php fsockopen()方法,简化,异步非阻塞调用

本文介绍了使用PHP的fsockopen函数实现非阻塞请求的方法,解决了因长时间运行方法导致程序阻塞的问题。通过具体实例展示了如何触发目标方法而不等待其返回结果。

介绍

在项目中遇到一个问题,就是php是同步的读取下来的,如果一个方法请求的时间长了一点, 那么整个程序走下去将会遇到阻塞,现在我想触发这个方法,但是又不影响我下下面的程序正常的走下去。查了一上午的方法, 就这个函数比较靠谱,但是会比较low 一点, 因为直接是通过url寻找我们要触发的方法。

方法

function _sock($url) {
    $host = parse_url($url,PHP_URL_HOST);
    $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 = parse_url($url,PHP_URL_QUERY);
    if($query) $path .= '?'.$query;
    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,true);//开启了手册上说的非阻塞模式
        stream_set_timeout($fp,1);//设置超时
        $header = "GET $path HTTP/1.1\r\n";
        $header.="Host: $host\r\n";
        $header.="Connection: close\r\n\r\n";//长连接关闭
        fwrite($fp, $header);
        usleep(1000); // 这一句也是关键,如果没有这延时,可能在nginx服务器上就无法执行成功
        fclose($fp);
        return array('error_code' => 0);
    }
}

例子

比如我在a站点:   http://tp5test.test/index.php/index/yibu   代码如下。

    public function index(){
        sleep('600');
        echo "kk";
    }

我在b站点触发这个方法,但是不想等待a站的返回,我只想摸一下她,其他我啥都不干。我继续做我要做的事情。

        $this->_sock('http://tp5test.test/index.php/index/yibu');
        echo "我没有等a站点返回值,我就执行了";

结论

通常直接curl 访问 a站点的值会一直等待,但是通过php的 fsockopen ,即可实现简单的最小1秒钟的阻塞。

 

 

PHP 中实现异步非阻塞处理机制,主要依赖于其运行环境、扩展以及编程模型的优化。PHP 本身是单线程、同步阻塞的语言,但在实际开发中,可以通过多种方式实现异步非阻塞的效果,从而提升系统性能和并发处理能力。 ### 异步非阻塞的实现方式 1. **FastCGI 的非阻塞方法(`fastcgi_finish_request()`)** 在 PHP-FPM 环境下,可以使用 `fastcgi_finish_request()` 函数提前结束 HTTP 响应,使客户端可以立即收到响应,而服务器继续在后台执行后续逻辑。这种方式适用于需要异步处理日志记录、邮件发送等操作的场景。 ```php echo "Response sent to client"; fastcgi_finish_request(); // 后续代码继续执行,但客户端已收到响应 ``` 2. **使用 `fsockopen()` + `stream_set_blocking()`** 通过创建非阻塞的 socket 连接,可以在不等待响应的情况下发起外部请求。此方法适合需要与外部服务通信但不关心其结果的场景[^1]。 3. **cURL 多请求异步执行** 使用 `curl_multi_init()` 可以同时发起多个 cURL 请求,并通过非阻塞方式处理网络 I/O,从而实现异步 HTTP 请求[^1]。 4. **使用异步框架(如 Swoole、ReactPHP、Amp)** 这些框架基于事件驱动和协程模型,提供了完整的异步非阻塞处理能力。例如,Swoole 提供了协程、异步 I/O、定时器等功能,使得 PHP 可以构建高性能的异步服务。 5. **使用 Gearman 或 Redis 队列实现异步任务分发** 将耗时任务放入队列中由工作进程异步处理,主流程可以快速返回响应,适用于异步日志、批量数据处理等场景。 6. **使用 `pcntl_fork()` 创建子进程** 在 CLI 模式下,可以通过 `pcntl_fork()` 创建子进程来执行异步任务,主进程可立即返回结果。 ### 异步非阻塞处理机制 PHP异步非阻塞处理机制主要围绕以下几个核心概念: - **协程(Coroutine)**:协程是一种用户态的轻量级线程,可以在单线程中实现多个任务的调度。例如,Swoole 和 Amp 框架都基于协程实现异步编程模型[^2]。 - **事件循环(Event Loop)**:异步框架通常依赖事件循环来监听和处理 I/O 事件,如网络请求、定时器等。ReactPHP 和 Amp 都提供了强大的事件循环机制[^2]。 - **连接池(Connection Pool)**:在数据库访问中,连接池可以避免频繁创建和销毁连接带来的性能损耗。例如,AMPHP 提供了异步非阻塞的 MySQL 客户端连接池[^2]。 ### 实际应用示例(Swoole 协程) ```php go(function () { $client = new Swoole\Coroutine\Http\Client('example.com', 80); $client->get('/', function ($client) { echo $client->body; }); $client->close(); }); ``` 上述代码使用 Swoole 协程发起异步 HTTP 请求,主线程不会被阻塞,适用于高并发场景。 ### 总结 PHP 虽然默认是同步阻塞的,但通过 FastCGI、异步框架、协程、事件循环等方式,可以实现高效的异步非阻塞处理机制。在选择实现方式时,应根据具体业务需求和部署环境进行合理选择。 ---
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

脚本大王

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值