Задать вопрос
  • Удалять из бд лайки или ставить isActive = 0?

    ipatiev
    @ipatiev
    Потомок старинного рода Ипатьевых-Колотитьевых
    Это пустые страхи.
    Никакой "фрагментации" "диска"в таблице из двух числовых полей (то есть с фиксированным размером записи) не будет. БД прекрасно сама повторно использует ячейки удалённых записей.
    Поэтому, как правильно сказал Akina, мягкое удаление для лайков делать бессмысленно
    Ответ написан
    Комментировать
  • Как протестировать производительность функций начинающему php-разработчику?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Никак.
    Никакой разницы в использовании системных ресурсов для разных способов вызова функций нет.

    Оценивать тот или иной подход следует с точки зрения архитектуры, а не воображаемой разницы в использовании системных ресурсов.
    Но для этого надо задать другой вопрос, или по крайней мере отредактировать этот, убрав из него все фантазии про системные ресурсы.
    Ответ написан
    7 комментариев
  • Как обрезать текст до определённого слова и после?

    ipatiev
    @ipatiev
    Потомок старинного рода Ипатьевых-Колотитьевых
    string phrase = @"Class: Warrior
    Weapon: Axe
    Strength: 55";
    string[] words = phrase.Split(Environment.NewLine.ToCharArray());
    Console.WriteLine(words[1]);


    Удивительно, что единственный ответ был написан в комментариях к вопросу, а целых три ответа написаны какими-то фриками, которые либо не поняли вопроса, либо не понимают того, что сами же написали, or both.

    При том что не зная ни слова на сишарп, я тупо с помощью гугля за 3 минуты получил требуемый код.
    Отсюда вопрос: у вас тут все такие? "Специалисты по крупному ПО", которые не то что простой код на три строчки написать не могут, на даже ответ на вопрос от комментария отличить не в состоянии?
    Ответ написан
    Комментировать
  • Возможно ли сделать конкатенацию к подготовленому sql запросу?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Возможно, но как правильно написал galaxy, prepare() нужно делать после формирования строки $sql, а не до.
    В общем случае это делается так:
    $sql = 'UPDATE product SET quantity = ?';
    $parameters[] = $quantity;
    if (....) {
        $sql .= 'AND name = ?';
        $parameters[] = $name;
    }
    $stmt = $db->prepare($sql);
    $stmt->bind_param(str_repeat("s", count($prameters)), ...$parameters);


    Но в вашем случае вы делаете что-то странное, там явно нужен скорее оператор IN. Но по этому коду очень сложно понять, что на самом деле нужно
    Ответ написан
  • В чём смысл передавать array_reverse в foreach без явной необходимости обратного порядка элементов?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Для ответов на подобные вопросы всегда полезно использовать логику.
    Например:
    Если необходимости в обратном порядке элементов нет, то array_reverse не нужна.
    Если array_reverse используется - значит, скорее всего, необходимость есть, но вы её просто не видите.

    Это универсальный способ, который позволяет ответить на можество подобных вопросов.

    "оставить исходный массив нетронутым" причиной не является.
    Ответ написан
  • Как обработать возникшую ошибку в PHP скрипте загрузки страницы?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Это очень хороший вопрос, по многим причинам.

    Во-первых, очень хорошо что он сам по себе поставлен. Обычно пользователи РНР не задумываются о таких "мелочах". Но на самом деле об этом должен думать каждый программист, делающий сайты
    Во-вторых, здесь мы можем видеть довольно характерный баг Апача, который действительно, почему-то не выполняет директиву ErrorDocument для 500 ошибок, полученных от РНР. Ну и вообще, завязываться на Апач во времена доминирования Нжинкса как-то не очень дальновидно.
    В-третьих, как правильно заметил Stalker_RED, сделать редирект при 500 статусе (или 500 статус при редиректе) невозможно - статус может быть только один. Да это и нет смысла делать - проще сразу на месте нужную страницу и прочитать.
    В-четвертых, текущий подход, прямо скажем, не очень оптимальный:
    - о роботах мы позаботились, о пользователе позаботились, но надо ещё не забыть и программиста. Которому как раз сообщение об ошибке-то нужно видеть во всех подробностях!
    - просто отдать нужный НТТР код недостаточно - надо бы ещё и завершить работу скрипта.
    - ловить все ошибки вручную через try-catch так себе удовольствие. И код раздувает,и поведение потом быстро не поменяешь. А если в какой-то момент захочется для отладки прикрутить whoops - это придётся по всем блокам бегать?

    Чтобы решить все эти проблемы разом, надо сделать единый обработчик ошибок. Который и подробности для программиста залогирует, и нужный заголовок отправит, и красивый хтмл юзеру покажет.

    В самом простом варианте это будет что-то вроде такого:

    set_exception_handler(function ($e)
    {
        error_log($e);
        http_response_code(500);
        if (ini_get('display_errors')) {
            echo $e;
        } else {
            include 'pages/error_500.php';
        }
    });

    В теории, конечно, можно заменить error handler на глобальный try-catch который оборачивает точку входа, но это менее удобно. Тем более, что для обработки фатальных ошибок нужен свой отдельный обработчик, и в итоге код обработки ошибок начинает занимать довольно значительный объем и лучше конечно его инициализацию вынести отдельно.
    Ответ написан
    Комментировать
  • Как удалить тег и содержимое с помощью preg_replace?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Лучшие собаководы настоятельно не рекомендуют удалять теги с помощью preg_replace.

    Строить dom дерево и обрезать ветки.
    Ответ написан
    1 комментарий
  • Для получения визы должно быть профильное образование?

    ipatiev
    @ipatiev
    Потомок старинного рода Ипатьевых-Колотитьевых
    По опыту, этот вопрос задают те, у кого нет ни профильного образования, ни профессионального опыта, ни оффера.
    Ничего личного, просто наблюдение.
    Ответ написан
    Комментировать
  • Как перейти с mysql на elasticsearch?

    ipatiev
    @ipatiev
    Потомок старинного рода Ипатьевых-Колотитьевых
    Никак. "перейти" с базы данных на поисковый движок нельзя.
    Можно сделать поисковый сервис, который будет индексировать информацию, взятую из бд

    На основе этого сервиса сделать полнотекстовый и фасетный поиск.
    А текущую базу данных оставить как есть. Только запросы оптимизировать, чтобы "скорость работы не понижалась"
    Ответ написан
    3 комментария
  • Безопасность кода php -> mysql?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Вопрос хороший, характерностью имеющихся в коде ошибок.

    На первом месте тут конечно , конечно, незабвенный Бобби Тейблс и его прошаренная мамаша.
    Таблицу здесь удалить не получится, но вот скачать всю базу - запросто.

    Плюс мамаша конечно тупит. Данные надо не "экранировать", поскольку почти никто не понимает, что это значит, а отправлять в БД отдельно от запроса.

    Но меня здесь больше интресует не безопасность, а осмысленность данного кода.
    Если элемент "login" попадает в сессию в результате авторизации, то зачем снова делать все эти 100500 запросов в БД?
    Я бы этот код сократил до
    <?php
    require_once $_SERVER["DOCUMENT_ROOT"] . "/engine/core/session.php";
    if (empty($_SESSION["user_id"])) {
        include "login.php";
        die;
    }

    и поместил в profile.php

    При этом убедившись, что код собственно авторизации выглядит как-то так

    $stmt = $conn->prepare("SELECT * FROM users_all WHERE name=?");
    $stmt->bind_param("s", $_POST['name']);
    $stmt->execute();
    $user = $stmt->get_result()->fetch_assoc();
    
    if ($user && password_verify($_POST['password'], $user['password']))
    {
        $_SESSION['user_id'] = $user['id'];
        header("Location: /profile.php");
        die;
    }
    Ответ написан
    Комментировать
  • Безопасно ли хранить .htaccess в корне сайта?

    ipatiev
    @ipatiev
    Потомок старинного рода Ипатьевых-Колотитьевых
    Это очень смешной вопрос.

    Если читать только заголовок, то вопрос звучит очень смешно. Типа "опасно ли дышать?". файлик .htaccess как раз и предназначен для размещения в папках сайта, корневой или не корневой - без разницы.

    Но если прочитать вопрос целиком, вместе с очень забавным текстом на картинке, то станет понятнее, что имеется в виду.
    Нет, дырой в безопасности является вряд ли.
    Тут, скорее, дыра в голове AKA непонимание смысла своих действий.

    Во-первых, формулировка. Если вспомнить, что корнем сайта как раз и является публичная директория, то вопрос получится изначально бессмысленный, "почему файл лежит в публичной директории, а не в публичной директории?"
    То есть надо сначала понять, что речь в замечании на картинке идет про корень приложения, а не сайта. В котором корень сайта - это всего лишь одна из папок. Та самая, "публичная".

    И только после этого можно приступать к ответу на вопрос:
    В корне приложения - то есть папке, которая, по идее, вообще никакого отношения к веб-серверу не имеет, класть htaccess скорее бессмысленно. И в теории может так оказаться, что веб-сервер-апач его вообще не прочтёт. И, как следствие - некие секретные настройки могут не примениться.

    Но тут надо вспомнить, что завязывать какую бы то ни было безопасность на файлик .htaccess - это уже так себе идея. Поскольку доля веб-сервера-апач неуклонно снижается, и весьма велика вероятность того, что на реальном сервере файлик .htaccess будет просто болтаться мертвым грузом, и никто не обратит на него ни малейшего внимания.
    Ответ написан
    3 комментария
  • Как сделать кэширование запросов в Mysql 8?

    ipatiev
    @ipatiev
    Потомок старинного рода Ипатьевых-Колотитьевых
    Альтернатива только в использовании MariaDB.
    Ответ написан
    2 комментария
  • Какая функция вызвала эту функцию в PHP?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    $executer = debug_backtrace()[1]['function']  ?? 'direct call';


    или чуть более расширенный вариант

    $class = debug_backtrace()[1]['class'] ?? '';
    $executer = ($class ? "$class::" : "") . (debug_backtrace()[1]['function']  ?? 'direct call');
    Ответ написан
    Комментировать
  • Как удалить параметры при редиректе?

    ipatiev
    @ipatiev
    Потомок старинного рода Ипатьевых-Колотитьевых
    Ответ написан
    Комментировать
  • Как очищать текст в php?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Никак не очищать.

    На самом деле этот вопрос встречается довольно часто. Вот например популярный ответ на Stack Overflow, который подробно разбирает этот распространённое заблуждение: https://stackoverflow.com/a/3126175. И основная мысль там:

    Понятие такой генерализованной "очистки данных" изначально бессмысленное и вредное.

    Особенно такой вот индусской функцией, которая сама по себе - пример редкого идиотизма: сначала заменяем символы < и > на HTML сущности... а потом бодро пытаемся вырезать HTML теги. Которых к этому моменту в тексте не останется ни одного!
    Или функция stripcslashes, которая здесь вообще ни к селу, ни к городу. Если я хочу написать сочетание \n, то с какой стати эта функция будет заменять его на перевод строки?
    Всё что можно оставить из этого безумного набора - это trim(). Да и то не всегда. Как правильно заметил Rsa97, могут быть случаи, когда лидирующие пробелы имеют значение, например, при выводе форматированного кода. Кстати, этим как раз грешит Хабр. Если запостить код с отступами, то первый будет "съеден"!


    Очистка

    Любая "очистка" (хотя правильнее говорить про форматирование), имеет смысл только в определённом контексте.
    И поэтому "очищать" надо только адресно, строго перед использованием в том или ином конкретном случае.

    Например, базе данных ни жарко, ни холодно от наличия HTML тегов.
    А проблемы могут начаться только при выводе данных в HTML. Но если мы будем предотвращать эти проблемы заранее, то просто попортим кучу данных. Поэтому форматировать данные для использования в контексте отрисовки HTML следет строго перед этой отрисовкой. То есть при выводе.
    Что и делают все популярные РНР шаблонизаторы автоматически.
    То есть вручную колупаться с "очисткой" вообще не нужно.

    Больше того, "очистка" HTML поможет данным, выводимым в яваскрипт, как мёртвому припарки. То есть опять же - всегда надо понимать, в какой именно контекст мы выводим данные, и форматировать соответствующим образом. В частности любые данные передавать в яваскрипт только через json_encode()

    И таких контекстов неисчислимое множество. Например, если мы используем переменную для передачи параметров в консольный скрипт, то надо обязательно обрабатывать её через escapeshellarg(). Если в регулярку - то preg_quote(). Имя файла для инклюда из переменной (хотя так делать вообще не стоит) надо хотя бы обрабатывать через basename(). И так далее.

    Валидация

    Если же наличие HTML тегов в поступающих данных противоречит техническому заданию, то надо заниматься не "очисткой", а валидацией: проверить регулярным выражением, есть ли в строке HTML теги. И если есть, то вернуть пользователю с сообщением об ошибке.

    Защита БД

    И кстати, по поводу "использую pdo".
    На всякий случай уточню, что само по себе использование PDO не защищает ни от каких проблем
    Важно помнить, что защита - это когда в базу данных отправляется строго константная строка запроса, полностью на 100% составленная из значений, прописанных в коде РНР, и в ней не используется ни одно значение, пришедшее в код извне. Причем PDO помогает здесь только наполовину, позволяя использовать в запросе подстановки вместо самих данных.
    Но при этом для всех остальных частей запроса - например имен полей - у ПДО нет никакой защиты и её надо организовывать самостоятельно. Либо проверяя по белому списку, лабо, по крайней мере, прогоняя через регулярку.
    Ответ написан
    13 комментариев
  • Где в Laravel лучше делать валидацию входящих данных - в контроллере или сделать кастомный Request для контроллера, или Middleware?

    ipatiev
    @ipatiev
    Потомок старинного рода Ипатьевых-Колотитьевых
    Вообще-то в Ларе УЖЕ есть этот самый отдельный сервис - Illuminate\Http\Request, который и предназначен для валидации входящих данных.
    Ответ написан
    2 комментария
  • Как выполнить sql скрипт, который хранится в файле.sql, в файле питона используя библиотеку pymysql.connect?

    ipatiev
    @ipatiev
    Потомок старинного рода Ипатьевых-Колотитьевых
    4. После размещения вопроса пользователю запрещается осуществлять:
    4.1. Дублирование вопроса, который уже размещался на страницах Сервиса. В том числе и в случае, если вопрос был удалён модератором, или на вопрос не был дан ответ (т.е. категорически запрещается дублирование вопроса с целью повторного привлечения к нему внимания).
    Ответ написан
    Комментировать
  • Почему mysqli_query всегда возвращает false?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Я уже отвечал на этот вопрос

    Но самое конечно ужасное - это что этим людям доверяют работу с картами.
    При том что все данные карт утекут в тот же момент когда этот "сервис" выйдет в онлайн
    Ответ написан
  • Как автоматизировать запуск sql скриптов?

    ipatiev
    @ipatiev
    Потомок старинного рода Ипатьевых-Колотитьевых
    Проще всего будет действительно через шелл скрипт ("файл с расширением sh"), причем даже записывать эту команду в файл не обязательно, а можно просто выполнить в консоли:
    for file in `ls /path/to/files/*.sql`; do mysql -uUSER -pPASSWORD DATABASE < $file ; done

    здесь mysql - это консольный клиент mysql
    Ответ написан
  • Вывожу картинки через php функцию, как вывести 2 фотки сразу?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Надо добавить метод getImages($num=2) чтобы она принимала аргументом количество картинок и возвращала массив.
    И в шаблоне можно будет сделать foreach(). Только дергать базу два раза некрасиво, лучше сначала получить в переменную, а потом ее использовать

    <?php if ($images = $product_1->getImages()) : ?>
    <?php foreach ($images as $img): ?>
        <img src="/media/uploads/small/small-<?= $img ?>" alt="<?= $product_1->prname ?>" title="Перейти в товар - <?= $product_1->prname ?>" />
    <?php endforeach ?>
    <?php else : ?>
      <img src="/media/uploads/nofoto.jpg" alt="Нет фото на товаре" title="Нет фото" />
    <?php endif; ?>
    Ответ написан