Ответы пользователя по тегу PHP
  • Поведение PHP На разных ОС?

    orlov0562
    @orlov0562 Куратор тега PHP
    I'm cool!
    Могу предположить, что проблема тут не в скрипте, а в том, что было два запроса.

    Попробуй использовать в $data microtime() или rand() чтобы понять что это не запись была два раза, а именно был вызван метод два раза

    Кроме этого, погуглить советую про flock и fclose
    Ответ написан
  • Как сделать простой php-роутер?

    orlov0562
    @orlov0562 Куратор тега PHP
    I'm cool!
    .htaccess
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-l
    RewriteRule ^(.+)$ index.php?route=$1 [QSA,L]


    index.php
    try {
        // берем переданный роут
        $route = trim($_REQUEST['route']??'index');
    
        // проверяем, если в конце слеш, то это index роут
        if (substr($route,'-1') == '/') $route.='index';
    
        // минимальная защита от инклуда неожидаемых файлов
        // ограничиваем имена до символов a-b, 0-9, тире, нижнее подчеркивание и слеш
        if (!preg_match('~^[-a-z0-9/_]+$~i', $route)) throw new Exception('Not allowed route');
    
        // генерим путь к файлу
        $filePath = dirname(__FILE__).'/pages/'.$route.'.php';
    
        // если не существует выкидываем ошибку
        if (!file_exists($filePath)) throw new Exception('Route not found');
    
        // если существует, инклудим файл
        include $filePath;
    } catch (Throwable $ex) {
        // в случае любых ошибок, показываем 404
        // тут обычно делают разные типы эксепшенов и разделяют 400 и 500 ошибки
        include dirname(__FILE__).'/pages/404.php';
    }


    структура вызова
    / => /pages/index.php
    /index => /pages/index.php
    /about => /pages/about.php
    /user/ => /pages/user/index.php
    /user/index => /pages/user/index.php
    /user/hello => /pages/user/hello.php
    ...
    /404 => /pages/404.php
    /<not-found> => /pages/404.php
    /user/<not-found> => /pages/404.php

    Далее доработать по потребностям.

    Но, я бы не советовал самому пилить, т.к. есть много всяких нюансов. Кроме того, есть куча готовых, проверенных, решений. Разве что, просто для интереса.
    Ответ написан
  • Почему не работает оператор If?

    orlov0562
    @orlov0562 Куратор тега PHP
    I'm cool!
    Я думаю, у тебя в условиях ошибка

    Попробуй вывести переменную
    $type = $_POST['type'];
    var_dump($type);

    и посмотреть что там оказывается в итоге

    так же назначь $question значение по-умолчанию, чтобы понимать что ни одно из условий не отработало
    $question = 'n/a';
    ...
    If($type == 'surname'){
      echo "1";
      $question = $_POST['surname_3'];


    кроме того, обрати внимание на оператор switch с ним было бы удобнее
    $type = $_POST['type'];
    
    switch($type) {
        default: // если тип не опознан сгенерировать ошибку
            throw new Exception('Undefined type: '.$type);
        break;
        case 'surname': 
            $question = $_POST['surname_3'];
        break;
        case 'id_publick': 
            $question = $_POST['id_3'];
        break;
        case 'phone_num': 
            $question = $_POST['phone_num_3'];
        break;
    }
    Ответ написан
  • Как реализовать подтверждение удаления записи из БД?

    orlov0562
    @orlov0562 Куратор тега PHP
    I'm cool!
    Это чистый JS, в обработчике onclick вызывается диалоговое окно, которое или пропускает или отменяет действие, самый простой пример
    <a onclick="if (!cofirm('Точно удалить?')) return false" href="#">удалить</a>


    Еще пример


    Вроде можно с помощью JS, но я в нём не особо разбираюсь пока что

    Для этой задачи придется разобраться, ничего не поделать.

    Хотя, не совсем точно, можно и на чистом php построить что-то типа "мастера", где у тебя будут в зависимости от параметров рендерится разные страницы, но это извращение.. Что-то типа

    Шаг 1. Рендерится страница с кнопкой удаления
    Шаг 2. Рендерится страница с диалогом удаления, на котором две ссылки
    ?=action=delete&confirm=yes
    ?=action=delete&confirm=no
    Шаг 3. Чекаем что выбрал пользователь в параметре confirm
    Ответ написан
  • Как быстрее всего обновить товары на сайте из xml файла?

    orlov0562
    @orlov0562 Куратор тега PHP
    I'm cool!
    Все очень зависит от того как происходит сравнение, если это вложенный цикл, что-то типа
    foreach($newItems as $newItem) {
        foreach($oldItems as $oldItem) {
        }
    }

    то конечно это будет долго. В этой ситуации наиболее простая оптимизация, это при нахождении старой записи, удалять ее из массива, тогда чем дольше будет работать скрипт, тем меньше будет oldItems и тем больше будет скорость.
    $existedItems = [...]
    foreach($newItems as $newItem) {
        $oldItems = $existedItems;
        foreach($oldItems as $k=>$oldItem) {
             unset($existedItems[$k]);
        }
    }


    Более логичный вариант, если хватает ресурсов, это загрузить оба массива в память, для каждого из них составить составной ключ "СкладКод+НоменклатураКод" и искать элементы по нему

    $newItems = [];
    foreach($newItemsXml as $newItemXml) {
        $hash = $newItemXml->storeId.'::'.$newItemXml->sku; // генерим хеш
        $newItems[$hash] = $newItemXml;
    }
    ...
    // то же самое для $oldItems
    ...
    foreach ($newItems as $hash=>$newItem) {
        $oldItem = $oldItems[$hash]; // максимально быстрая выборка
        ...
    }


    Если памяти не так много, тогда тот же подход но разделенный по складам, т.е. сначала один склад прогоняем, потом второй.

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

    orlov0562
    @orlov0562 Куратор тега PHP
    I'm cool!
    Я не знаком с этой библиотекой, но пример на гите выглядит так
    var_dump ($zaif->fetch_ticker ('BTC/JPY'));
    если это и есть аналогичный вывод (т.е. var_dump), то тебе надо просто получить данные в массив и затем вывести их в соответствии с ключами

    У тебя сейчас такой вывод
    array(20) {
      ["symbol"]=>
      string(7) "XMR/ETH"
      ["timestamp"]=>

    значит тебе надо сделать что-то типа
    $data = $zaif->fetch_ticker ('BTC/JPY')
    вместо
    var_dump($zaif->fetch_ticker ('BTC/JPY'))
    и потом ты сможешь использовать значения обращаясь по ключу
    echo $data ["symbol"]; // выведет XMR/ETH
    Ответ написан
  • Как вместо таймера прописать дату?

    orlov0562
    @orlov0562 Куратор тега PHP
    I'm cool!
    Делай по аналогии с тем, что уже есть + нужна функция склонения существительных
    <?php
    function tpl_tpluralForm($n, $form1, $form2, $form3)
    {
        $n = abs($n) % 100;
        $n1 = $n % 10;
    	
        if ($n > 10 && $n < 20) {
            return $form3;
        }
    	
        if ($n1 > 1 && $n1 < 5) {
            return $form2;
        }
    	
        if ($n1 == 1) {
        return $form1;
        }
    	
        return $form3;
    }
    
    $seconds = 2*24*60*60 + 8*60*60;
    
    $days = floor( $seconds / (24*60*60) );
    $hours = $seconds < 24*60*60
                  ? floor( $seconds / (60*60) )
                  : floor( ($seconds % (24*60*60)) / (60*60) )
    ;
    echo $days.' '.tpl_tpluralForm($days, 'день', 'дня', 'дней')
         .' '.$hours.' '.tpl_tpluralForm($hours, 'час', 'часа', 'часов');


    Выведет: 2 дня 8 часов
    Ответ написан
  • Как решить ошибку с Warning: count(): Parameter must be an array or an object that implements Countable in ....?

    orlov0562
    @orlov0562 Куратор тега PHP
    I'm cool!
    Эту ошибку возвращает count когда в него передается null. До версии php 7.2 вернет 0, а с версии php 7.2 будет описанная ошибка.

    Исправить можно, вот так
    $products = $this->getProductList();
    if ($products) {


    а лучше так
    $products = $this->getProductList();
    if (is_iterable($products)) {


    а еще лучше вот так
    $products = $this->getProductList();
    if (is_countable($products)) {

    но для этого варианта нужен или php 7.3 или полифил который можно найти в комментариях к описанию функции https://www.php.net/manual/ru/function.is-countable.php
    Ответ написан
  • Почему WordPress через некоторое время выполнения PHP скрипта дает 404?

    orlov0562
    @orlov0562 Куратор тега PHP
    I'm cool!
    Это не проблема WP. Это ограничение или веб-сервера или времени выполнения скрипта (гугли set_time_limit). Запускай парсер через cron, напрямую, без участия веб-сервера и увеличенным временем выполнения скрипта.
    Ответ написан
  • Как проверить повторы в бд и не вносить запись при их нахождении?

    orlov0562
    @orlov0562 Куратор тега PHP
    I'm cool!
    Почитай про конструкцию: INSERT IGNORE ..

    $stmt = mysqli_prepare($link, "INSERT IGNORE INTO Users (a1, a2, a3, s1, s2) VALUES (?, ?, ?, ?, ?)");
    mysqli_stmt_bind_param($stmt, 'sssss', $a1, $a2, $a3, $s1, $s2);
    
    foreach($json['object'] as $item) {
      $a1 = $item['a1'];
      $a2 = $item['a2'];
      $a3 = $item['a3'];
      $s1 = $item['s1'];
      $s2 = $item['s2'];
      mysqli_stmt_execute($stmt);
    }
      mysqli_stmt_close($stmt);
      mysqli_close($link);
    Ответ написан
  • Как удалить из TXT файла, строчки где нет символа "@" используя PHP?

    orlov0562
    @orlov0562 Куратор тега PHP
    I'm cool!
    Для решения твоей задачи, тебе необходимо считать файл в переменную. Сделать это можно разными способами, но наиболее уместные тут, это: file и file_get_contents.

    Далее в случае с file_get_contents тебе надо или использовать регулярные выражения, для замены строк с помощью функции preg_replace и модификатором m в регулярном выражении, тем самым выполнить первую часть твоей задачи. Либо разбить полученный текст на строки с помощью функции explode по символу перевода строки. В результате получишь массив строк.

    В случае когда у тебя есть массив строк, тебе надо пройтись по нему и проанализировать строки на предмет вхождения подстроки. Заводишь новый массив, куда будешь складывать строки. Итерация делается с помощью for, foreach или while. Поиск подстрок делается с помощью функции strpos или mb_strpos. Соответственно если нет символа @, добавляешь строки в новый массив, если нет, то нет.

    Для того, чтобы убрать повторение строк, используй эту же строку в качестве ключа ассоциативного массива. Так же можно использовать функцию array_unique после того, как будет сделана первая часть задачи.

    После того, как ты это сделаешь, тебе нужно будет склеить строчки обратно в текст, для этого используй функцию implode. Записать полученный текст в файл, тебе поможет функция file_put_contents
    Ответ написан
  • Можно ли хранить SQL запрос в переменной сессии PHP?

    orlov0562
    @orlov0562 Куратор тега PHP
    I'm cool!
    Хранить в сессии SQL запрос вполне безопасно.

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

    Кеш непосредственно запроса, имеет смысл использовать, если для формирования конечного запроса, используются дополнительные запросы и эти запросы не поддаются кешированию на стороне бд.
    Ответ написан
  • Как передать через ajax значение нескольких чекбоксов?

    orlov0562
    @orlov0562 Куратор тега PHP
    I'm cool!
    У меня указанный код отрабатывает так, как и ожидается, данные отправляет POST запросом.

    советую проверить, Function.php на наличие ошибок
    на время дебага закомментировать location.href = 'Vyzi.php'; или заменить на alert/console.log
    и добавить error коллбек, по аналогии с success

    так же попробуй открыть консоль разработчика в браузере (F12), перейди на вкладку Network и посмотри что отправляется и что возвращается в ответ
    Ответ написан
  • Как вывести массив foreach в обратном порядке?

    orlov0562
    @orlov0562 Куратор тега PHP
    I'm cool!
    у array_reverse есть второй параметр отвечающий за сохранение порядка ключей
    <?php
    $go = ['test1','test2','test3'];
    print_r(array_reverse($go, true));

    выведет
    Array ( [2] => test3 [1] => test2 [0] => test1 )

    более правильное решение если массив именно такой как ты указал, т.е. не ассоциативный
    <?php
    $go = ['test1','test2','test3'];
    
    for ($i=count($go)-1; $i>=0; $i--) {
         echo $i.' => '.$go[$i].'<br>';
    }

    выведет
    2 => test3
    1 => test2
    0 => test1
    Ответ написан
  • Php сформировать массив?

    orlov0562
    @orlov0562 Куратор тега PHP
    I'm cool!
    <?php
    $arr = [
     8=>array (
        'id' => '9',
        'master_theme' => 'Безопасность',
        'theme' => 'Светофоры',
      ),
      9 =>
      array (
        'id' => '10',
        'master_theme' => 'Безопасность',
        'theme' => 'Экологическая полиция',
      ),
      10 =>
      array (
        'id' => '11',
        'master_theme' => 'Благоустройство',
        'theme' => 'Благоустройство ВДНХ',
      ),
      11 =>
      array (
        'id' => '12',
        'master_theme' => 'Благоустройство',
        'theme' => 'Благоустройство водоёмов',
      ),
    ];
    
    $res = [];
    
    foreach($arr as $item) $res[$item['master_theme']][] = $item['theme'];
    
    echo '<pre>';
    print_r($res);
    echo '</pre>';


    результат

    Array
    (
        [Безопасность] => Array
            (
                [0] => Светофоры
                [1] => Экологическая полиция
            )
    
        [Благоустройство] => Array
            (
                [0] => Благоустройство ВДНХ
                [1] => Благоустройство водоёмов
            )
    
    )
    Ответ написан
  • Почему после подключения RedBeanPHP перестают работать js?

    orlov0562
    @orlov0562 Куратор тега PHP
    I'm cool!
    Привет.

    RedBeanPHP сам по себе не может влиять на js. Всего скорее, у тебя происходит какая-то ошибка и в конечный html добавляется какой-то код (сообщение об ошибке, или трейс ошибки), который и ломает все.

    Открой конечный код html (Ctrl+U в браузере) и посмотри что выводится в месте подключения redbean. Предполагаю, что там ошибка или код обрывается, это и приводит к проблеме.
    Ответ написан
  • В каких случаях стоит использовать redbeanphp?

    orlov0562
    @orlov0562 Куратор тега PHP
    I'm cool!
    Привет,

    RedBeanPHP - это ORM которая отличается от всех своих собратьев тем, что может на лету создавать и менять схему базы данных в режиме разработчика. В остальном это обычная ORM-ка, которых сейчас целая куча.

    В 95% фреймворков встроены собственные ORM-ки которые и надо использовать. В остальных 5% можно использовать все что угодно, хоть голый mysqli, хоть PDO, хоть ReadBeanPHP, главное чтобы тебе было комфортно. Я, например, когда надо что-то накидать "на коленке" использую Idiorm или Paris, удобнее чем PDO напрямую, покрывает 99% потребностей, легко читается, легко переписывается на что-то другое.
    Ответ написан
  • Как через curl передать дополнительные параметры следующего вида?

    orlov0562
    @orlov0562 Куратор тега PHP
    I'm cool!
    Привет

    Я думаю ты ищешь функцию http_build_query

    $url = 'https://site.com/?'
              .http_build_query([
                  'queryString' => [
                      ['name'=>'date', 'value'=>'2019-05-10'],
                      ['name'=>'showAll', 'value'=>true],
                  ],
    ]);
    echo $url;


    если перейти по такому url в $_GET окажется

    Array
    (
        [queryString] => Array
            (
                [0] => Array
                    (
                        [name] => date
                        [value] => 2019-05-10
                    )
                [1] => Array
                    (
                        [name] => showAll
                        [value] => 1
                    )
            )
    )
    Ответ написан
  • Как отправлять заголовок и url страницы в форме обратной связи?

    orlov0562
    @orlov0562 Куратор тега PHP
    I'm cool!
    можно добавить в форму любые скрытые поля используя html тег input с типом hidden
    <input type="hidden" name="url" value="тут-url-страницы">
    <input type="hidden" name="form-title" value="тут-название-формы">

    сами поля можно либо заранее заполнить через php, либо отлавливать event у формы "on submit" через js и заполнять их перед отправкой формы
    Ответ написан