Премини към съдържанието
Форумът в приложение

По-лесно сърфиране. Научи повече.

Kaldata.com - Форуми

Приложение на форума на цял екран с push известия, значки и други.

За да инсталирате това приложение на iOS и iPadOS
  1. Докоснете Иконата за споделяне в Safari
  2. Превъртете менюто и докоснете Добавяне към началния екран.
  3. Докоснете Добавяне в горния десен ъгъл.
За да инсталирате това приложение на Android
  1. Докоснете менюто с 3 точки (⋮) в горния десен ъгъл на браузъра.
  2. Докоснете Добавяне към началния екран или Инсталиране на приложение.
  3. Потвърдете, като докоснете Инсталиране.

Добре дошли!

Добре дошли в нашите форуми, пълни с полезна информация. Имате проблем с компютъра или телефона си? Публикувайте нова тема и ще намерите решение на всичките си проблеми. Общувайте свободно и открийте безброй нови приятели.

Моля, регистрирайте се за да публикувате тема и да получите пълен достъп до всички функции.

 

php process

Featured Replies

Здравейте,

Вчера ми се случи следната ситуация. PHP проект трябва да извика шел команда. След края на тази команда се вика отново php скрипт с параметри генерирани от първия php скрипт. Шел командата може да продължи работа часове... опитах се да вкарам нещата с pnctl_waitpid pnctl_fork работят за живота на скрипта. Тествах и други неща но без особен успех. Работя със Symfony, там много културна библиотека за процеси има. Синхронно работи "prg1 ; php scr1", асинхронно обаче не вика scr1. В крайна сметка си реших проблема със следната структура

shell_exec("nohup sh -c 'prog1 --pram=xyx; php scr1 --param1=xxx' >/dev/null 2>&1 &")

Въпросът ми е дали има по елегантно решение?

Здравей,

Ами добре си се справил.

Какво разбираш под "по-елегантно"?

Всеки човек мисли различно. Най-ефективната работа за сътветния човек протича по различен начин.

Аз лично бих си записал изходните параметри в база данни или във файл и първия скрипт в края си стартирва втория скрипт, който търси данните в базата или във файла.(последния файл или последните данни по id от базата)

Така имаш и за по-късна диагностика (debuging) междинните резултати, които се подават като параметри на втория скрипт.

  • Автор

То въпроса е точно за базата. Записвам старт дата, върша работа с външна програма записвам крайна дата по подадено id на втория скрипт (от първи скрипт). Сега може да не са само дати, а и друга работа. Тоест правя това, което и ти :wink12: предлагаш.

Сега ми стана малко по-ясен твоя проблем. Викаш външна програма и нея не можеш да я промениш, че да извиква твоя скрипт в края си.

Ами можеш да пуснеш твоята програмка на определен интервал да се стартирва и да проверява дали другата програма е записала данните в базата. (примерно всеки 5 мин.)

Може да проверяваш дори дали даден процес все още работи(ps -q <pid>) и ако не работи да действаш, ако примерно външната програма блокира, е хубаво да имаш timeout (10 часа) и да репортва грешка.

  • Автор

Да това е решение, но мисля е доста по пръснато... зависи софтуера от задаване на крон. Цялата работа е за парсване на сайтове, инструмент (не правя скрапер на информация :P). За целта свалям сайта с външна програма... видя ми се тъпо да обхождам, като идиот с php. След края на процеса записвам в базата кога е свършило и започвам парсване по определени критерии. Процесите ще са на кронове... но колкото по-малко по добре :) че да не стане накрая повече логика в кронтаба отколкото в проекта. Също така 5 мин интервал са много ако имам 10,100,n сайта на опашката. Ще загубя процесорно време.

За тая работа се ползват шел скриптове. Да не говорим, че ако се ползва unix shell има и pipeline с който процесите могат да си предават параметри.  

  • Автор
преди 2 часа, mr mcwolf написа:

За тая работа се ползват шел скриптове. Да не говорим, че ако се ползва unix shell има и pipeline с който процесите могат да си предават параметри.  

Може ли малко информация как бихте го направили с шел скрипт?

Ами то си зависи какво точно се опитваш да постигнеш и какви са параметрите които искаш да предаваш.

Ако вземем за основа това:

shell_exec("nohup sh -c 'prog1 --pram=xyx; php scr1 --param1=xxx' >/dev/null 2>&1 &");

 

и ако XYX и XXX са константи правиш нещо такова

#!/bin/sh
PHP = "/path/to/php_cli";

PROG1 = "/path/to/prog1";
PROG2 = "/path/to/prog2";

$PROG1 --pram = $1; 
$PHP $PROG2 --param1 = $2;

