简体   繁体   English

如何异步运行PHP代码

[英]How to run the PHP code asynchronous

How can I run PHP code asynchronously without waiting? 如何在不等待的情况下异步运行PHP代码? I have a long run (almost infinite) that should run while server starts and should process asynchronously without waiting. 我有一个长期运行(几乎无限)应该在服务器启动时运行,并且应该异步处理而无需等待。

The possible options I guess are: 我猜可能的选择是:

  1. Running the code in a web page and keep it open to do that task 在网页中运行代码并保持打开状态以执行该任务
  2. Calling the script from some command line utility (I am not sure how) which would process in the background. 从某个命令行实用程序调用脚本(我不确定如何)将在后台处理。

I am running the PHP scripts on my local server which will send emails when certain events occur, eg birthday reminders. 我在本地服务器上运行PHP脚本,当发生某些事件时会发送电子邮件,例如生日提醒。

Please suggest how can I achieve this without opening the page in a browser. 请建议如何在不在浏览器中打开页面的情况下实现此目的。

If you wanted to run it from the browser (perhaps you're not familiar with the command line) you could still do it. 如果你想从浏览器运行它(也许你不熟悉命令行),你仍然可以这样做。 I researched many solutions for this a few months ago and the most reliable and simplest to implement was the following from How to post an asynchronous HTTP request in PHP 几个月前我研究了很多解决方案,最可靠和最简单的实现方法如下: 如何在PHP中发布异步HTTP请求

<?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);
}

Let's say the file above is in your web root directory ( /var/www ) for example and is called runjobs.php. 假设上面的文件位于您的Web根目录( /var/www )中,例如名为runjobs.php。 By visiting http://localhost/runjobs.php your myjob.php file would start to run. 通过访问http://localhost/runjobs.php您的myjob.php文件将开始运行。 You'd probably want to add some output to the browser to let you know it was submitted successfully and it wouldn't hurt to add some security if your web server is open to the rest of the world. 您可能希望向浏览器添加一些输出以告知您已成功提交,如果您的Web服务器对世界其他地方开放,则添加一些安全性也不会有什么坏处。 One nice thing about this solution if you add some security is that you can start the job anywhere you can find a browser. 如果添加一些安全性,这个解决方案的一个好处是你可以在任何可以找到浏览器的地方开始工作。

Definitely sounds like a job for a cron task. 绝对听起来像是一项cron任务的工作。 You can set up a php script to do your task once and have the cron run as often as you like. 您可以设置一个php脚本来执行一次任务,并让cron随时运行。 Here's a good writeup on how to have a php script run as a cron task; 这是关于如何将php脚本作为cron任务运行的好文章; it's very easy to do. 这很容易做到。

thanks Todd Chaffee but it is not working for me so i edited your code i hope you will not mind and may be it will also help others with this technique 谢谢Todd Chaffee,但它不适合我,所以我编辑了你的代码我希望你不介意,也许它也会帮助其他人用这种技术

cornjobpage.php //mainpage 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 testpage.php

    <?
    echo $_REQUEST["Keywordname"];//Output > testValue
    ?>

This isn't really what PHP is designed for. 这不是PHP的设计目的。 You have to use the PECL threading library to spin off threads that run asynchronously, and I don't recommend it. 您必须使用PECL线程库来分离异步运行的线程,我不推荐它。 The new hotness in the async department is node.js - I recommend you look into that and see if you can utilize it. 异步部门的新热点是node.js - 我建议你研究一下,看看你是否可以利用它。 It's designed for light weight, asynchronous network operations, and can be used to fire PHP scripts. 它专为轻量级,异步网络操作而设计,可用于触发PHP脚本。

How Can I run PHP code asynchronously without waiting. 如何在不等待的情况下异步运行PHP代码。 I have a long run (almost inifinite) that should run while server starts and should process asynchrously without waiting. 我有一个长期运行(几乎无限)应该在服务器启动时运行,并且应该异步处理而无需等待。

Assuming a typical LAMP system, you can start a PHP daemon from the command line with 假设有一个典型的LAMP系统,你可以从命令行启动一个PHP守护进程

root# php yourscript.php &

where yourscript.php contains something similar to 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);
}
?>

Embellishments: To make your script directly executable: chmod +x yourscript.php and add #!/usr/bin/php to the beginning of yourscript 装饰:使你的脚本可以直接执行:chmod + x yourscript.php并将#!/ usr / bin / php添加到你脚本的开头

To start with apache, you should add that command to your apache startup script (usually apachectl) and be sure to add code to kill it when apache stops. 要从apache开始,您应该将该命令添加到您的apache启动脚本(通常是apachectl)中,并确保在apache停止时添加代码来终止它。

The check if you are already running involves a file with your PID in /var/locks/ and something like system('/bin/ps '.$thePID); 检查你是否已经在运行涉及一个文件,其中你的PID在/ var / locks /中,类似于system('/ bin / ps'。$ thePID); It also makes the kill instruction easier to write. 它还使kill指令更容易编写。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM