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

    erge
    @erge
    Примус починяю
    для MySQL смотрите функции работы с датами и CASE WHEN
    DATETIME приводите к DATE и через CASE WHEN определяете

    SELECT
        id,
        dt,
        CASE DATE(dt)
          WHEN CURDATE() THEN 'Сегодня'
          WHEN CURDATE() + INTERVAL -1 DAY THEN 'Вчера'
          ELSE 'Ранее'
        END AS when_day
      FROM items
    ;


    см. пример

    для PHP аналогично, смотрите switch case и DateTime для работы объектом, который представляет дату и / или время и методы для манипуляции с ними.

    $now = new DateTime();  // текущая дата
      switch ($DATEPOSTED) { // в формате Y m d
        case $now->format("Y m d"):
            echo "сегодня";
            break;
        case ((clone $now)->modify("yesterday"))->format('Y m d'):
            echo "вчера";
            break;
        default:
            echo "ранее";
      }


    PS: здесь (clone $now) я клонирую $now, чтобы не изменять основную переменную, если обернуть в функцию то это не обязательно, см. пример ниже.

    см. полный пример

    UPDATE:
    касательно кода в стилистике автора
    $DATEPOSTED = strtotime("-1 day");
    здесь вчерашний день задается неверно!
    во-первых, strtotime - Преобразует текстовое представление даты на английском языке в метку времени Unix
    во-вторых, время Unix (timestamp) не совпадает с форматом заданным выше и в $now - Y m d, поэтому сравнивать их некорректно, необходимо приводить дату к одному формату Y m d
    $DATEPOSTED = date('Y m d', strtotime(' -1 day'));
    далее по условию, если необходимо просто сравнивать с сегодня и что не сегодня то это вчера, то условие вообще банальное:
    if ($now == $DATEPOSTED) {
    Ответ написан
    Комментировать
  • Можно ли написать циклический запрос, получающий последнюю запись из древа, не делая несколько запросов в цикле?

    erge
    @erge
    Примус починяю
    -- вывод ветки дерева
    WITH RECURSIVE
    cte (id, title, parent_id) AS (
      SELECT     id,
                 title,
                 parent_id
      FROM       test
      WHERE      id = 1 -- < id узла от которого выводить
      UNION ALL
      SELECT     t.id,
                 t.title,
                 t.parent_id
      FROM       test t
      INNER JOIN cte
              ON t.parent_id = cte.id
    )
    SELECT * FROM cte;


    для того чтобы идти от потомка к родителю, необходимо "развернуть" связь в ON t.parent_id = cte.id т.е. ON t.id = cte.parent_id и из полученного выбрать запись с parent_id is null

    т.е. так:
    -- вывод самого верхнего родителя по дочернему узлу
    WITH RECURSIVE
    cte (id, title, parent_id) AS (
      SELECT     id,
                 title,
                 parent_id
      FROM       test
      WHERE      id = 4 -- < id узла
      UNION ALL
      SELECT     t.id,
                 t.title,
                 t.parent_id
      FROM       test t
      INNER JOIN cte
              ON t.id = cte.parent_id
    )
    SELECT * FROM cte
      WHERE parent_id IS NULL;


    см. пример

    для MySQL 5+ можно так:

    SELECT * FROM (
      SELECT  id,
              title,
              parent_id 
        FROM (SELECT * FROM test ORDER BY id DESC) test_sorted
        JOIN (select @pv := 4) initialisation -- < id узла
        WHERE find_in_set(id, @pv)
          AND length(@pv := concat(@pv, ',', COALESCE(parent_id, '')))
    ) t
      WHERE parent_id is null
    Ответ написан
    Комментировать
  • Как заменить двойные кавычки на "?

    erge
    @erge
    Примус починяю
    Нужно сначала разбить текст на группы attribute_name="attribute_value" затем для этих групп вызвать замену и это можно сделать при помощи preg_replace_callback

    регулярка для поиска ([^= ]+)="(.*?)"\s+(?=([^= ]+=|\/>))
    см. RegEx101

    используем ее в preg_replace_callback, находим пары атрибут=значение и заменяем , делая подмену символов в значении через htmlspecialchars

    $str = '
    <order acode="7102774" ProductName="Какой-то текст "с скобочками", которые нужно заменть" ClientBarCode="" />
       <order acode="7102774" ProductName="Какой-то текст "с скобочками", которые нужно заменть" ClientBarCode="" />
     <order acode="7102774" ProductName="Какой-то текст "с скобочками", которые нужно заменть" ClientBarCode="" />
          <order acode="7102774" ProductName="Какой-то текст "с скобочками", которые нужно заменть" ClientBarCode="" />';
    
    $out = preg_replace_callback(
        '/([^= ]+)="(.*?)"\s+(?=([^= ]+=|\/>))/',
        function($m) {
            return $m[1].'="'.htmlspecialchars($m[2], ENT_QUOTES).'" ';
        },
        $str);
        
    echo $out;


    см. пример
    Ответ написан
    Комментировать
  • PHP как правильно написать регулярное выражение для обработки url?

    erge
    @erge
    Примус починяю
    https:\/\/site.ru\/[A-Z0-9]{8}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{12}\/$


    пример на regex101
    Ответ написан
    Комментировать
  • Как получить название и 'картинку' из БД?

    erge
    @erge
    Примус починяю
    Нет связи между таблицами file_managed или field_revision_field_image с таблицей node, поэтому у вас получается декартово произведение.
    состоящее в перечислении через запятую табличных выражений в предложении FROM (таблицы, представления, подзапросы) при отсутствии предложения WHERE, связывающего столбцы из перечисленных источников строк
    (см.)
    в настоящее время у вас только одна связь по типу 'article' и этого очевидно недостаточно.
    Ответ написан
    Комментировать
  • Как лучше всего формировать xlsx в php на 10+ млн ячеек?

    erge
    @erge
    Примус починяю
    Чтобы было быстрее работайте с файлами xl/worksheets/sheet?.xml (внутри zip архива - xlsx файла) напрямую! либо как с XML, либо как с текстом поиск/замена (через регулярки например), хотя... если это чистый файл с нуля, то проще и быстрее генерировать эти файлы с нуля как текст, в этом файле данные в разделе sheetData, см. пример:

    <sheetData>
        <row r="1">
          <c r="A1" t="str">
            <v>Иванов</v>
          </c>
          <c r="B1" t="str">
            <v>Петров</v>
          </c>
          <c r="С1" t="str">
            <v>Сидоров</v>
          </c>
    ...
        </row>
      </sheetData>


    PS: да сохраните любой эксельник в xlsx переименуйте в zip и посмотрите, поймете.

    Либо переходите на связку ... например на Go + пакет Excelize и либо на нем микросервис сделать и соответственно работать, либо бинарник для cmdline и соответственно вызывать его из PHP
    Ответ написан
  • Как экспортировать базу JSON в MYSQL?

    erge
    @erge
    Примус починяю
    1. не экспорт, а импорт
    2. гуглите (яндексите) import json to mysql (есть море информации)
    3. если импортировать записи как в примере в простую таблицу в новую БД, то проще и быстрее как уже говорили выше - загружать напрямую в базу из CSV файла, а json конвертнуть в CSV при помощи sed например (одной строчкой)
    Ответ написан
    Комментировать
  • Как настроить выгрузку excel на PHPEexcel чтобы выгрузка из mysql начиналась с первого элемента, а не со второго?

    erge
    @erge
    Примус починяю
    $query1 = mysqli_query($link, "SELECT * FROM goods ORDER BY id");


    $s = 1;

    UPD:

    да, заметил...
    зачем зафетчили первую строку до вывода в цикле??
    $myrow = mysqli_fetch_array($query1);
    удалите ее.
    Ответ написан
    3 комментария
  • Как перебрать неопределённое количество элементов через цикл?

    erge
    @erge
    Примус починяю
    Можно ли как-то это всё прогнать через цикл, чтобы избавиться от дублирования кода?


    от дублирования кода избавляют функции или методы в классах.
    Ответ написан
    Комментировать
  • Как найти телефон в sql с помощью match against?

    erge
    @erge
    Примус починяю
    UPD:
    немного неверно написал ранее, т.к. это поиск по части номера, то естественно надо LIKE
    $sql = "SELECT * FROM tbl WHERE replace(replace(replace(replace(phone,'(',''),')',''),' ',''),'-','') LIKE concat(replace(replace(replace(replace('".$num."','(',''),')',''),' ',''),'-',''), '%')";


    UPD2:
    PS:
    Не совсем понимаю как это реализовать с помощь полнотекстового поиска.

    а зачем вообще реализовывать это с помощью полнотекстового поиска??
    если номер телефона хранится в отдельном поле, в определенном формате?
    1. либо приводите обе стороны "искомого" к одному формату (т.е. удаляете все лишнее) как например выше.
    2. либо, если номера в базе хранятся в одном формате приводите искомый (вводимый) номер к формату хранения в базе + знак % и поиск LIKE
    3. либо делаете поиск через REGEXP соответствующим образом формируя рег.выражение из PHP
      но это несколько сложнее, надо ее динамически формировать в зависимости от введенных цифр.
      вот регулярка для проверки телефона практически в любом варианте написания:
      ^\+?7[ -]?\(?\d{3}\)?[ -]?\d{3}[ -]?\d{2}[ -]?\d{2}$

      под MySQL сами перепишите... см. ссылку выше, там другие классы символов.
    4. либо, если все же таки нужен полнотекстовый поиск, то искомое значение НЕОБХОДИМО приводить к формату в базе и искать отформатированное значение
    Ответ написан
    Комментировать
  • Как исправить ошибку при выводе из 2-х таблиц?

    erge
    @erge
    Примус починяю
    1. а если INNER JOIN ?

    SELECT `zadachi`.id AS id_zadacha,`zadachi`.*,`users`.* 
      FROM `zadachi`
      INNER JOIN `users` ON `users`.id_1c = `zadachi`.autor
      WHERE `zadachi`.komy = '$id' OR (`zadachi`.autor = '$id' AND `zadachi`.komy = '$id') 
      ORDER BY `zadachi`.id DESC


    2.
    а: Группа новых задач...
    б: Группа просроченных задач...
    в: Группа поставленных задач кому то...


    3 запроса, объединить через UNION ALL
    типа
    SELECT 'NEW' as group, .... FROM ... 
    UNION ALL
    SELECT 'EXPIRED' as group, ... FROM ...
    UNION ALL
    SELECT 'OTHER' as group, ... FROM ...
    Ответ написан
  • Где ошибка в функции запроса в бд?

    erge
    @erge
    Примус починяю
    Catchable fatal error: Object of class waDbResultSelect could not be converted to string in

    вы хотя бы пробовали перевести данную строку??
    объект класса waDbResultSelect не может быть преобразован в строку

    ни о чем не говорит??

    Ну вы посмотрите внимательно, что вы делаете-то??
    $n = $model -> query("SELECT * FROM `w3m_404urls` WHERE `url`= '$rqul'")


    у вас в $n находится waDbResultSelect, т.е. резалтсет (целая строка(и) таблицы)
    к тому же и в запросе у вас * (т.е. в результате как минимум не одно поле)

    может быть вы все-таки из резалтсета возьмете одно поле url и будете его сравнивать с $rqul , а не весь резалтсет?

    см. waModel и waDbResultSelect

    Ну, и, не вижу никакого смысла сравнивать кислое с пресным, в смысле одно и тоже.
    вы выбираете по url и потом выбранное опять с ним же сравниваете ??
    надо считать кол-во выбранного - если > 0 , то запись есть. соответственно далее ...

    $n = $model -> query("SELECT * FROM `w3m_404urls` WHERE `url`= '$rqul'")->count();
    if ($n > 0 ) {
    // UPDATE
    } else {
    // INSERT
    }


    PS: ну и почему бы не упомянуть что вы используете Webasyst , здесь экстрасенсы??
    Ответ написан
    1 комментарий
  • Почему не редактируются данные в БД?

    erge
    @erge
    Примус починяю
    первичный ключ, которым должен быть по идее id, у вас не указан как primary key, во все строках равен 0 - почему!?

    необходимо поле id сделать первичным ключем, но прежде необходимо либо удалить все строки, либо в каждой строке прописать id инкрементально.

    правда все строки у вас идентичные и их никак не различить...
    поэтому можно сделать так:

    set @i = 0;
    
    update `grey_csgo_gifts_list`
      set id = @i := @i + 1;
    
    alter table `grey_csgo_gifts_list` modify `id` int(11) auto_increment primary key;


    см. пример на dbfiddle
    Ответ написан
    Комментировать
  • Как отсортировать полученный массив и создать таблицу?

    erge
    @erge
    Примус починяю
    получаете список этажей
    SELECT floor FROM $pndid GROUP BY floor

    фетчите в массив
    далее цикл по массиву

    в цикле: {
    выводите надпись этажа из элемента массива
    делаете запрос к базе вида:
    SELECT * FROM $pndid WHERE floor = $floor
    фетчите запрос и формируете "клиентскую" таблицу.
    }

    как-то так.

    PS: либо можно обойтись одним запросом, выбрать все что необходимо в JSON
    и далее уже обойти этот JSON
    Ответ написан
    Комментировать
  • Как получить отрендеренную HTML-страницу при помощи Selenium или PhantomJS?

    erge
    @erge
    Примус починяю
    c Selemium не работал, но имхо, брать надо не getPageSource, а после загрузки всей страницы, найти элемент, например body, и получить у него innerHTML, если вы парсите регэкспами. Либо работать с DOM страницы, что как бы наверно удобнее.

    примерно как-то так (возможно ошибаюсь с синтаксисом):

    $element = $driver->findElement(WebDriverBy::cssSelector('body'));
    
    $src = $element->getAttribute('innerHTML');
    
    # или так
    
    $src = $driver->executeScript("return document.body.innerHTML");
    Ответ написан
    1 комментарий
  • Как перемещать файлы между сайтами, которые находятся на одном сервере?

    erge
    @erge
    Примус починяю
    move_uploaded_file

    поправка, т.к. изначально не уловил сути:

    sudo chmod go+x /var
    sudo chmod go+x /var/www
    sudo chmod go+x /var/www/vhost
    sudo chmod go+x /var/www/vhost/site2
    sudo chmod go+x /var/www/vhost/site2/www
    sudo chmod go+rwx /var/www/vhost/site2/www/file
    Ответ написан
  • Почему php выводит из базы что то одно?

    erge
    @erge
    Примус починяю
    Подозреваю что на выходе , после цикла
    while($row = mysqli_fetch_array($res))
    Result set - $res становится ПУСТЫМ! поэтому второй while его не отрабывает.
    и либо
    - его необходимо наполнить заново, повторно выполнив запрос
    $res = mysqli_query($dbc, $query);

    либо, что более корректно:

    1) заполнить из result set некий массив, далее по коду уже работать с массивом.

    2) на каждом номере класса выполнять запрос
    SELECT * FROM `pupils` WHERE class = 'НОМЕРКЛАССА' -- я допустил что колонка у вас называется class

    и далее делать вывод анологично.

    3) что еще более правильное:
    получить из базы список классов, например
    SELECT DISTINCT class FROM `pupils` -- я допустил что колонка у вас называется class


    далее цикл по резалтсету
    выводим
    <div class="cl">
          <h3>НОМЕРКЛАССА</h3>


    делаем запрос вида
    SELECT * FROM `pupils` WHERE class = 'НОМЕРКЛАССА' -- я допустил что колонка у вас называется class


    далее цикл по резалтсету
    выводим
    <h4>ФИО</h4>
    конец вложенного цикла

    выводим закрывающий тэг </div>

    конец первого цикла.

    как-то так... ну код сами напишете ;)
    Ответ написан
    4 комментария
  • Как запустить nodejs скрипт через PHP exec?

    erge
    @erge
    Примус починяю
    может лучше скрипт node.js оформить как микросервис?
    и из PHP общаться с ним по API (REST API)
    PS: закрыть извне доступ на порт микросервиса, либо прикрутить авторизацию.
    так же в таком случае основное приложение и микросервис можно разнести на разные сервера.
    Ответ написан
  • Как считать данные из таблицы MySQL и внести их в массив с последующей записью?

    erge
    @erge
    Примус починяю
    Можно результат запроса обернуть в JSON форму, а в php к результату применить json_decode($result, true)

    SQL запрос:
    SELECT
        CONCAT(
          '{"',`session`,'":{',
          GROUP_CONCAT('"PRODUCT ', @i:=@i+1, '":{"PRODUCT ID":',product_id,',"PRICE":',price,',"QUANTITY":',quantity,'}' separator ','),
          '}}') AS value
      FROM carts, (SELECT @i:=0) X
      WHERE `session` = 222145
      GROUP BY `session`


    пример работы на sqlfiddle

    в PHP как-то так:
    $session_id = 222145;
    
    $sql = 'SELECT
        CONCAT(
          \'{"\',`session`,\'":{\',
          GROUP_CONCAT(\'"PRODUCT \', @i:=@i+1, \'":{"PRODUCT ID":\',product_id,\',"PRICE":\',price,\',"QUANTITY":\',quantity,\'}\' separator \',\'),
          \'}}\') AS value
      FROM carts, (SELECT @i:=0) X
      WHERE `session` = %s
      GROUP BY `session`';
    
    $arr = json_decode(mysql_result(mysql_query(sprintf($sql, $session_id)),0), true);
    
    var_dump( $arr );
    Ответ написан
    Комментировать
  • Как обработать и сравнить большой массив данных?

    erge
    @erge
    Примус починяю
    вариантов есть несколько....
    1) загружаете данные доступными вам способами во временную таблицу, далее UPDATE по этой таблице
    если из PHP, то собрать из массива запрос вида
    INSERT INTO tmp_goods (name, article, price)
      VALUES ('NAME_1', 'ARTICLE_1', PRICE 1),
    .......
             ('NAME_N', 'ARTICLE_N', PRICE_N)
    ;


    после чего выполнить UPDATE:
    UPDATE goods g
      INNER JOIN tmp_goods t ON t.article = g.article
      SET g.price = t.price
      WHERE g.price != t.price
    ;


    и очистить tmp_goods если она более не нужна.

    2) собрать из массива запрос вида:
    UPDATE goods
    SET price = CASE article
    WHEN ARTICLE_1 THEN PRICE_1
    WHEN ARTICLE_2 THEN PRICE_2
    ....
    ELSE price END


    так же есть операторы:
    REPLACE ,
    INSERT ON DUPLICATE KEY UPDATE
    и вообще погуглите - MySQL множественный апдейт

    и... еще вариант:
    можно обойтись без временной таблицы (как в варианте 1)...
    соберите из массива запрос вида:

    UPDATE goods g
      INNER JOIN (
        SELECT 'ARTICLE-1' AS article, PRICE_1 AS price UNION
        SELECT 'ARTICLE-2', PRICE_2 UNION
        SELECT 'ARTICLE-3', PRICE_3 UNION
    ...
        SELECT 'ARTICLE-N', PRICE_N
        ) t ON t.article = g.article
      SET g.price = t.price
      WHERE g.price != t.price
    ;


    смотрите пример на sqlfiddle (сосбтвенно update в левом поле описания схемы)
    Ответ написан
    Комментировать