Ответы пользователя по тегу PHP
  • Как разделить диапазон дат на 3 части?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    Три зоны на отрезке:
    1. до 1 сентября
    2. между 1 сент. и 31 окт
    3. после 31 окт
    Это три варианта начала, три варианта конца (совпадает или после начала)
    Из 3x3=9 комбинаций, реально возможны только 6. Дающие 1, 2 или 3 отрезка на выходе:
    .
         начало
       ---|---|---
    к | 1
    о -
    н | 2   1
    е -
    ц | 3   2   1


    Для простоты, та же задача с числами. Есть фиксированный отрезок 20..30 (сентрябрь - октябрь). И даются на вход два числа, второе больше первого.

    Можно «в лоб» записать логику условиями if - else if - else
    треш-код через условия
    function ranges(int $a, int $b): array
    {
        $start = 20;
        $finish = 30;
    
        $result = [
            'before' => null,
            'match' => null,
            'after' => null,
        ];
    
        if ($a < $start) {
            if ($b < $start) {
                $result['before'] = [$a, $b];
            } else {
                $result['before'] = [$a, $start];
                if ($b < $finish) {
                    $result['match'] = [$start, $b];
                } else {   
                    $result['match'] = [$start, $finish];
                    $result['after'] = [$finish, $b];
                }
            }
        } else if ($a < $finish) {
            if ($b < $finish) {
                $result['match'] = [$a, $b];
            } else {
                $result['match'] = [$a, $finish];
                $result['after'] = [$finish, $b];
            }
        } else {
            $result['after'] = [$a, $b];
        }
    
        return $result;
    }
    
    print(json_encode(ranges(5, 25))); // {"before":[5,20],"match":[20,25],"after":null}
    Но стоит подумать над более красивым решением. Положить все 4 значения в массив и отсортировать его по возрастанию. 4 значения определяют 3 смежных отрезка. Некоторые из отрезков стоит проигнорировать, если они за рамками входного диапазона.

    $arr = [$start, $finish, $a, $b];
    sort($arr, SORT_NUMERIC);
    Ответ написан
    Комментировать
  • Как в массиве чисел найти средний минимум и средний максимум?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    идти по массиву, вычислять разницу с предыдущим значением.
    Если разница поменала свой знак — предыдущая точка была локальным минимумом или максимум. Смотреть на знак разницы:
    1, 2, 3, 2, 3, 2, 1
    0  +  +  -  +  -  -
          ^  ^  ^ в этих точках знак поменялся
    Складывать найденные точки в два массива: максимумы и минимумы.
    Потом посчитать среднее в каждом.
    Ответ написан
    3 комментария
  • Функции хелперы, что это и зачем они нужны если и без них всё работает?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    Бывает непреодолимое желание избегать повторяющихся кусков кода. Часто оно здраво и ведёт к правильному рефакторингу кода.

    Когда повтор происходит внутри одного класса, его можно выделить в приватный метод этого же класса.

    Но бывает, один и тот же изолируемый функционал требуется в совершенно разных кусках приложения. Отсутствует какой-то один класс, куда его логично упрятать. Тогда можно создать хэлпер — например, класс со статическим методом, и вызывать его откуда угодно. Ну, или сервис..

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

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    нужно создать потоковый контекст и использовать stream-notification-callback (см. пример).

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

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    можно без (тяжелых) регулярок — с помощью sscanf():

    $str = "attachment=12345";
    list($number) = sscanf($str, "attachment=%d");
    
    echo $number; // 12345
    Ответ написан
    Комментировать
  • Как исправить ошибку в VK API Invalid request: v is required. Version param should be passed as "v". "version" param is invalid and not supported?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    ...[key] => album_id [value] => 286941183version=5.131

    ничего не смущает?

    Перед . http_build_query() надо ещё & добавить.

    По-хорошему, все параметры, включая owner_id и album_id лучше в общий массив, а потом http_build_query(). Для порядка. Заметите, что owner_id дублируете.
    Ответ написан
    Комментировать
  • Какие аналоги fetch есть в PHP?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    Три популярных способа выполнять веб-запросы в PHP:
    1. file_get_contents() – не самый удобный, но не требует установки зависимостей т.к. является частью ядра PHP
    2. curl – PHP должен быть собран с этой библиотекой, чаще всего на хостингах так и есть по умолчанию.
    3. Guzzle HTTP – устанавливается через Composer и значительно упрощает работу с запросами


    В PHP запросы чаще выполняют синхронно, без событий-промисов, хотя такая возможность и появилась.
    Выполнили запрос – дождались ответа. В следующей строчке работаете с полученным ответом.
    Ответ написан
    Комментировать
  • Разработать REST API - как изучать?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    1. понимать, как устроены веб запросы (чем GET принципиально отличается от POST и PUT)
    2. уметь спланировать и создать таблицу в базе данных
    3. работать с базой данных в PHP: подключаться, вставлять новые записи, находить существующие
    4. принимать и обрабатывать веб-запросы на PHP, фильтровать и валидировать данные. Возвращать ответы и сообщать о возможных ошибках.
    5. узнать, что все эти задачи – типовые, часто востребованные, и поэтому есть масса готовых решений – и научиться их находить и использовать
    Ответ написан
    9 комментариев
  • Как однозначно конвертировать цвет из RGB в HSL и обратно, получая один и тот же результат?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    цветовые пространства RGB и HSL не совпадают, поэтому несоответствия неизбежны.

    Например, полностью черному rgb(0, 0, 0) соответствует множество hsl(*, *, 0).

    Хотя например, в этой работе предлагают точный целочисленный метод конвертации: Integer-based accurate conversion between RGB and ... (на англ.). Один из авторов — Владимир Чернов, выпускник Петербургского Политехнического университета.
    Ответ написан
    1 комментарий
  • Как проверить вхождение диапазона дат в определенный диапазон?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    1. ассоциативный массив, где ключи даты, значения обозначают начало это или конец интервала.
    2. отсортировать по ключам
    3. двигаться слева направо, следить чтобы не было два начала подряд.
    Ответ написан
  • Как создать HTML таблицу для игры морской бой?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    Для таблицы 10 х 10 понадобится выводить 11 х 11, ведь добавляются заголовки строк / столбцов.

    HTML лучше собирать в одной переменной. И вывести её в самом конце.

    Сделайте для начала без динамики, без всех этих $_POST['size'] статичную таблицу 3х3.
    1, 2, 3; А, Б, В

    $size = 3;
    $rowTitles = explode(',', 'А,Б,В,Г,Д,Е,Ж,З,И,К');
    
    $html = '';
    for ($row = 0; $row <= $size; $row++) {
        $tr = '';
        for ($col = 0; $col <= $size; $col++) {
            if ($row === 0) {
                // строка с номерами столбцов
                if ($col === 0) {
                    $tr .= '<th></th>'; // угловая пустая ячейка
                } else {
                    $tr .= '<th>' . $col . '</th>'; // название столбца
                }
            } else {
                // строка с обычными клеточками
                if ($col === 0) {
                    // название строки
                    $tr .= '<th>' . $rowTitles[$row - 1] . '</th>';
                } else {
                    // обычная клеточка
                    $tr .= '<td>' . $rowTitles[$row - 1] . $col . '</td>';
                }
            }
        }
        $html .= $tr . PHP_EOL;
    }
    
    $html = '<table><tbody>' . $html . '</tbody></table>';
    
    echo $html;
    Ответ написан
    Комментировать
  • Как лучше реализовать постоянный отсчёт времени и суммирование значений?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    Надо ли иметь в БД статичное значение баллов? Может, оставить свойство вычисляемым — когда требуется узнать про конкретного пользователя, сколько у него баллов — выполняется поиск купленных им карточек за последние 10 дней и до сих пор активных, и суммируются.

    Либо можно обновлять базу cron-задачей. Округлить до какого-то интервала времени: 1 сутки (если все в одном городе), или 1 час, если пользователи со всех частей света. Карта начинает действовать в ближайший следующий «момент» после активации. В ближайшую полночь, скажем.

    1000 пользователей по 5 карточек — это не нагрузка, всё легко отработает.
    Ответ написан
    1 комментарий
  • Как одновременно запустить 1500 ботов, выполняющих http запросы?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    Если с PHP, то я бы делал это в Swoole: там и свои таблицы-в-памяти, и корутины, чтобы «сон» не тормозил остальных, — и вообще полезный опыт.

    P.S. не надо заниматься спамом, накрутками и прочим абьюзерством!
    Ответ написан
    2 комментария
  • Можно как то суммировать эти цифры использую цикл php?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    $sum = 0;
    for ($i = 9; $i <= 40; $i++) {
        if ($i % 2 === 0) {
            $sum += $i;
        }
    }
    echo "Сумма: $sum" . PHP_EOL;
    Ответ написан
    Комментировать
  • Как на php отрисовать динамическую картинку?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    рисовать на фронте в canvas ?
    Ответ написан
  • Как удалить Currency символ ₽?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    вместо asCurrency() может лучше asDecimal() в таком случае?
    Ответ написан
    Комментировать
  • Библиотеки синтаксического сахара на PHP?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    поищите на github

    для массивов там среди результатов MortalFlesh/MFCollectionsPHP
    Ответ написан
    Комментировать
  • Как создать меню в вложенностью из одного массива?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    Решение, но так-себе.. Идти по элементам, складывая их в массив-результат.
    Держать доп. массив референсов на последние элементы каждого из уровней.
    В нём находить очередного родителя подходящего уровня.
    Не забывать разрушать референсы.
    В общем, явно переусложнил.
    код
    $array = [
        ["TITLE" => "Тест 1", "LEVEL" => 1,],
        ["TITLE" => "Тест 2", "LEVEL" => 2,],
        ["TITLE" => "Тест 3", "LEVEL" => 2,],
        ["TITLE" => "Тест 4", "LEVEL" => 3,],
        ["TITLE" => "Тест 5", "LEVEL" => 2,],
        ["TITLE" => "Тест 6", "LEVEL" => 3,],
    ];
    
    const TITLE = 'TITLE';
    const LEVEL = 'LEVEL';
    const CHILDREN = 'CHILDREN';
    
    $result = [];
    $refs = [];
    
    foreach ($array as $item) {
        $level = $item[LEVEL];
    
        if ($level === 1) {
            $result[] = $item;
            $refs = [&$result[count($result) - 1]];
        } else {
            for ($i = count($refs) - 1; $i >= 0; $i--) {
                $parent = &$refs[$i];
                if ($parent[LEVEL] === $level - 1) {
                    if (!isset($parent[CHILDREN])) {
                        $parent[CHILDREN] = [];
                    }
                    $parent[CHILDREN][] = $item;
    
                    array_splice($refs, $i + 1);
                    $refs[] = &$parent[CHILDREN][count($parent[CHILDREN]) - 1];
    
                    unset($parent);
                    break;
                } else {
                    unset($parent);
                    continue;
                }
            }
        }
    }
    
    echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
    результат
    [
      {
          "TITLE": "Тест 1",
          "LEVEL": 1,
          "CHILDREN": [
              {
                  "TITLE": "Тест 2",
                  "LEVEL": 2
              },
              {
                  "TITLE": "Тест 3",
                  "LEVEL": 2,
                  "CHILDREN": [
                      {
                          "TITLE": "Тест 4",
                          "LEVEL": 3
                      }
                  ]
              },
              {
                  "TITLE": "Тест 5",
                  "LEVEL": 2,
                  "CHILDREN": [
                      {
                          "TITLE": "Тест 6",
                          "LEVEL": 3
                      }
                  ]
              }
          ]
      }
    ]
    Ответ написан
    Комментировать
  • Как записать первое значения из цикла?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    сначала пройти циклом по всем датам, отбирая победителя.
    Затем уже что-то выводить или записывать в файл.
    $recentChannel = null;
    foreach ($xml->channel->item as $channel) {
        if (!$recentChannel || strtotime($channel->pubDate) > strtotime($recentChannel->pubDate)) {
            $recentChannel = $channel;
        }
    }
     
    // теперь $recentChannel содержит канал с самой свежей датой
    Ответ написан
    Комментировать
  • Как лучше проверять строку на пустоту в php?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    Недостатки исходных вариантов проверки:
    $str = "0";  // непустая строка, содержащая цифру ноль
    if (!$str) echo "bool false\n"; // сработает
    if (empty($str)) echo "is empty\n"; // сработает
    
    $str = null; // не строка
    if ($str == "") echo "equals empty str\n"; // сработает
    if (strlen($str) === 0) echo "zero length str\n"; // сработает


    Поэтому лучший вариант, как и предложил Rsa97, проверять строгое равенство === с пустой строкой.
    Ответ написан
    Комментировать