И самото извикване

shell_exec("nohup myscript.sh xyx xxx &");

 

Ако двата процеса трябва да си предават данни  (казваш, че втората програма ползва нещо генерирано от първата) можеш да ползваш pipeline за да пренасочиш stdout на първия към stdin на втория

$PROG1 --pram = $1 | $PHP $PROG2 --param1 = $2;

 

Отделно, можеш да ползваш логически И/ИЛИ за да определяш при какъв изходен код да се изпълнява втория процес.

 

Като цяло, в php скриптът не бива да завираш подобна логика. Неговата функция трябва да е само и единствено да стартира един процес (и евентуално да му подаде параметри за инициализиране). Така по всяко време ще можеш да подменяш поведението на този "background task" без да търсиш местата на които той се стартира.

Имай в предвид, че в подобни схеми винаги трябва да работиш с абсолютни пътища, защото не се знае дали променливата PATH е сетната коректно за текущия потребител (обикновено не е).

Редактирано от mr mcwolf (преглед на промените)

  • Автор

Този начин ми допада повече от моя. За пътищата са ми абсолютни, дори бинаритата ги взимам с which. Затова пуснах и темата... че не ми допадаше как го направих. Благодаря.

Според мен дори ще ти е по-лесно през shell скрипта да си правиш врътките в самата база. Реално можеш от скрипта да присвоиш output-a от процеса на променлива с VARIABLE=$(program params) и след това директно можеш да си извикаш mysql -e "INSERT INTO alabala (`end_date`) VALUES (NOW()) where `id_field` = $VARIABLE" databasename - или нещо от сорта.

#!/bin/bash

INPUT_PARAM=$1

PROG_OUTPUT=$(external_program --param $INPUT_PARAM)

mysql -usomeuser -psomepass -e "INSERT INTO ....... WHERE `some_field`=$PROG_OUTPUT" somedatabase

Като разбира се, ако не ползваш mysql - си ползваш CLI tool-a на предпочитаната база.
По този начин не правиш никакви врътни през PHP, а директно си викаш скрипта и го оставяш той да си върши работата.

 

п.с. А и ако в скрипта ти викаш subshell променливите ще трябва да ги export-неш за да са видими в scope на дъщерния шел

Редактирано от borovaka (преглед на промените)

  • Автор
преди 20 часа, borovaka написа:

Според мен дори ще ти е по-лесно през shell скрипта да си правиш врътките в самата база. Реално можеш от скрипта да присвоиш output-a от процеса на променлива с VARIABLE=$(program params) и след това директно можеш да си извикаш mysql -e "INSERT INTO alabala (`end_date`) VALUES (NOW()) where `id_field` = $VARIABLE" databasename - или нещо от сорта.


#!/bin/bash

INPUT_PARAM=$1

PROG_OUTPUT=$(external_program --param $INPUT_PARAM)

mysql -usomeuser -psomepass -e "INSERT INTO ....... WHERE `some_field`=$PROG_OUTPUT" somedatabase

Като разбира се, ако не ползваш mysql - си ползваш CLI tool-a на предпочитаната база.
По този начин не правиш никакви врътни през PHP, а директно си викаш скрипта и го оставяш той да си върши работата.

 

п.с. А и ако в скрипта ти викаш subshell променливите ще трябва да ги export-неш за да са видими в scope на дъщерния шел

Благодаря за предложението, но нямам прости INSERT STATEMENT има доста логика и предпочитам тя да си остане, като логика на основния език. Преди съм мешал и съм си патил от това... дори още си сърбам попарата с определени проекти.

Архивирана тема

Темата е твърде стара и е архивирана. Не можете да добавяте нови отговори в нея, но винаги можете да публикувате нова тема, в която да продължи дискусията. Регистрирайте се или влезте във вашия профил за да публикувате нова тема.

Разглеждащи това в момента 0

  • Няма регистрирани потребители разглеждащи тази страница.

Дарение

  • Подкрепи съществуването на форума - направи дарение
    25%
    Дарени 252.69 EUR от нужните 1,000.00 EUR

Бюлетин

Получавайте известие, когато има важна промяна или новина свързана с форума.

Профил

Навигация

Търсене

Търсене

Конфигуриране на push известия в браузъра

Chrome (Android)
  1. Докоснете иконата на катинар до адресната лента.
  2. Докоснете Разрешения → Известия.
  3. Променете предпочитанията си.
Chrome (Desktop)
  1. Кликнете върху иконата на катинар в адресната лента.
  2. Изберете Настройки на сайта.
  3. Намерете Известия и коригирайте предпочитанията си.