前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >PHP实现异步的三种方式

PHP实现异步的三种方式

作者头像
超级小可爱
发布2023-02-20 16:00:41
2.5K0
发布2023-02-20 16:00:41
举报
文章被收录于专栏:小孟开发笔记

首先说明:PHP本身不支持异步,需要使用一些特殊技巧变相实现异步的效果!

三种实现方式

通用的异步执行文件 exec.php

1 2 3

sleep(8); $data = "--- type " . date("Y-m-d H:i:s") . " ---\n"; file_put_contents("../log.txt", $data, FILE_APPEND);

popen

通过 popen() 函数打开进程文件指针,从而能异步执行脚本文件。(只在linux下有效)

1 2

pclose(popen("php exec.php &", 'r')); echo 1;

缺点:只能异步执行本地的脚本文件,不能跨域执行,不能传递参数。

每次执行都会创建新的进程,当并发量高时就创建大量进程,从而造成资源浪费。

curl(推荐)–可以把需要异步执行的操作单独写一个方法或文件通过curl来调用,通过设置超时时间来达到异步的效果

应用程序以 curl 发起 http 请求的形式实现异步。但是 curl 请求也需要等待请求返回,程序同样会阻塞,这时我们需要设置 http 请求的超时时间为1s,这样相当于发起了一个 http 请求去执行任务,但是不等待其返回结果,继续向下执行程序,这样就可以实现异步效果。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22

function asyncCurl($url, $data) {     if (is_array($data)) {         $data = http_build_query($data, null, '&');     }     $ch = curl_init();     curl_setopt($ch, CURLOPT_URL, $url);     curl_setopt($ch, CURLOPT_POST, 1);     curl_setopt($ch, CURLOPT_POSTFIELDS, $data);     curl_setopt($ch, CURLOPT_TIMEOUT, 1);     curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);     $result'response' = curl_exec($ch);     $result'httpCode' = curl_getinfo($ch, CURLINFO_HTTP_CODE);     return $result; } $url = "http://127.0.0.1/exec.php"; $data = []; asyncCurl($url, $data); echo "OK";

curl 请求实现异步方式的缺陷就是 http 请求的最小超时时间为1s。也就是应用程序无论如何都要等待1s钟以上才能响应(现在 curl 扩展也能支持毫秒级别的超时时间设置,不过毫秒时间的超时很容易造成请求失败)。

fsockopen

fsockopen() 函数用于打开一个网络连接或者一个Unix套接字连接。通过发起 http 通信来实现异步。

从原理上来说与 curl 请求一样。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32

function sockPost($host, $url, $param) {     $port = parse_url($url, PHP_URL_PORT);     $port = $port ? $port : 80;     $scheme = parse_url($url, PHP_URL_SCHEME);     $path = parse_url($url, PHP_URL_PATH);     $query = http_build_query($param);     if ($scheme == 'https') {         $host = 'ssl://' . $host;     }     $fp = fsockopen($host, $port, $error_code, $error_msg, 1);     if (!$fp) {         return array('error_code' => $error_code, 'error_msg' => $error_msg);     } else {         stream_set_blocking($fp, 0);         stream_set_timeout($fp, 10);         $header = "GET $path" . "?" . "$query" . " HTTP/1.1\r\n";         $header .= "Host: $host\r\n";         $header .= "Connection: close\r\n\r\n";//长连接关闭         fwrite($fp, $header);         usleep(2000); // 延时,防止在nginx服务器上无法执行成功         fclose($fp);         return array('error_code' => 0);     } } $host = "127.0.0.1"; $url = "/exec.php"; $param = []; $result = sockPost($host, $url, $param); var_dump($result);

fsockopen 方式相比 curl 更复杂,需要自己拼接处 http 请求的 header 部分。在 curl 不支持毫秒级超时之前 fsockopen 方式无疑是最佳选择。

未经允许不得转载:肥猫博客 » PHP实现异步的三种方式

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
命令行工具
腾讯云命令行工具 TCCLI 是管理腾讯云资源的统一工具。使用腾讯云命令行工具,您可以快速调用腾讯云 API 来管理您的腾讯云资源。此外,您还可以基于腾讯云的命令行工具来做自动化和脚本处理,以更多样的方式进行组合和重用。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档