Ответы пользователя по тегу PHP
  • Почему в PHP zlib не работает во врапперах?

    @alexalexes
    Попробуйте одинарные кавычки вместо двойных.
    'php://filter/read=convert.base64-decode|zlib.inflate/resource='.$sourceFile

    PS:
    Нашел вот такой комментарий на Хакере.
    https://xakep.ru/2012/11/22/php-filter-wrapper-attacks/
    При всех выгодах данный метод уничтожения стопперов не может быть универсальным. В 2009 году было замечено, что функция base64_decode некорректно обрабатывает строки, содержащие в середине знаки равенства [#47174]. Этот баг был довольно оперативно исправлен для функции base64_decode, но для фильтра convert.base64-decode никаких исправлений сделано не было. Поэтому, если при «выдавливании» на каком-то шаге получаются данные, содержащие знак равенства, дальнейшее применение фильтра convert.base64-decode уничтожит преобразуемую строку.

    $s = 'php://filter/read=convert.base64-decode/resource=data:,dGVzdA==CRAP'; 
    var_dump(file_get_contents($s)); // print: string(0) ""

    Ответ написан
  • Переход сайта с http на https. Почему не работает getimagesize() по пути //site.ru?

    @alexalexes
    На стороне сервера нужно выявить места, где идет обращение к файлам сервера, где пути к файлам это не url в представлении клиента (браузера), а путь внутри файловой системы сервера, и переписать соответствие url и filepath.
    В вашем случае путь в файловой системе может выглядеть так:
    htdocs/TmpGif/tr_87754306592959_133380.gif
    Ответ написан
  • Как вывести данные в loadTpl?

    @alexalexes
    Скорее всего вызов шаблона при переборе строк будет такой:
    while ($news = $NewsQuery->fetch())
    {
       $lastNewsList .= loadTpl("/last_news/news.html", 
    [
      "created_at" => $news['created_at'],
      "title" => $news['title'],
      "content" => $news['content']
    ]);
    }

    ... или даже еще проще:
    while ($news = $NewsQuery->fetch())
    {
       $lastNewsList .= loadTpl("/last_news/news.html",  $news);
    }

    Как поведет себя шаблон в этой строчке -
    $pageData['lastNews'] = loadTpl("/last_news/parent.html", $data);

    Без кода parent.html - не ясно.
    Как обрабатывается $pageData при наличии ключа 'lastNews', тоже нужно поинтересоваться, а надо ли намерено где-то еще указывать 'lastNews', чтобы отрисовать этот контент.
    Ответ написан
  • Как разделить число на 100 и прибавить получившейся результат к сумме которую делим?

    @alexalexes
    Если округлять центы в пользу пользователя, то:
    UPDATE dle_users
    SET user_balance = user_balance + round(user_balance / 100.0, 2)

    Если округлять центы в пользу системы, то:
    UPDATE dle_users
    SET user_balance = user_balance + ceil(user_balance / 100.0 * 100) / 100.0
                                                                    ^       ^
                                              корректировка ceil по 2 знакам после запятой
    Ответ написан
    1 комментарий
  • Как реализовать создание файла xls на сайте из php sql запроса?

    @alexalexes
    Это называется кэширование файлов.
    Вы привели только заголовок, какой тип контента отдает скрипт.
    Типичный не оптимизированный скрипт (его поведение) под отдачу файла.
    // Запрос к БД, получающий ресурсы для формирования файла
    // Заголовком сообщаем имя файла клиенту
    // Формируем / получаем тело файла
    echo /*отдаем переменную с телом файла*/;

    Оптимизированное под кэширование поведение скрипта:
    // Запрос к БД на время обновления ресурсов из чего собирать файл
    // Получаем время изменения файла в каталоге files
    // Если файл не старее чем сведения в БД то формируем тело из него.
    // Если файл старее чем сведения в БД на установленную константу времени жизни кэша, то получаем новое тело файла и обновляем файл кэша.
    // Заголовком сообщаем имя файла клиенту
    echo /*отдаем переменную с телом файла*/;
    Ответ написан
    Комментировать
  • OpenWRT+PHP7 "Ошибка Call to undefined function mysqli_connect()" не понимаю что делать?

    @alexalexes
    Поиск по OpenWRT ресурсам говорит, что, возможно, проблема в конкретной сборке OpenWRT.
    Попробуйте воспользоваться советом:
    Try this. Check /etc/php7/

    Rename 20_mysqli.ini to 30_mysqli.ini, or delete 20_mysqli.ini if both exist. If you also have 20_openssl.ini there, rename that to 10_openssl.ini.
    Above change is needed to load the modules in the correct order.
    This should now be fixed in the latest builds, but you could be running older code, or suffering from the bug that was there earlier.
    Ответ написан
    1 комментарий
  • Зачем присваивать переменной результат readdir()?

    @alexalexes
    Функция readdir(), как правило, используется вместе с while.
    За один цикл нужно только один раз вызвать readdir, чтобы можно было поработать с дескриптором элемента каталога, не перейдя на другой элемент, поэтому появится такая неуклюжесть :
    while(true)
    {
      $f = readdir($d);
      if($f === fasle)
      {  break; }
      // Сделать что-то с $f в противном случае.
    }

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

    @alexalexes
    Можно. Самое главное, мы не подключаем php-скрипт, а отправляем данные этих форм на обработку этим php-скриптом. Так проще прийти к пониманию, как оно работает.
    Чтобы php-скрипт мог воспринимать данные первой формы, он должен уметь пренебрегать наличием параметра user_car.
    А делается это таким образом:
    строчка:
    $car = $_POST['user_car'];
    исправляется на:
    $car = array_key_exists('user_car', $_POST) ? $_POST['user_car'] : null;

    и другая строчка:
    $mail->Body    = '' .$name . ' хочет перегнать машину ' .$car. '  из ' .$from. ' в ' .$to. '. <br> Вот его номер телефона ' .$phone;

    исправляется на:
    $mail->Body    = $name . ' хочет перегнать '.(is_null($car) ? 'неуточненную машину' : 'машину ' .$car). '  из ' .$from. ' в ' .$to. '. <br> Вот его номер телефона ' .$phone;

    PS:
    Чтобы вам не прислали js-инъекцию на почту, все принимаемые параметры, из которых формируется текст письма, следует экранировать.
    $name = htmlspecialchars($_POST['user_name']);
    $phone = htmlspecialchars($_POST['user_phone']);
    $car = array_key_exists('user_car', $_POST) ?  htmlspecialchars($_POST['user_car']) : null;
    $from = htmlspecialchars($_POST['from']);
    $to = htmlspecialchars($_POST['to']);
    Ответ написан
    Комментировать
  • Несколько массивов вместо одного?

    @alexalexes
    $description1[] = array([..................])
    Обратите внимание сколько раз тут объявлен массив в массиве.
    array([]) - это аналогично [[]] или array(array())
    PS: Для того, чтобы не путаться впредь, перестаньте использовать один из способов.
    Либо array() если у вас php 5.6-
    либо [] если php 5.6+ (это предпочтительней - стильно, модно молодежно, похож на JS)
    Ответ написан
  • Как определить переменную в зависимости от размера картинки?

    @alexalexes
    Определяете с помощью метрики - пропорции:
    $p = $imgwidth * 1.0 / $imgheight; // пропорция; умножение на 1.0 чтобы перевести число в float;
    $delta_q = 0.1; // Дельта ощущения "квадратности" изображения
    switch(true)
    {
      case $p > (1.0 +  $delta_q): echo 'альбомный формат изображения'; break;
      case $p < (1.0 - $delta_q): echo 'книжный формат изображения'; break;
      default: echo 'изображение, вероятно, квадратное'; 
    }

    Когда у вас пропорция $p == 1.0 , то изображение строго квадратное.
    Чтобы избавиться от строгости, вводится дельта $delta_q, дабы считать квадратными изображения, в пропорции "слегка" меньше единицы и "слегка" больше единицы.
    Ответ написан
    Комментировать
  • Учить PHP 5 или 7?

    @alexalexes
    Пока не появится реальная задача - вообще бесполезное метание.
    Читать про то и про другое, потом что-то пытаться накодить.
    Однако, по-настоящему вы освоите ту или иную версию, когда будете работать над реальным серверным приложением/сайтом.
    Ответ написан
    Комментировать
  • Почему не работают функции mb_convert_encoding() и iconv()?

    @alexalexes
    Страница-источник на самом деле в кодировке utf8 отдается, а не в windows-1251, как это указано в html.
    Конвертировать не нужно, если вам нужен utf8 на выходе:
    header('Content-type: text/html; charset=utf8');
      echo file_get_contents('http://antiko22.info/vse_novosti/dolg-pered-mfo-ne-mozhet-prevyshat-telo-zajma-bolee-chem-v-3-raza/');
    Ответ написан
  • Как правильно вывести записи из бд(MySql,PHP)?

    @alexalexes
    Накопите промежуточные строки в $out_arr, соедините элементы массива через разделитель join-ом и подайте на вывод.
    $out_arr = array(); 
    while($hero2 = mysqli_fetch_assoc($hero1))
        {
         
    $time_now = strtotime($hero2['cron1']);
    $time_need = strtotime($hero2['cron2']);
    if($time_need>=$time_now ){
    $t_s= date("H:i ",75600-($time_need-$time_now));
    }
    else
    $t_s= date("H:i ",75600-($time_now-$time_need));
           $out_arr[] = str_replace(":",".",$t_s);
     }
    echo "[".join(' ,',  $out_arr).']';
    Ответ написан
    Комментировать
  • Как заменить специальные символы & quot;?

    @alexalexes
    Если не хотите заморачиваться с регулярными выражениями, то достаточно функции замены строк.
    $result = str_replace(array('amp;', '&', 'quot;'), '',  'Ремень HENDERSON &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;quot; "2 в 1&am');

    PS: Только определитесь в том, что у вас могут быть сущности в строковом представлении или в кодах символах, от этого зависит нужно ли конвертировать коды символов в html-сущности и обратно в первом аргументе функции.
    Ответ написан
    Комментировать
  • Как сделать корректный вывод json?

    @alexalexes
    Вы вот это:
    array(
                        'id' => $banner->id,
                        'url' => $banner->url,
                        'name' => $banner->name,
                        'image' => $banner->image
                    );

    Вкладываете в $this->data по ключу $key, отсюда следует, что $this->data - это массив, поэтому он декодится в скобочках [].
    Ответ написан
    Комментировать
  • Как правильно сгруппировать массив php?

    @alexalexes
    Если строки в массиве строго форматированы, и путь всегда начинается с "/home/каталог", то, чтобы получить ключ для вновь сформировываемого массива, достаточно функции explode(), если вам нужно более гибко искать название каталога, то придется вычленять его регулярным выражением.
    <?
      $input_arr = [
      "/home/fol1/test.txt",
      "/home/fol1/Browsers/test2.txt",
      "/home/fol2/Browsers/test3.txt",
      "/home/fol2/Browsers/ttre/test2.txt"
      ];
      $out_arr = [];
      foreach($input_arr as $item)
      {
        $folders = explode('/', $item);
        $key = $folders[2];
        if(!isset($out_arr[$key]) || !array_key_exists($item, $out_arr[$key])) // если еще не был такой путь
          $out_arr[$key][] = $item;
      }
      print_r($out_arr);
    ?>
    Ответ написан
    Комментировать
  • Как лучше сделать парсер данных с разных источников?

    @alexalexes
    В вашей схеме еще не хватает подсистемы scheduler - планировщик заданий.
    Его нужно чаще всего запускать по крону (а может он у вас будет вертеться в бесконечном цикле, а может спать в потоковом режиме выполнения).
    Планировщик, на основе результатов проходов паука, парсера, ограничений на проходимых сайтах, нагрузки собственной системы, будет регулировать частоту запуска перезапуска заданий.
    Желательно, чтобы задания паука и парсера были достаточно атомарны.
    Паук в одну страницу постучал, записал статус получения ответа, каков контент в ответе (html или текстовое сообщение, или JSON и тд.), удалось ли ему распознать структуру, метаданные и тд.
    Если, например, вернулась 404 стр, то возможно, с помощью планировщика установить правило, что можно натравить паука на url чуть позже, через час, день, неделю и тд.
    По аналогии, можно фиксировать статусы работы других подсистем checker-а, парсера.
    Если один из модулей застревает на 5 разе на каком-то задании, то сыпать критическую ошибку в лог и тд.

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

    @alexalexes
    У вас что клиентский, что серверный скрипт не имеют функционала оповещать пользователя о возникшей ошибке.
    php-скрипт должен отдавать хоть малюсенькое текстовое сообщение, что удалось отправить почту.
    ....
    $send_result = mail($admin_email, adopt($form_subject), $message, $headers );
    echo $send_result ? 'success' : 'fail';

    Клиентский скрипт должен иметь возможность в коллбэк функции done словить это сообщение:
    ...
    ).done(function(e)
    {
        var resp = e.responseText;
        alert(resp === 'success' ? 'Сообщение отправлено!' : 'Ошибка отправки сообщения');
    ....
    }

    Для аякса хорошо бы еще добавить функцию fail(), когда серверный скрипт вообще не отвечает.
    $.ajax({
          type: "POST",
          url: "../js/mail.php", //Change
          data: th.serialize()
        }).done(function(e) {
         .......
        }).fail(function()
        {
          alert('Фатальная ошибка отправки!');
        });

    Немного доработав скрипты, и получив некоторые сообщения, можно будет сориентироваться, какого рода ошибка у вас возникла.
    Ответ написан
    Комментировать
  • Как удалить нужную запись из БД?

    @alexalexes
    Если заняться изучением основ SQL, то можно понять, что в данной ситуации самым оптимальным решением будет - выполнить запрос с параметром:
    DELETE FROM videos WHERE id = ?
    Естественно, на странице браузера надо обеспечить, чтобы при нажатии кнопки "Удалить" серверу передавался id удаляемой записи, помимо того, какое действие мы хотим совершить.
    Серверный скрипт, также должен принимать не только параметр вида действия (delete), но параметр id, на какую запись необходимо направить действие. Далее, структура SQL-запроса должна иметь в себе возможность подставить параметр.
    PS:
    $ids = R::getAssoc('SELECT id FROM videos');
        $videos = R::find( 'videos', 'id = ?', $ids );

    Самое не оптимальное решение - выгребать все записи из таблицы, а потом на стороне серверного приложения искать ту единственную, которая удовлетворяет условию. Эта медвежья услуга нагружает тракт обмена данных между веб-сервером и СУБД-сервером.
    Ответ написан
    Комментировать
  • Как сделать вывод значений из одинаковых полей формы?

    @alexalexes
    Обработчик селекта js который и меняет блоки с помощью display:none, display:block.

    Вариант А. Переписать этот обработчик так, чтобы наверняка удалял неиспользуемый вариант и создавал блок с нужным вариантом полей, тогда у вас в форме не будут лишних полей.
    Вариант A2. Переписать этот обработчик так, чтобы в скрытых блоках имена полей были с префиксами, а не в скрытых префиксы убирались, тогда сервер будет обрабатывать только те поля, у которых нормальные имена (без префиксов).
    Вариант A3. К дополнению к display: none, нужно вырубать поля атрибутом disable.
    Вариант Б. Поля с именами, которые будут обрабатываться на сервере вынести в отдельные поля hidden (на форме будут поля с теме же именами, но с префиксами, чтобы они не пересекались и не брались в учет сервером), и по submit сделать обработчик, чтобы он переносил в них значения по текущему состоянию формы.
    PS: Самый нетрудозатратный для разработчика - вариант А3.
    /* 
      Функция вкл и выкл полей формы в различных контейнерах
      @param str enable_id - id-контейнера, в котором нужно вкл. поля ввода
      @param arr disable_ids - массив id контейнеров, в которых нужно выкл. поля ввода
    */
    function fields_enable_and_disable(enable_id, disable_ids)
    {
      var enable_container = document.getElementById(enable_id); // получаем контейнер, в котором нужно "включить" поля ввода
      var field_types = ['input', 'select', 'textarea']; // все виды полей ввода с которыми нужно проделать манипуляцию вкл/выкл.
      var count_i = field_types.length; // кол-во типов полей
      for(var i = 0; i < count_i; i++) // перебираем типы полей
      {
        var field_type = field_types[i]; // текущий тип поля
        var enable_fields = enable_container.getElementsByTagName(field_type); // получаем коллекцию полей ввода, которые нужно вкл.
        var count_j = enable_fields.length; // кол-во полей текущего типа
        for(var j = 0; j < count_j; j++) // перебираем поля этого типа
          enable_fields[j].disabled = false; // включаем
        var count_k = disable_ids.length; // кол-во контейнеров, в которых нужно выкл. поля
        for(k = 0; k < count_k; k++) // перебираем неактивные контейнеры
        {
          var disable_id = disable_ids[k]; // id - текущего неактивного контейнера
          var disable_container = document.getElementById(disable_id); // получаем неактивный контейнер
          var disable_fields = disable_container.getElementsByTagName(field_type); // получаем поля текущего типа неактивного контейнера
          var count_n = disable_fields.length; // кол-во этих полей по текущ. типу
          for(var n = 0; l < count_n; n++)
            disable_fields[n].disabled = true; // выкл. эти поля
        }
      }
    }
    Ответ написан