Ответы пользователя по тегу PHP
  • Есть идеи как диспатчить события в WS сервере ratchet?

    @rPman
    Подключайся к своему же веб-серверу, и отсылай ему системное сообщение (про авторизацию не забудь).

    Вебсокет ратчет сервер это 1-поточное приложение, соответственно получив сообщение будет исполнен метод в том же пространстве где можно хранить список клиентов. Точно помню у ратчет был массив со списком всех подключенных клиентов, не уверен, доступен ли он публично напрямую, но в худшем случае можно собирать собственный список, доступный глобально.
    Ответ написан
  • Как объединить одинаковые поля в php?

    @rPman
    В цикле собираешь не строку а массив, складывая значения в ключи $result[$value]=true; это автоматически уберет дубликаты $value

    После цикла собираешь строку с помощью implode взяв ключи как массив array_keys, при этом порядок будет сохранен.
    Ответ написан
    Комментировать
  • Как вызывать метод без параметров, а сам метод сделать с параметрами?

    @rPman
    после 5.6 версии php можно использовать variadic functions
    function test(...$params){var_dump($params);}
    test(1,2,3);

    работает для всех мест использования - функций, методов, замыканий.
    Ответ написан
    Комментировать
  • Как правильно перебрать выполнить for in в php?

    @rPman
    foreach(file('filename') as $str)
    {
      ...
       ibase_query($str);
      ...
    }

    если размер файла сравним с доступной памятью то лучше читать построчно
    $r=fopen('filename','r');
    while(!feof($r))
    {
      $str=trim(fgets($r));
      if(empty($str)) continue;
      ...
      ibase_query($str);
      ...
    }
    fclose($r);
    Ответ написан
    3 комментария
  • Как уменьшить нагрузку кода?

    @rPman
    Код ужасен, не разбираюсь в нем да и не охота.
    Вы фактически загружаете все данные в php память, но не одним запросом а огромным количеством (на каждого человека по несколько да?) что абсурдно.

    Правильно либо загрузить все одним запросом в память и вертеть данными как вам хочется, либо что лучше - сделать все необходимые операции исключительно sql кодом.

    Ну и для начала, тригером, как только появляется у пользователя реферер - обновляйте поле referers_count в таблице пользователя, тогда вы можете быстро и эффективно делать запрос по пользователям с нужным количеством рефереров, так же вместо того чтобы делать по крону вычисления, считайте что там вам нужно считать по реферам в момент запроса данных, сохраняйте в кеш таблице на дату, при этом формула должна как то учитывать что предыдущий подсчет учел данные (например транзакции имеют пометку времени, значит запрос должен брать только те транзакции, время которых новее предыдущего запроса)...
    Ответ написан
    7 комментариев
  • Обновление Excel-документа?

    @rPman
    Необходимо в документ добавить макросы, которые будут запрашивать необходимую информацию и обновлять документ.
    Ответ написан
    Комментировать
  • PHP - вывод картинок из папки. Как вывести только JPG?

    @rPman
    Если надо для каждого файла какие то условия проверять и glob с масками * и ? не подходит то используйте pathinfo, разбирает путь в виде строки и возвращает полезную информацию:
    print_r(pathinfo('/path/file.ext.jpg'));
    Array
    (
        [dirname] => /path
        [basename] => file.ext.jpg
        [extension] => jpg
        [filename] => file.ext
    )
    Ответ написан
    Комментировать
  • Как вместо текста, сделать редирект в php? const ERROR = редирект?

    @rPman
    Если я верно понял проблему - никак.

    Но, можно воспользоваться хаком, не определять константу ERROR и при каждой попытке доступа к ней будет возникать ошибка 'Use of undefined constant', которую можно отловить колбеком set_error_handler
    set_error_handler(function(int $errno , string $errstr , string $errfile, int $errline, array $errcontext)
    {
    echo 'ERROR: $errno='.$errno.' $errstr ='.json_encode($errstr ).' $errfile='.json_encode($errfile).' $errline='.$errline.PHP_EOL; // .' $errcontext='.var_export($errcontext)
    });
    
    test;
    test;

    ERROR: $errno=2 $errstr ="Use of undefined constant test - assumed 'test' (this will throw an Error in a future version of PHP)" $errfile="C:\\W\\test\\php\\a.php" $errline=8
    ERROR: $errno=2 $errstr ="Use of undefined constant test - assumed 'test' (this will throw an Error in a future version of PHP)" $errfile="C:\\W\\test\\php\\a.php" $errline=9


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

    @rPman
    С точки зрения нейминга пакетов в OS, php бывает php-cli и просто php. Первый - для запуска из коммандной строки или службы, т.е. просто как скриптовый язык (кстати жутко удобный, имхо удобнее bash, и самый быстрый из существующих в принципе, рядом с ним идет node js но он не такой удобный), второй - для работы web бакэнда.

    По факту это один и тот же бинарник но когда запускаешь приложение из командной строки, настройки php.ini берутся из другого каталога (смотреть /etc/php/...).

    Можно внутри php файла не указывать <?php но в начале указать по стандарту #!/usr/bin/php и тогда скрипт будет запускаться как любое другое приложение (нужен флаг x на файле) либо использовать <?php и запускать
    php файл.php
    Второй вариант мне нравится больше, потому что редакторы ide для php чаще ожидают второй вариант а при первом не включают подсветку синтаксиса.

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

    Т.е. вам нужны механизмы запуска вашего скрипта в виде службы (или хотя бы пока просто скриптом вручную, я видел примеры когда запускали автоматически внутри screen чтобы можно было мониторить активность простым подключением по ssh), плюс механизмы организации задач в виде списков (самое простое в базе данных) и инструменты нотификации об изменении статуса каждой (окончание или ошибка), например нужно же клиенту сообщить о том что работа завершена (при правильной реализации для этого пользуются websocket)
    Ответ написан
    Комментировать
  • Как инкрементировать число?

    @rPman
    В терминах базы данных это называется sequence, в каких то это специальный объект с этим именем, значение которого можно запросить и получить следующее, в каких то используется стратегия autoincrement, когда это значение вычисляется автоматически при добавлении в таблицу (например primary key) в каких то, а значит следующее значение можно получить только добавив запись, ну а в совсем уж слабых, пользователи заводят специальную таблицу, где одна запись - сиквенс, значение которого можно прочитать и увеличить на нужное число простым update (и использовать блокировки).

    Самое главное, в базах данных за многопользовательский доступ (а значит конфликты, что делать если два пользователя одновременно затребуют следующее значение), отвечает механизм транзакций.

    При попытке реализовать подобное на базе файлов возникнет необходимость реализовывать контроль за подобными коллизиями уже самому.
    обожаю велосипеды, не надо так делать
    Пишите в файл, добавляя символы < и > (смысл у каждого - транзакция начата и завершена соответственно), текущая позиция (размер файла) будет значением сиквенса (т.е. сначала вы определяете размер файла, и читаете его последний байт, если он < то ждете случайное время в миллисекундах и повторяете процесс, если он >, значит текущая позиция будет номером сиквенса, добавляете в файл символ <, отрабатываете генерацию формы, пишете >, это самый опасный момент, если нет сервера, смерть процесса до этого момента 'заблокирует' работу, так всегда бывает когда нет сервера, чтобы возобновить - достаточно добавить >), если нужен счетчик то считаете количество < во всем файле до текущей позиции.
    Если счетчик должен считать долго, можно в начало файла записывать определенное число (выравнивая его по фиксированному количеству символов, например sprintf('%08u',$seq);) отдельным процессом на сервере запустить периодическое усечение этого файла, процесс так же ждет момента когда последний символ будет >, переименовывает файл, считает в нем количество, и обновляет запись в первоначальном файле, создав его если он не создался и после этого удаляет предыдущий переименованный.
    В этом случае не важно, в какой последовательности будет происходить работа с файлом и сколько в него будут писать приложений, пока размер файла меньше размера сектора (4кб минимум чаще больше) то операции с ним атомарны (под вопросом сетевые FS типа nfs/samba но на них и так проблемы) а значит сам файл станет механизмом контроля и синхронизации.

    p.s. Внимательно подумайте, вам нужен счетчик или нужно уникальное значение? Можно чтобы каждое следующее значение было ровно на единицы больше? может быть оно меньше предыдущего?

    Существуют алгоритмы, позволяющие получить уникальное число без какого либо контроля и синхронизации (например у вас кластер из кучи машин между которыми пользователи распределяются по какому то своему алгоритму, если спрашивать какой то единый центр за контролем над числами, то это станет бутылочным горлышком всего кластера).

    Самый простой алгоритм - который по правде говоря не дает гарантий, но значительно понижает вероятность коллизий - взять текущее время, в милли-/микро-/пико-секундах, при наличии кучи машин - добавить номер этой машины, можно добавить еще случайное число (чем больше его разрядность тем ниже вероятность коллизий)
    sprintf("%u",microtime(true)*1000000);
    еще есть метод uniqid, он делает примерно то же самое но возвращает hex строку.

    p.s. время на машинах должно быть синхронизировано с точным, чтобы не было такого что в какой то момент оно откатится назад на достаточное значение чтобы метод дал сбой
    Ответ написан
    5 комментариев
  • Как ограничить доступ к файлам на стороне сервера?

    @rPman
    все зависит от того, как
    любой кто использует мой компьютер может открыть их

    защитить файлы можно правами доступа ОС и не пускать людей за компьютер со своим доступом

    так же можно запускать сервер под правами пользователя, отличными от того под которым используешь комп (создать нового), соответственно выдав права на папку с сайтом на этого пользователя, никто кроме знающего пароль к нему не сможет ихпрочитать
    Ответ написан
    Комментировать
  • Почему код возвращает лишнее?

    @rPman
    Хотя бы для отладки вывел что возвращает тебе ftp_mlsd, 100% все проблемы бы решились сразу.

    Пальцем в небо - в linux каждый каталог содержит два элемента '.' и '..', соответственно текущий и предыдущий каталог, вдруг ftp их возвращает а ты их в файлы записываешь? но тип по уму у них должен быть dir, плюс зациклилось бы все.
    Ответ написан
    Комментировать
  • Нужно ли обрабатывать фатальные ошибки в PHP?

    @rPman
    Если я верно понял вопрос, речь идёт об организации контроля над фатальными ошибками и следующие действия.

    Фатальные ошибки возникают, когда допущена ошибка в коде, например синтаксическая, или необработанные исключения, или неожиданная комбинация данных... в общем произошло то, чего не ждёшь.

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

    Наиболее легко получает народ ошибки такого рода, когда заканчивается место на диске или ram.

    Самое логичное, служба, отвечающая за принятие решения о повторном перезапуске, должна попытаться проверить возможные причины, считать попытки и правильно реагировать. Например у меня одни скрипт при перезапуске по ошибке отправлял мне sms, и какраз место на диске кончилось и он не смог сохранить факт отправки, слал их сотнями.

    Логично предположить, что можно наоборот запретить перезапуск при фатальных ошибках, но тогда нужно значительно увеличивают скорость реагирования на них поддержке, т.е. круглосуточно.

    Очень сложный вопрос м в конце концов упирается в объем ресурсов, которые вы готовы в это вложить.
    Ответ написан
  • Как можно сделать откат и повтор OOP?

    @rPman
    2 основных подхода к реализации отката:
    1. вместо вычислений, на каждом шаге просто добавляете или удаляете описание операций (иногда подойдут обычные замыкания) в специальный массив, реальные вычисления проводите в момент когда запрашивается результат
    2. каждый шаг вычислений сохраняет предыдущее значение в специальном массиве, соответственно откат - это получение этого значения и удаление последнего элемента в масссиве (если не нужен redo)

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

    Так же возможно сочетание обоих подходов, для оптимизации ресурсов.
    Ответ написан
    Комментировать
  • Как правильно отправлять header, get и post запросы при парсинге, чтобы не банили?

    @rPman
    В общем случае нужно повторять те же запросы и ту же их последовательность, в идеале с правильными таймингами, что делает браузер. Если хотите знать что да как, открываете в браузере хром или фаерфокс нужную страницу, жмете f12, закладка network, выбираете по очереди каждый запрос, правая кнопка, копировать, curl с заголовками и изучаете.

    Понятно что конкретный сервис может не заморачиваться с таким скрупулезным анализом, но что именно будет делать - вопрос исследования.

    Поэтому правильный способ, не пытаться объять необъятное и пользоваться готовым браузером, управляя им со стороны или плагином/инжектом управляющего скрипта прямо на страницу.
    Ответ написан
  • Как поженить php8 и apache24?

    @rPman
    Сообщение об ошибке 'не найден указанный модуль'

    Настраивать вручную apache и php под windows это какая то форма мазохизма да?
    Выбирайте на выбор:

    * cygwin <-- рекомендуется, очень качественно поддерживают весь стек утилит linux, удобный gui
    * msys
    * wsl <-- это вообще linux позволяет запустить почти полноценный да еще и без виртуализации (как wine в linux для windows)
    * поставьте же наконец себе linux в виртуалке, это пара минут шевеления мышкой без каких либо знаний

    А еще можно не ставить apache, особенно если вы туда не лезете и вам нужно просто отлаживать свои скрипты локально, запускайте встроенный в php веб сервер:
    php -S 0.0.0.0:8080
    Ответ написан
    4 комментария
  • Как в классе использовать global?

    @rPman
    global может использоваться только внутри методов или функций, т.е.
    $a = 'test';
    
    class Cls {
    
      public function __construct($a) {
        global $a;
        $this->a = $a;
      }
      public function printer(){
        global $a;
        echo $this->a;
      }
    }
    
    $get = new Cls($a);
    $get->printer();


    Использование global - очень неверная стратегия, и ее нужно избегать всеми силами....

    В крайнем случае используй static (если нужно чтобы переменная была единая для всех экземпляров класса), причем его можно использовать как в пределах описания переменных и методов класса так и внутри функции при определении переменной

    Если прямо надо сильно глобальную переменную и лень писать global в каждом методе, пользуйся функциями, определенных глобально, их будет видно везде. Пример реализации сиквенса:
    function next_seq() {
      static id=0;
      return id++;
    }

    или даже возвращающего целые объекты или массивы
    function yoyo() {
      static $o=false;
      if($o===false) $o=new MyCoolObject();
      return $o;
    }
    использовать:
    yoyo()->myCoolMethod();


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

    @rPman
    для этого из $code удаляю по 1 символу
    так заведи еще одну переменную для этого и скопируй туда $code
    Ответ написан
  • Как работает генератор?

    @rPman
    Ответ написан
    Комментировать
  • Как передать несколько параметров одной строкой?

    @rPman
    не надо в value ничего умножать

    несколько input на странице с name="sub_section[]" автоматически будут проанализированы веб сервером и превращены в массив из их value

    p.s. объясните, почему вы в 2021 году используете веб стандарт, который на клиенте работает без javascript? я конечно могу придумать пару применений такому но что то мне подсказывает что это не ваш случай.

    пользуйтесь XMLHttpRequest, он давно уже стандартизирован во всех браузерах, сериализуйте красиво в javascript свои данные и не заморачивайтесь
    Ответ написан