Как запустить PHP-код асинхронно - PullRequest
14 голосов
/ 06 мая 2011

Как я могу запустить код PHP асинхронно, не дожидаясь? У меня есть долгосрочный прогон (почти бесконечный), который должен работать при запуске сервера и должен обрабатываться асинхронно, без ожидания.

Возможные варианты:

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

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

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

Ответы [ 5 ]

24 голосов
/ 06 мая 2011

Если вы хотите запустить его из браузера (возможно, вы не знакомы с командной строкой), вы все равно можете это сделать. Несколько месяцев назад я исследовал множество решений для этого, и самым надежным и простым для реализации было следующее из Как разместить асинхронный 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 файл начнет работать. Возможно, вы захотите добавить некоторые выходные данные в браузер, чтобы сообщить, что они были успешно отправлены, и не мешало бы добавить некоторую защиту, если ваш веб-сервер открыт для остального мира. Хорошая особенность этого решения, если вы добавите некоторую безопасность, - это то, что вы можете начать работу везде, где сможете найти браузер.

4 голосов
/ 06 мая 2011

Определенно звучит как работа для задачи cron.Вы можете настроить php-скрипт для выполнения своей задачи один раз и запускать cron так часто, как вам нравится. Вот хорошая статья о том, как запустить скрипт php в качестве задачи cron;это очень легко сделать.

0 голосов
/ 19 декабря 2016

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

cornjobpage.php // главная страница

     <?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
    ?>
0 голосов
/ 06 мая 2011

Как я могу запускать код 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);
}
?>

Украшения: Чтобы сделать ваш скрипт непосредственно исполняемым: chmod + x yourscript.php и добавьте #! / Usr / bin / phpначало вашего скрипта

Чтобы начать с apache, вы должны добавить эту команду в ваш скрипт запуска apache (обычно apachectl) и обязательно добавить код, чтобы убить его, когда apache остановится.

Проверкаесли вы уже работаете, включает файл с вашим PID в / var / locks / и что-то вроде system ('/ bin / ps'. $ thePID);Это также облегчает написание инструкции по уничтожению.

0 голосов
/ 06 мая 2011

Это не совсем то, для чего предназначен PHP. Вы должны использовать библиотеку потоков PECL для выделения потоков, которые работают асинхронно, и я не рекомендую это делать. Новая проблема в асинхронном отделе - это node.js - я рекомендую вам изучить это и посмотреть, сможете ли вы его использовать. Он предназначен для облегченных асинхронных сетевых операций и может использоваться для запуска сценариев PHP.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...