• Как обработать запрос не получая ошибку по таймауту?

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

    Ошибка здесь
    Количество необходимых элементов для отображения на странице не может быть таким, что при их получении случится таймаут. Человек в состоянии воспринять ну максимум тыщу строк. А лучше - 50.
    Поэтому необходимыми являются 50 строк, а не "все".

    Если же данные извлекаются для последующей обработки, то надо учитьSQL и обрабатывать данные на стороне БД, получая уже готовый результат

    Если уж совсем не получается средствами БД, то тогда это надо делать в консольном скрипте, и не париться по поводу таймаутов.
    Ответ написан
    5 комментариев
  • Нужно ли два раза прописывать session_start()?

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

    Ошибка headers already sent к количеству вызовов отношения не имеет, это стандартная ошибка при кривой структуре кода и лечится элементарно. В интернете примерно миллион рекомендаций по её решению.
    Ответ написан
  • Как правильно получить массивы из формы в POST и отправить?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    foreach ($_POST as $key => $value) {
        echo "$key=". (is_array($value) ? implode(",", $value) :  $value)."<br />\n";
      }
    Ответ написан
    2 комментария
  • Apache не открывает страницы .php а отображает их списком файлов, как исправить?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
  • Стоит ли проверять имя и пароль пользователей при каждом запросе к api(guzzle)?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Стоит ли проверять имя и пароль пользователей при каждом запросе к api(guzzle)?

    Вот как всегда, в заголовке вопроса одно, а в тексте - ну совсем же другое.

    В моем случае выдавать токен вообще бессмысленно,верно?

    Верно

    Но в общем случае, на который претендует вопрос судя по заголовку, проверять каждый раз не стоит, а стоит выдавать по логину и паролю ограниченный по времени токен при запросе на отдельную точку входа.
    Ответ написан
  • Как JavaScript получит доступ к файлам вне папки `public`?

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

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

    Рекомендую найти видео "Как писать код, который понравится вашим тестам" с первой PHPRussia. Там очень доходчиво рассказывается про то, почему надо делать простые методы. Не только для тестов. А ещё и для повторного использования и для упрощения поддержки кода. Когда надо прочитать основную логику модуля, то даже сокращение в два раза (по одному методу вместо двух строк кода) уже сильно облегчает задачу.
    А если уж даже тест понял, что делает ваш код, то человек поймёт и подавно :)

    Как вам написали выше - все дело в именах методов. Если они информативные, то есть если конструкция
    if ($this->function_7($a) && $this->function_8($b))
    читается как связный английскй текст, то mission accomplished! Функции выполняют свою роль: легче всего читать код, которого нет. Вместо того, чтобы разбирать, что делает тот или иной код, можно просто прочитать небольшой текст на английском.
    Ответ написан
    4 комментария
  • Как перехватить любое исключение в php?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    В старых версиях PHP деление на ноль никакое не исключение, а обычная ошибка.
    О чем ясно написано в выводимом сообщении: Warning: Division by zero in ...

    Чтобы перехватывать ошибки, их надо конвертировать в исключения. В простейшем варианте
    set_error_handler(function ($level, $message, $file = '', $line = 0)
    {
        throw new ErrorException($message, 0, $level, $file, $line);
    });

    После установки такого обработчика все ошибки будут автоматически конвертироваться в исключения, и соответственно могут быть пойманы через try..catch:

    Fatal error: Uncaught ErrorException: Division by zero
    Ответ написан
    1 комментарий
  • Зачем использовать filter_input если можно тот же результат получить меньшим кодом?

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

    Сами по себе функции фильтрации - довольно странная часть языка. И нынешний отказ от FILTER_SANITIZE_STRING как раз подтверждает этот тезис. Задумка была в теории неплохая, но реализация получилась так себе. А, главное - все эти функции только насильно меняют значение переменной. Молча.
    А в нормальном современном приложении принято проверять переменную на соответствие правилам и выдавать ошибку

    В случае, если вместо числового id нам приходит вдруг массив, надо не молча его глотать и химичить с превращением в число, а сразу отвечать в репу 400-й ошибкой, не разводя сантименты.

    Поэтому я бы взял какую-нибудь либу для валидации, вот первая же из гугля, https://github.com/rakit/validation
    И нормально проверял входящие параметры.
    В случае, если это пользовательский ввод, типа логина и пароля, то отдавать культурные ошибки
    Если же это чисто внутренняя инфраструктура приложения, типа id из нашей же ссылки, то при наличии ошибок молча отдавал 400.
    Ответ написан
  • Как сделать прогресс бар с отрезками?

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

    Шкала у нас нелинейная, первый шаг 100 единиц, последний - 2000.
    Но при этом для вычислений мы берём не позицию шага, а его значение.
    Ну и разумеется получаем то, что получаем.
    250 от 3000 - это никакие не "примерно 50 единиц", а примерно 8 процентов. Вот эти 8 процентов вам и показывает.

    Длина отрезка при разбивке на 5 частей будет 20%
    И вот 8 от 20 как раз и составляет те самые "примерно 50" процентов длины первого отрезка :)

    Выше товарищ правильно пишет про отладку.
    Но отладка в обязательном порядке состоит из двух вещей:
    1. Надо понимать, что делает твой код. В частности, иметь представление, какое значение каждая переменная должна иметь на каждом этапе.
    2. Запускать код, выводя промежуточные результаты, и сравнивая их с ожидаемыми.

    Без п.1 заниматься отладкой бессмысленно.
    Именно поэтому для программиста очень важно понимать, как работает его код. Иначе он просто не сможет его отладить.
    Ответ написан
  • Удалять из бд лайки или ставить 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;
    }
    Ответ написан
    Комментировать