Задать вопрос
Ответы пользователя по тегу PHP
  • Могу ли я прогнать через password_hash пароли в бд, которые md5, чтобы не сломалась авторизация?

    @alexalexes
    Смену способа хеширования пароля вы можете провернуть только при участии каждого пользователя, в два этапа.
    1 этап.
    Делаете патч в функцию авторизации.
    Когда пользователь авторизуется, проверяете, что заполнено поле по хешу новой функции.
    Если оно заполнено по новой функции, то все проверки верности пароля проводите с ней, поле старой функции игнорируете.

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

    2 этап
    Когда число поменянных хешей примерно будет равно числу активных пользователей за определенный период, то в патче запрещаете пользоваться старым хешем для проверки паролей, отправляете пользователя принудительно восстанавливать пароль по другим учетным данным, например, по эл. почте.
    При восстановлении доступа пароль хешировать новой функцией.
    Все, с этого момента можно избавиться от логики использования старого хеша.
    Ответ написан
    Комментировать
  • Как добавить данные в бд с помощью php sqlsrv?

    @alexalexes
    Чтобы скрипт перестал быть черным ящиком, полезно иногда пошарить в справке, где в очередном PDO интерфейсе пробивать ошибки операций работы с СУБД:
    // Выполняем запрос
        $stmt = sqlsrv_query($conn, $query, $params);
    // То, чего никогда в учебниках не напишут - на любой чих в сторону СУБД - чекать ошибки и выводить их куда-нибудь:
    if( $stmt === false ) {
        if( ($errors = sqlsrv_errors() ) != null) {
            foreach( $errors as $error ) {
                echo "SQLSTATE: ".$error[ 'SQLSTATE']."<br />";
                echo "code: ".$error[ 'code']."<br />";
                echo "message: ".$error[ 'message']."<br />";
            }
        }
    }
    
        // Освобождаем ресурсы
        sqlsrv_free_stmt($stmt);
    Ответ написан
  • Как найти опечатку в номере телефона?

    @alexalexes
    Сделать полноценную авторизацию и хранить номер в учетке.
    При заполнении формы автоматически подставлять его из учетной записи.
    Ответ написан
    Комментировать
  • Как разбить строку оператором explode?

    @alexalexes
    Я так понимаю, что вы в запросе слепили строку со ссылками через запятую в свойстве $row['links'], и тоже самое сделали с расширениями в свойстве $row['file_extension'].
    Чтобы собрать каждую ссылку со своим расширением файла нужно что-то такое сделать:
    $linksArray = explode(',', $row['links']);
    $extenArray = explode(',', $row['file_extension']);
    $link = [];
    foreach($linksArray as $index => $link_item)
    {
      $link[] = '<a href="'.$link_item.'">'.(isset($extenArray[$index]) && $extenArray[$index] !== '' ? $extenArray[$index] : '').'</a>';
    }
    var_dump($link);
    Ответ написан
  • Какой параметр php модуля отключает тему формы с сайта?

    @alexalexes
    В скриптах включаем рапортование ошибок всех типов и предупреждений.
    Меняем версию PHP на подходящую, и смотрим логи сервера, какие новые предупреждения стали прилетать, которых не было раньше.
    Вангую, что какая-нибудь isset проверка существования переменной/ключа массива не проставлена в определенном месте скрипта.
    Ответ написан
  • Нужно составить запрос если?

    @alexalexes
    if ($result->num_rows > 0 && $order['status_cart'] == 'Ожидает оплаты')
    {
      // do something
    }

    Вообще, замените ваш enum на атрибуте status_cart на числовой id статуса. Сделайте отдельную таблицу - "Статус оплаты" и пропишите там все значения, сошлитесь на эту таблицу внешним ключом.
    Если не хотите отказаться от enum, то используйте английские наименования, иначе вам придется гарантировать, что вы протащите кириллицу на все скрипты (чтобы везде был utf-8 в том числе при передачи данных в API).
    Ответ написан
    2 комментария
  • Устанавливать ли в php таймзону пользователя?

    @alexalexes
    Проблем с временными зонами вообще не будет, если их представление выдавить максимально ближе к модели представления данных на интерфейсе пользователя.
    Нужно конвертировать в строку только непосредственно перед отрисовкой дату и время из UTC, и обратно загонять время в UTC, если забираете пользовательский ввод.
    Весь бек должен работать в одной временной зоне, а от пользователя знать, что он в такой-то временной зоне, только в контексте сессионной переменной, если это необходимо.
    Ответ написан
    Комментировать
  • Как сжать в зип архив сайт?

    @alexalexes
    Потому, что у вас в коде происходит обход только по текущему уровню каталога $dir.
    Чтобы обход заныривал глубже, нужно создать рекурсивную функцию.
    Телом рекурсивной функции у вас будет:
    if ($dh = opendir($dir))
    {
    // код, который у вас в вопросе
    }

    А точка вызова для смены подкаталога:
    if (is_file($dir.$file)) {
    // код из вопроса
                }
    else if(is_dir($dir.$file))
    {
       $zip->addEmptyDir($dir.$file);
       // тут должен быть вызов рекурсивной функции, по которой вы передаете контекст $zip и $dir.$file (наверное, передача по ссылке)
    }

    В этом случае у вас будет рекурсивный обход каталогов в глубину.
    PS: Проконтролируйте дескриптор $zip на больших вложенностях и большим содержании файлов, нет ли переполнения выделенной оперативной памяти. Еще стек вызовов функций не бесконечный, тоже проконтролируйте глубину вызова.
    PPS: Бэкапить сайты в архив делается одной строчкой линуксовой командой, и засовывается в crontab. Будет работать надежнее. Эта не задачка для php-разработчика.
    То, что вы делаете - это просто тренировка на кошках, как работать с ZipArchive в PHP.
    Ответ написан
    4 комментария
  • Почему файл заполнен?

    @alexalexes
    Две гипотезы.
    1. Ваш код генерирует "нулевой" результат, поэтому записывается null значение.
    Попробуйте искусственно записать null значение в буфер, без реальных данных.
    2. Код генерирует слишком большой результат, не влезает в оперативную память выполнения скрипта (переполнение возникает именно на выполнении minify_html). Как ошибка записывается null значение.
    Попробуйте уменьшить значение выделенной оперативной памяти так, чтобы хватало для работы кода, но не хватало на выполнение minify_html, понаблюдайте через memory_get_usage, как на каждом этапе используется память.
    Ответ написан
  • Имеет ли смысл разбирать чужие сложные скрипты для самообучения?

    @alexalexes
    Обзорно и структурно нужно понимать, как выглядит компонент, который подключаешь.
    А вот когда вы нарветесь на баг, или захотите чуть-чуть изменить функционал, которого нет в документации к компоненту, то сами захотите докопаться до того метода в компоненте, который его реализует, или создадите аналогичные по структуре методы, чтобы не портить стиль реализации этого компонента.
    Ответ написан
    Комментировать
  • Вычисления datetime if()?

    @alexalexes
    Если нужно в php сравнивать даты, то из базы отдельным полем приводите любую дату в формат YmdHis и можете сравнивать значения как строки:
    if($date < date('YmdHis'))
    {
    }

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

    @alexalexes
    Поставьте проверку реферера на той странице, где хотите закрыть.
    Ответ написан
    Комментировать
  • Как сделать правильно группировку под группами из базы?

    @alexalexes
    То, что вы хотите получить можно сделать таким запросом:
    select S.*,
         (select S1.location from services S1 where S1.main = S.main and (S1.list is null or S1.list = '')) head_index
    from services S
    order by head_index, S.list is null or S.list = '' desc, S.location is null or S.location = '' desc, S.location

    А потом вывести таким скриптом:
    $sql = "select S.*,
         (select S1.location from services S1 where S1.main = S.main and (S1.list is null or S1.list = '')) head_index
    from services S
    order by head_index, S.list is null or S.list = '' desc, S.location is null or S.location = '' desc, S.location";
    $res = mysqli_query($conn, $sql);
    $cat_index = 0;
    while($row = msqli_fetch_assoc($res))
    {
      if(is_null($row['list']))
      {
        if($cat_index > 0)
          echo '</ul>';  // закрытие списка
        echo '<p>'.$row['main'].'</p><ul>'; // название категории, начало списка
        $cat_index++; // считаем категорию, чтобы правильно закрывать списковые теги
      }
      else
      {
        echo '<li>'.$row['list'].'</li>';
      }
    }
    if($cat_index > 0)
      echo '</ul>'; // закрытие списка

    А вообще, многоуровневые списки делаются по-другому.
    Ответ написан
  • При отправке данных из js через fetch, php код не исполняется, в чем причина?

    @alexalexes
    В message.php:
    var_dump(date('d.m.Y H:i:s'));
    var_dump($_POST);
    exit();

    Посмотрите, меняется ли время и содержание поста. Если один раз, а потом не меняется, то копайте заголовки кеша для браузера.
    Ответ написан
    Комментировать
  • Как правильно работать с большим массивом: создавать новый или перезаписывать элементы старого?

    @alexalexes
    Выгоднее всего положить в базу данных, которая специализируется на ключ-значении данных, типа redis или memcached и там делать манипуляции - они на этом специализируются.
    Если с массивом работать напрямую, то выгоднее изменять существующий массив, в изменяющие функции передавать массив по ссылке, следить, чтобы методы при изменении массива не создавали новый массив, а работали с существующим.
    Будут провалы производительности у границ количества элементов кратные степени двойки (ссылка). Это плата за высокоуровневые фишки в виде ресайза массива, чего нет на низком уровне реализации интерпретатора PHP.
    Ответ написан
    5 комментариев
  • Какую кодировку выбрать для бд чтобы хранить фото?

    @alexalexes
    В базе данных, обычно, не хранят бинарные данные файлов.
    Кладете на файловый сервер файл, берете путь к этому файлу и записываете в поле таблицы.
    Если очень приспичило какой-то бинарник положить в поле таблицы, то для этого есть binary/varbinary type.
    Но злоупотреблять возможностью записывать безразмерные данные в одно поле не стоит - намучаетесь с бекапами.
    Ответ написан
    Комментировать
  • Как настроить кнопку удаления из бд?

    @alexalexes
    при желании ее удалять

    Скорее очищать данные работы программы. Вряд ли вы держите исходный код программы в таблицах БД, чтобы потом ее удалять.
    Не вполне понятно, как называются таблицы, которые вы хотите очищать (сами таблицы как объекты БД останутся, удалится только их содержимое). Но по вашему фрагменту можно что-то работающее при посте action=delete написать так:
    if(isset($_POST['action']) && $_POST['action'] == 'delete') // есть action и он равен delete
    {
        $link = mysqli_connect($host, $user, $password, $database);
        $sql = "DELETE FROM `program_day_1`"; // по одной инструкции удаления на каждую таблицу
        $res = mysqli_query($link, $sql);
        $sql = "DELETE FROM `program_day_2`";
        $res = mysqli_query($link, $sql);
        mysqli_close($link);
        header('location: program-admin.php');
    }
    Ответ написан
  • Как в текст из базы данных вставить шаблон?

    @alexalexes
    Если слайдер находится всегда в определенном месте статьи или есть фиксированные варианты расположения,
    то нужно доработать редактор статей, чтобы к статье можно было прикрепить список изображений (у одного элемента изображения должен быть путь к файлу, поле описания, порядковый номер в слайдере) как связанный ресурс статьи и генерировать слайдер автоматически по наличию этого ресурса (у самого ресурса слайдера должно быть свойство расположения слайдера - если есть варианты).
    Ответ написан
    1 комментарий
  • PHP: Почему 'mb_convert_encoding' не конвертирует простую строку?

    @alexalexes
    $str = 'Привет 2019 Мир!'; // написано в той кодировке, в которой сохранен файл (хрустальный шар говорит, что utf-8)
    $str = mb_convert_encoding( $str, 'windows-1251', mb_detect_encoding( $str ) ); // конвертируем в cp1251
    header('Content-Type: text/html; charset=windows-1251'); // Откуда трабла с кодировкой? - не соответствие сообщаемой кодировки в http-заголовке от сервера, с выводимым контентом от сервера. Исправляется явным указанием заголовка
    var_dump( $str ); // выводим в той кодировке, что выводит заголовок charset сервера в браузер (хрустальный шар говорит, что до указания header() было charset=utf-8)
    Ответ написан
    2 комментария