Как запустить PHP-код асинхронный
Как я могу запустить PHP-код асинхронно, не ожидая? У меня длинный пробег (почти бесконечный), который должен запускаться во время запуска сервера и должен обрабатываться асинхронно, не ожидая.
Возможные варианты, которые я предполагаю:
- Запуск кода на веб-странице и его открытие для выполнения этой задачи
- Вызов script из некоторой утилиты командной строки (я не уверен, как), которая будет обрабатываться в фоновом режиме.
Я запускаю скрипты PHP на своем локальном сервере, которые будут отправлять электронные письма, когда происходят определенные события, например. напоминания дня рождения.
Пожалуйста, предложите, как я могу достичь этого, не открывая страницу в браузере.
Ответы
Ответ 1
Если вы хотите запустить его из браузера (возможно, вы не знакомы с командной строкой), вы все равно можете это сделать. Я исследовал множество решений для этого несколько месяцев назад, и самым надежным и простым в реализации было следующее из Как разместить асинхронный HTTP-запрос в PHP
<?php
$params['my_param'] = $a_value;
post_async('http:://localhost/batch/myjob.php', $params);
/*
* Executes a PHP page asynchronously so the current page does not have to wait for it to finish running.
*
*/
function post_async($url, array $params)
{
foreach ($params as $key => &$val) {
if (is_array($val)) $val = implode(',', $val);
$post_params[] = $key.'='.urlencode($val);
}
$post_string = implode('&', $post_params);
$parts=parse_url($url);
$fp = fsockopen($parts['host'],
isset($parts['port'])?$parts['port']:80,
$errno, $errstr, 30);
$out = "POST ".$parts['path']." HTTP/1.1\r\n";
$out.= "Host: ".$parts['host']."\r\n";
$out.= "Content-Type: application/x-www-form-urlencoded\r\n";
$out.= "Content-Length: ".strlen($post_string)."\r\n";
$out.= "Connection: Close\r\n\r\n";
if (isset($post_string)) $out.= $post_string;
fwrite($fp, $out);
fclose($fp);
}
Скажем, файл, приведенный выше, находится в корневом каталоге вашего веб-сайта (/var/www
) и называется runjobs.php. Посещая http://localhost/runjobs.php
, ваш файл myjob.php
начнет работать. Вероятно, вы захотите добавить некоторый вывод в браузер, чтобы вы знали, что он был отправлен успешно, и не помешает добавить некоторую безопасность, если ваш веб-сервер открыт для остального мира. Одна хорошая вещь об этом решении, если вы добавляете некоторую безопасность, заключается в том, что вы можете запускать работу везде, где вы можете найти браузер.
Ответ 2
Определенно звучит как задание для задачи cron. Вы можете настроить php script для выполнения своей задачи один раз и запустить cron так часто, как вам нравится. Вот хорошая запись о том, как запустить php script как задачу cron; это очень легко сделать.
Ответ 3
На самом деле PHP не предназначен. Вы должны использовать библиотеку потоков PECL, чтобы открутить потоки, которые запускаются асинхронно, и я не рекомендую это. Новая жара в асинхронном отделе node.js - я рекомендую вам изучить это и посмотреть, можете ли вы его использовать. Он предназначен для легкого веса, асинхронных сетевых операций и может использоваться для запуска скриптов PHP.
Ответ 4
Как я могу запустить PHP-код асинхронно без ожидания. У меня длинный пробег (почти инфинитный), который должен запускаться пока сервер запускается и должен обрабатывать асинхронно, не дожидаясь.
Предполагая типичную систему LAMP, вы можете запустить демон PHP из командной строки с помощью
root# php yourscript.php &
где yourscript.php содержит что-то похожее на
<?php
$log = fopen('/var/log/yourscript.log', 'a+');
// ### check if we are running already omitted
while(true) {
// do interesting stuff and log it.
// don't be a CPU hog
sleep(1);
}
?>
Украшательства:
Чтобы сделать ваш script напрямую исполняемым: chmod + x yourscript.php
и добавьте #!/usr/bin/php в начало вашего документа
Чтобы начать с apache, вы должны добавить эту команду в ваш apache startup script (обычно apachectl) и не забудьте добавить код, чтобы убить его, когда apache останавливается.
Проверка, если вы уже работаете, включает файл с вашим PID в /var/locks/
и что-то вроде системы ('/bin/ps'. $thePID); Это также упрощает запись команды kill.
Ответ 5
спасибо Todd Chaffee, но он не работает для меня, поэтому я отредактировал ваш код. Надеюсь, вы не будете возражать, и может быть, это также поможет другим с этой техникой.
cornjobpage.php//mainpage
<?php
//if you want to call page for multiples time w.r.t array
//then uncomment loop start & end)
?>
<?php
//foreach ($inputkeywordsArr as $singleKeyword) {
$url="http://localhost/projectname/testpage.php";
$params['Keywordname'] = "testValue";//$singleKeyword
post_async($url, $params);
//}//foreach ($inputkeywordsArr end
?>
<?php
/*
* Executes a PHP page asynchronously so the current page does not have to wait for it to finish running.
*
*/
function post_async($url, array $params)
{
foreach ($params as $key => &$val) {
if (is_array($val)) $val = implode(',', $val);
$post_params[] = $key.'='.urlencode($val);
}
$post_string = implode('&', $post_params);
$parts=parse_url($url);
$fp = fsockopen($parts['host'],
isset($parts['port'])?$parts['port']:80,
$errno, $errstr, 30);
$out = "GET ".$parts['path']."?$post_string"." HTTP/1.1\r\n";//you can use POST instead of GET if you like
$out.= "Host: ".$parts['host']."\r\n";
$out.= "Content-Type: application/x-www-form-urlencoded\r\n";
$out.= "Content-Length: ".strlen($post_string)."\r\n";
$out.= "Connection: Close\r\n\r\n";
fwrite($fp, $out);
fclose($fp);
}
?>
testpage.php
<?
echo $_REQUEST["Keywordname"];//Output > testValue
?>