php通过fsockopen异步发送邮件

不考虑pthreads拓展的话,原生php是不支持多线程的。如果想要在web项目中异步发送邮件或者执行其他php脚本,就可以考虑使用fsockopen的方法:发送一个socket连接请求目标脚本,不需要等待目标脚本执行结果直接关闭socket连接,接着执行后续任务,同时目标脚本由于收到请求,开始响应并执行。这就实现了php的“伪异步”。

    $url = YOUR_WEB_PATH . "/send_email";  // 异步执行的目标脚本
    $post_data = array();
    /**
     * 构造$post_data
     */

    trigger_async_request($url, $post_data); // 触发异步请求

    /**
     * 后续任务
     */
function trigger_async_request($url, $post_data = array())
{
    $method = empty($post_data) ? "GET" : "POST";
    $url_array = parse_url($url);
    $port = isset($url_array['port']) ? $url_array['port'] : 80;

    $fp = fsockopen($url_array['host'], $port, $errno, $errstr, 30);
    if (!$fp) {
        return false; // 无法打开socket连接
    }

    $getPath = isset($url_array['query']) ? $url_array['path'] . "?" . $url_array['query'] : $url_array['path'];

    $header = $method . " " . $getPath . " HTTP/1.1\r\n";
    $header .= "Host: " . $url_array['host'] . "\r\n";
    if (!empty($post_data)) {
        $post_data = http_build_query($post_data);
        $header .= "Content-Type: application/x-www-form-urlencoded\r\n";
        $header .= "Content-Length: " . strlen($post_data) . " \r\n";
    }
    $header .= "Connection: Close\r\n\r\n";
    if (!empty($post_data)) {
        $header .= $post_data . "\r\n\r\n"; //传递POST数据
    }

    fwrite($fp, $header);

    // 等待30ms,这对于nginx服务器很重要,让nginx有足够的时间将请求转交给php-fpm。
    // 否则,如果在nginx转交请求前识别到用户断开连接,那么就不会继续转交请求了。
    usleep(30000);

    fclose($fp);
    return true;
}
function send_email() {
    set_time_limit(0);
    ignore_user_abort(true);
    
    /**
     * 发送邮件。。。
     */
}

 

 

参考:

http://www.laruence.com/2008/04/14/318.html

http://www.laruence.com/2008/04/16/98.html

http://www.cnblogs.com/zhangweishi/p/5306813.html

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top