Задать вопрос
Ответы пользователя по тегу PHP
  • Как отсортировать массив за цифрами?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    Disclaimer: неоптимальный вариант для популяризации функций PHP

    Можно использовать sscanf(), чтобы вынимать число из каждой строки (если они одинаково начинаются) и сортировать массив своей функцией, переданной в usort():

    $arr = [
      'image_name_1.jpg',
      'image_name_11.jpg',
      'image_name_2.jpg',
      'image_name_100.jpg',
      'image_name_001.jpg',
    ];
    
    usort($arr, function($a, $b) {
      $format = 'image_name_%d.jpg';
      list($aVal) = sscanf($a, $format);
      list($bVal) = sscanf($b, $format);
      return $aVal - $bVal;
    });
    
    echo json_encode($arr);
    /*
    ["image_name_1.jpg","image_name_001.jpg","image_name_2.jpg","image_name_11.jpg","image_name_100.jpg"]
    */
    Ответ написан
    Комментировать
  • Какой PHP-микро-фреймворк взять для простенького REST API с авторизацией, и чтобы не из "большой тройки"?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    Может, в редакторе Swagger накидать спеки API и автоматом сгенерить по ним сервер и клиент на любом из предлагаемых языков/фреймворков?

    Например, сервер под теми же Lumen, Slim, Silex, Symfony, Node.js
    Ответ написан
    5 комментариев
  • Получится ли сэкономить память с yield?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    Почему бы не измерить использование памяти во всех вариантах?
    БольшойМассив так и так остаётся в памяти и не копируется целиком в array_slice(). Что будет, если передать его в array_slice()по ссылке – уменьшится использование памяти?

    Почему бы вообще не работать со ссылкой на массив и не запоминать положение "курсора"?
    reset(), next(), current() – вот это вот всё..

    Второй вариант - выгрузить массив из памяти в файл, и читать чанки оттуда с нужной позиции. Например, если массив содержит 32-битные целые, то записать весь массив в бинарный файл, по 4 байта на число. См. pack() и unpack(). Оффсет в файле равен индексу числав массиве * 4 байта.
    Ответ написан
    4 комментария
  • Как сделать простой php-роутер?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    На github есть много популярных (по числу звёзд) реализаций php router'а.

    Задача типичная, решений много.

    Для обучения так же полезно, как писать велосипед, изучать чужой код.
    Ответ написан
    Комментировать
  • Как через php перезагрузить nginx?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    Можно просто по крону раз в 15 минут делать не перезагрузку самого nginx, а только перечитку конфигов.

    в кронтабе для root, с проверкой корректности конфигов:
    15 0 0 0 0  nginx -t  &&  nginx -s reload > /dev/null 2>&1


    Ещё лучше сделать bash-скрипт, где в случае непрохождения теста конфигов, отправлять письмо с восклицаниями.
    Ответ написан
    Комментировать
  • Как получить остаток от деления PHP?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    170 % 11 === 5; // true

    170 / 11 = 15,4545454545
    15 целых + остаток.
    11*15 = 165
    170 = 11 * 15 + 5
    Этот остаток 5 и получается оператором остатка от деления % (не путать с процентами)
    Ответ написан
    Комментировать
  • Как лучше всего передавать и хранить, просмотры и лайки на PHP?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    Посты лайкаются и смотрятся неравномерно: бурлят свежие посты, статично висят старые-забытые.
    Поэтому для кипящего ядра можно держать данные в оперативке, скажем, в Redis – туда писать, оттуда читать. Если ключа поста нет в Redis, то вынимать из БД. Периодически из Redis'а копировать в БД все данные и убирать из Redis данные по постам, которые перестали обновляться.

    Часть нагрузки можно передать на клиент. При загрузке с сервера всем раздавать одинаковые данные о свежих постах (их id без содержания, если длинные). Далее по мере просмотра счётчики лайков/просмотров обновлять на клиенте, синхронизируя лайки с сервером не так часто. И скрипт на клиенте решает дальше, какие посты подгружать и показывать, учитывая локальные просмотры.

    Ещё мысль: nginx умеет Lua. Можно операции с лайками/просмотрами поручить сольному nginx без PHP. Правда, возникает вопрос с авторизацией.
    Ответ написан
    2 комментария
  • Как в ffmpeg из нескольких изображений и их зум склеить видео?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    Всё описанное можно сделать в ffmpeg.

    Анимированный зум делается фильтром zoompan. Он с только целыми координатами работает, поэтому, чтобы не дергался, делать это в повышенном разрешении. Потом даунсэмплить.

    Например, из недавнего проекта, где интерактивно генерилась анимация по шаблону, это из bash-скрипта:
    FILTER="[0]                                                   \
        pad=color=0x99999900:w=${wIn}:h=${hIn}:x=${xPad}:y=${yPad}, \
        scale=20064x3264,                                           \
        zoompan=                                                    \
          s=${wSrc}x${hSrc}                                         \
          :d=${frames}                                              \
          :z='( ${zoomcode} ) / 16.89999'                           \
          :x='2*(${xPad} + ${xPoi}) * (zoom - 1) / zoom'            \
          :y='2*(${yPad} + ${yPoi}) * (zoom - 1) / zoom'            \
          [fg];                                                     \
          [1][fg]overlay=x=247:y=438                                \
      "

    Т.к. зумить меньше, чем влезает во вьюпорт нельзя, сначала картинке добавляется по краям паддинг прозрачный, чтобы можно было уменьшать. Потом размер увеличивается с запасом раз в 5-10, чтобы сделать незаметными целочисленные пиксельные шаги зума и смещения.
    Ответ написан
    Комментировать
  • Как показать ссылку только 5 пользователям за раз?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    Можно сделать JS, который от каждого пользователя будет пинговать ваш сервер раз в N секунд, подтверждая, что пользователь всё ещё на сайте. Прекращение поступления пинга с id отображаемого у того пользователя баннера делает такой баннер вакантным для нового отображения.

    На бэкенде в момент загрузки страницы определяется, какой из вакантных баннеров можно показать.
    Ответ написан
  • Сортировка по N значений?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    может, просто слепить значения в строку и сортировать по строке?
    $tosort = array_map(
      function($el) {
        $el['sortable'] = implode(',', [$el['sort_0'], $el['sort_1'], $el['sort_2'], $el['sort_3']]);
        return $el;
      },
      $products
    );
    
    $result = usort(
      tosort,
      function( $a, $b) {
        return $a.sortable < $b.sortable ? -1 : 1;
      }
    );


    p.s. Как «прекрасен» PHP, посмотри:

    Как раз в этом коде понадобились два метода для работы с массивами, и у одного
    array_map() аргументом сначала идёт callable, потом массив;
    а у другого
    usort() наоборот: сначала массив, потом callable.
    ¯\_(ツ)_/¯
    Ответ написан
  • Как сделать отсчет времени в PHP?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    Вероятно, можно вычислять время получения очередного бонуса, или даже сколько бонусов должно быть у человека в любой момент времени.

    Например, 1 бонус полагается каждые 15 минут с момента первого визита. Надо запомнить в БД id пользователя и время его первого визита. Тогда при любом следующем его обращении к боту можно посчитать, сколько у того бонусов. Текущее время минус время 1-го визита (в сек.) разделить на 900 и взять целую часть.
    Ответ написан
    3 комментария
  • Как написать скрипт на PHP?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    sscanf()

    $str = '921205400655';
    list($year, $month, $day) = sscanf($str, "%2d%2d%2d");
    if ($year > 30) $year = 1900 + $year;
    else $year = 2000 + $year;
    $date = sprintf("%04d.%02d.%02d", $year, $month, $day);
    
    echo $date; // 1992.12.05
    Ответ написан
    6 комментариев
  • Почему возвращается ошибка от VK API?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    method is unavailable with group auth

    «Метод недоступен с токеном сообщества.»

    Посмотрите документацию метода wall.post(), самый первый абзац. Единственный вариант запустить wall.post():
    Этот метод можно вызвать с ключом доступа пользователя, полученным в Standalone-приложении через Implicit Flow, или с использованием окна подтверждения. Требуются права доступа: wall.


    Зарегистрируйте Standalone приложение, получите через него токен админа группы и размещайте записи с параметром from_group=1, чтобы от имени группы.
    Ответ написан
    2 комментария
  • Как организовать обработку больших объемов данных?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    Несколько не связанных идей:
    1. хранить каждую «последовательность» (набор) из 500000 (не важно, сколько) чисел как картинку с 1-битным цветом, 3873*3873px, чтобы покрыть диапазон 0..15e6. Будет 15 млн. таких картинок. Черный пиксель - число, белый - нет числа. Картинки можно накладывать и смотреть, насколько потемнело ) Но в цифре это делать неэффективно, вот если бы аналогом..
    2. хранить последовательность как бинарную строку, где включённые биты означают выбранное число. 15e6 бит примерно 1875e3 байт =~1.9Mb на набор. 1875e3 * 15e6 = 28125e9 байт =~28Тб
    3. хранить как бинарный файл по 3 байта (24 бита) на число. 0–15 млн прекрасно уместятся: 224 = 16 777 216. См. php функции pack() / unpack(). Один набор 500000 * 3 = 1.5Мб, 15млн наборов 22.5Тб
    4. Не хранить всё. Полное покрытие диапазона 0..15 млн. идеально подобранными диапазонами по 500 тыс. потребует всего 30 таких диапазонов.
    5. Гипотеза. Если все выборки действительно случайны, можно брать любые N, они окажутся хуже «настоящего» максимума лишь незначительно.
    6. «Расчеты одной последовательности идут долго порядка 3-х минут» 180 секунд * 15e6 = 27e8 секунд, это почти 86 лет. А вы за несколько дней собирались как-то?

    Ответ написан
    1 комментарий
  • Чем лучше делать информер из api?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    Отрывок данных в вопросе – обычный JSON, стандартный формат, понятный всем. В JavaScript есть метод JSON.parse(), в PHP разбирается функцией json_decode()

    Получайте данные, фильтруйте из них интересующие рейсы.

    «Чем лучше» – стандартный ответ «тем, в чём комфортнее вам».
    Ответ написан
    1 комментарий
  • Как в php разбить 12ти-значное число на определенные блоки?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    Есть специально для этого в PHP функция sscanf() – разбирает строку по формату.

    $str = "111222772019"; // строка из БД
    
    list($unit, $employee, $serial, $year) = sscanf($str, "%3d%3d%2d%4d");
    // 3 цифры, 3 цифры, 2 цифры, 4 цифры
    
    printf("Unit: %d, man: %d, id: %d, year: %d<br/>", $unit, $employee, $serial, $year);
    // Unit: 111, man: 222, id: 77, year: 2019
    Ответ написан
    Комментировать
  • Как избавиться от "такого" кода?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    Бот «сломается» при большом числе запросов. Прежде, чем отдать ожидаемое «ok», он выполняет ещё два веб-запроса: users.get() и messages.send()– это съедает время и память. Будье готовы переключиться на схему с очередью и отдельными рабочими. Приняли запрос, сохранили, отдали "ok". Другой процесс, рабочий, неспеша разбирает задачи из очереди, отправляет ответы. Стали популярнее, добавили рабочих с других серверов.

    Не проверяете user text на минимальную длину. Пришлют одну букву - получат весь FAQ. По мере роста FAQ'а, можете столкнуться с дубликацией: на запрос "hi" найдётся, скажем, ключ с "high load".
    Ответ написан
    1 комментарий
  • Как проверить, принадлежит ли пользователю паблик через его токен?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    Метод groups.getMembers() с фильтром filter=managers доступен только Администраторам сообщества.

    Не делайте получение токена через просьбу скопировать адресную строку. Это плохая практика.
    Ответ написан
    3 комментария
  • Как выполнить код после завершения цикла?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    $arr = ['element_0', 'element_1', 'element_2', 'element_3'];
    $result = []; // объявите его заранее массивом
    $i = 1;
    
    foreach($arr as $item) {
        if ($i++ > 4) break;
        array_push($result, $item); // и пихайте в массив очередное значение
    }
    echo implode(', ', $result);
    Ответ написан
    2 комментария
  • Как правильно отправить и обработать данные на сервере методом json?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    const data = [];
    $('input[name="params[]"]:checked').each((i, el) => data.push(el.value));
    $.post('file.php', data);
    Ответ написан
    Комментировать