Задать вопрос
Ответы пользователя по тегу PHP
  • По порту 8080 php не работает?

    @rPman
    web-сервер Tomcat это для запуска java баэнда
    spoiler
    Точнее jvm, и я даже слышал компилятор php в jvm - JPHP, но это явно не ваш случай
    Так же есть смешная штука, запуск php на клиенте на javascript с помощью webasm, тоже думаю не ваш случай

    Вам нужна поддержка php на сервере, установить к примеру apache или nginx (+cgi) и в нем настроить проксирование, какие команды идут в tomcat а какие выполняются тут же.

    p.s. есть старый проект php-java bridge
    Ответ написан
    Комментировать
  • Как правильно построить сервис, создающий отложенные задачи на основе расписания из другого сервиса?

    @rPman
    Фраза про хранение расписания на сервисе А звучит немного неудобно, ведь сервис В обязан знать оперативно обо всех изменениях в расписании, поэтому - расписание должно синхронизироваться между сервисами в момент его изменения. Для синхронизации нужно продумать варианты с проблемами на сервисе В, а так же продумать первоначальную синхронизацию при первом запуске, когда В только что запущен или, например пересоздан.

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

    Постоянные опросы, это просто некрасиво и да, тут не создаст проблем, ведь делает это только один участник (некрасиво это когда запрашивающих состояние много, тогда нагрузка на сервер взлетает экспоненциально от их количества). Правильно и логично, наладить двустороннюю связь по http rest (сервис В сообщает об изменении в состоянии сервису А вызвав у него соответствующий http запрос) или используя socket (websocket, благо решений готовых тьма, т.е. сервис А держит открытое подключение к В и по нему же отправляет и получает всю необходимую информацию, бонусом максимальная оперативность и информация проблемах на сервисе или со связью, что будет возможно с задержкой при http rest подходе).

    Реализация не требует чего то особенного и тяжелого типа RabbitMQ или Kafka (о чем тут все наверняка сразу подумали/погуглили, всего тысячи отчетов всего 8 воркеров)... это задача того же уровня проверки на профпригодность.

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

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

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

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

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

    Итого на сервисе В должны быть:
    * веб сервер с приложением обслуживающий запросы, синхронизацию расписания, заполнение очереди задач на выполнение, контроль за нодами с воркерами
    * ноды с воркерами со своим веб сервером (независим от процесса, выполняющего задачу)
    * хранилище логов воркеров (независимое от воркеров) + база данных сервиса для расписания и очереди
    Ответ написан
  • Почему при выводе дробных числ появляются лишние цифры?

    @rPman
    Тебе исчерпывающе ответили о причинах, такова природа десятичных чисел, которые хранятся в битах.

    Если тебе нужно работать с числами в той форме что сохранена - либо используй строки.
    'capacity' => "0.2",
    либо используй целочисленный формат с фиксированной степенью (где то ты должен определить предел точности, сколько знаков после запятой, которые тебя интересуют, и делай на это соответствующую скидку при операциях умножения и деления).
    'capacity' => 2000,
    В данном случае речь о 4 значимых цифрах или 10^4
    при умножении, результат нужно делить на 10^4 и отбрасывать все что после запятой через intVal или round (а перед делением наоборот первый операнд умножать)

    Внимание, на php int, при превышении PHP_INT_MAX будет автоматически сконвертировано в float, поэтому даже с этим методом придется хранить числа в строках и использовать bc math или рекомендуют gmp как самую быструю реализацию
    Ответ написан
    Комментировать
  • Как сделать чтобы проект удалил папку с самим собой и на её место скопировал другую папку?

    @rPman
    Зачем вы вызываете rm из кода? когда в php есть свои методы?

    Удалить файл, из которого php запущен нет никаких проблем, в т.ч. в текущем каталоге вместе с ним самим.
    test.php
    <?php
    unlink('test.php');
    rmdir(getcwd());
    ?>

    Ищите не закрытые файлы в своем коде.

    p.s. вы рекурсивно удалять файлы не можете код написать?
    // внимание, код нужно дорабатывать до универсальности
    function rrmdir($dir) {
        foreach(glob($dir.'/*') as $f) {
            is_dir($f) ? rrmdir($f) : unlink($f);
        }
        rmdir($dir);
    }
    Ответ написан
  • Как посчитать расстояние между точками маршрута для автомобильного маршрута используя API Яндекс карт на php?

    @rPman
    Очевидно для того что бы бесплатно это делать, вам нужно где то добыть данные, и уже работать с ними самостоятельно.

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

    Я думаю лучше заплатить
    Ответ написан
  • Как анализировать JS и PHP ошибки на своем сайте?

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

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

    Самое простое - это текстовый лог в формате jsonl, это сериализованный в json по строчно на каждое событие (а атрибуты события - атрибуты объекта json). В некоторых случая json не поддерживается, например какой-нибудь fail2ban его не умеет, но умеет с помощью регулярных выражений извлекать данные из текста, тогда данные можно собирать и разделять в виде, удобным для последующей обработке регулярными выражениями.

    Как только объемы событий выходят на гигабайты, текстовые логи становятся неудобными (а может и раньше) и данные лучше складывать в какую-либо базу данных... кому то нравится nosql (неудобна для анализа), кто то сразу в sql базы складывает (они удобны тем что могут хорошо масштабироваться на несколько устройств или машин). Те, кому нужно совсем много данных, могу задуматься о предварительном анализе данных через промежуточный сервис (т.е. для того что бы оставить сообщение, приложение по сети отправляет лог-серверу запрос), который делает минимальный анализ, выделяет что сохранить и как, проводит базовую аналитику и сохраняет в базы данных (лог база данных может быть сложнее чем пара табличек).
    Ответ написан
    Комментировать
  • MySQL: как реализаовать поиска по нескольким вхождениям?

    @rPman
    Есть еще instr это однозначно быстрее like

    Ну и fulltext индексы конечно, искать с некоторым языком запросов

    p.s. если искать в строках базы приходится ограниченное количество слов (т.е. грубо говоря список слов определяется проектом, а не свободным вводом от пользователя) то можно заранее (при добавлении строк) построить свой собственный индекс, размещая факт наличия подстроки в строке boolean полем true/false или создав соответствующие таблицы (если наличие слов сильно разряжено - это эффективнее), где наличие записи - факт наличия слова.

    Например у тебя искать нужно три слова: man, woman, child, соответственно создаешь три boolean колонки has_man, has_woman, has_child в той же таблице где анализируемая строка и заполняешь их триггером.

    Или если тот же пример но через таблицы, то в искомой таблице у тебя должно быть primary key поле, и ты создаешь на каждое слово по таблице has_man, has_woman, has_child, с единственным полем id, в эти таблицы помещаешь запись с id из искомой таблицы, если в ее строке есть это слово.. это так же можно делать триггером.
    Ответ написан
    Комментировать
  • Как узнать длину видео в PHP?

    @rPman
    Установить пакет ffmpeg и использовать утилиту ffprobe
    Вот информация о видео в json:
    ffprobe -v quiet -print_format json -show_format example.avi

    или вот конкретно одно поле с длительностью в секундах
    ffprobe -v quiet -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 example.avi


    соответственно на php выполни эту команду, например:
    $duration=`ffprobe -v quiet -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "$filename"`';

    и получишь в $duration секунды в float или пусто при ошибке.
    Ответ написан
    1 комментарий
  • Как проверять доступ, если $_COOKIE и $_SESSION недоступны?

    @rPman
    Храни все данные в url (это $_GET параметры), вместо обновления делай переход/

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

    @rPman
    Пользуйтесь средами разработки, поддерживающими php и xdebug (или аналоги).

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

    А так есть еще такие Atom, Netbeans IDE, Komodo IDE, Aptania Studio,..
    Ответ написан
  • Как выполнить поиск данных, если в базе данных указан шаблон?

    @rPman
    Вам нужно сначала определить, к какому шаблону соответствует введенный пользователем запрос, для этого этот список шаблонов должен быть определен в программе, например регулярными выражениями, для каждого по очереди нужно будет делать проверку запроса пользователя, соответственно порядок этих проверок нужно будет тщательно продумать, например если один шаблон включается в другой, то он должен быть выше по списку (например a???b и a?c?b - второй шаблон тут должен проверяться первым).

    Каждому шаблону нужно будет дать соответствие строку sql запроса в базе данных (либо подстрокой выражения)

    p.s. так ли нужно пользователям такое усложнение поиска?
    Ответ написан
    Комментировать
  • Как в html выполнять замену текстового содержимого в зависимости от родительского тега?

    @rPman
    Когда речь идет о строгом следовании html (и не только, там и javascript может быть), то простым поиском или регулярными выражениями не получится.

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

    @rPman
    Тут только остается заполнять test.php выводом отладочной информацией, добавляя после каждого вывода fflush или аналог (как вариант, вывод логов в другое место, вплоть до БД).

    Без логирования есть еще вариант отладка в какой-нибудь среде разработки, но... вопрос а на домашнем компьютере все работает?
    Ответ написан
  • Как сохранять клики и их время в кликере?

    @rPman
    вместо условных 100 кликов людям засчитывало ~40
    судя по sql у тебя количество сохраняемых кликов считается как сначала запросом получить текущее значение, затем сохранить его увеличенным... что естественно неправильно обсчитывается, если одновременно на бакэнд идут несколько запросов, и завершаются в разном порядке (т.е. первый, получил значение 1, затем его обогнал второй, получил то же значение 1, оба отправляют +1 значение, т.е. 2, вместо ожидаемого 3.

    Правильно: одним обновлением в базе нужно - проверять допустимость клика (проверить время последнего клика), обновить время последнего клика и увеличить количество кликов на 1... после чего бакэнд проверяет, сколько записей было обновлено, если 0 - значить выход за лимиты, если 1 - все ок.
    update set clicks=clicks+1, last_click_time=now() where last_click_time+:ALLOWED_CLICK_INTERVAL<now() and id=:current_id


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

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

    @rPman
    Вам зачем нужна прослойка? Что бы заменить некрасивый синтаксис curl_xxx на свой некрасивый?

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

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

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

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

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

    @rPman
    а почему бы не объединить эти обе библиотеки в одну?
    зачем мельчить если они друг от друга зависят и так?
    Ответ написан
    Комментировать
  • Как правильно использовать python скрипт через PHP backend?

    @rPman
    В общем случае технологии называются Interprocess communication.

    Изначально предлагались (php/python) механизмы очереди сообщений, shared memory и semaphores, как минимум на их основе делают высокоуровневые библиотеки по работе с сообщениями (и используют именно их, а не низкоуровневые, но знать про них обязан каждый, чтобы понимать недостатки)

    Второе и самое логичное, использовать socket-ы, как unix socket или pipes, так и tcp. Многие не заморачиваются, а поднимают полноценный асинхронный http сервер и организуют общение между приложениями по http или лучше websocket протоколу, так как это позволяет распределить приложения уже не в пределах одного сервера, а в сети, что дает очень высокую гибкость, но ценой значительных накладных расходов на сериализацию.

    Правда если используются разные языки программирования, в которых разные форматы для структур данных, так же придется сериализовать структуры, т.е. память копировать и кодировать/декодировать.
    Ответ написан
    2 комментария