php 的 fsockopen()函数相关

第一步:

首先准备两个文件a.php和b.php,两个文件都放到一台服务器上,同时创建a.txt, 1.txt, 2.txt, 3.txt文件,这几个txt文件都设置777权限

目录机构如下:

其中a.php文件的代码如下:

<?php

class test{

        /**
     * php异步请求
     * @param $host string 主机地址
     * @param $path string 路径
     * @param $param array 请求参数
     * @return string
     */
    private static function asyncRequest($host, $path, $param = array())
    {   
        $query = isset($param) ? http_build_query($param) : '';
        $port = 80;
        $errno = 0;
        $errstr = '';
        $timeout = 30; //连接超时时间(S)
        
        //打开连接通道
        $fp = fsockopen($host, $port, $errno, $errstr, $timeout);
        //$fp = stream_socket_client("tcp://".$host.":".$port, $errno, $errstr, $timeout);
        
        //echo '<pre>'; 
        //var_dump($query);
        //var_dump($fp);
        //var_dump($host,$port,$errstr,$timeout);
        //die;
        
        if (!$fp) {
            var_dump('连接失败');
            return '连接失败';
        }
        if ($errno || !$fp) {
            var_dump($errstr);
            return $errstr;
        }
        
        stream_set_blocking($fp, 0); //非阻塞
        stream_set_timeout($fp, 1);//响应超时时间(S)

        //通道打开,模拟HTTP请求,http协议标准的换行是\r\n,
        //说明: 一般我们用浏览器访问网站(get请求或者post请求)时, 我们并没有写请求头,是因为浏览器自动为我们加上请求头; 但是但我们用代码模仿浏览器发送get/post请求的时候,需要我们自己把请求头加上, 这也是我们为什么写下面这段代码的原因.
        $out = "POST " . $path . " HTTP/1.1\r\n";
        $out .= "host:" . $host . "\r\n";
        $out .= "content-length:" . strlen($query) . "\r\n";
        $out .= "content-type:application/x-www-form-urlencoded\r\n";
        $out .= "connection:close\r\n\r\n";
        $out .= $query;
        
        //http模拟完成,发送给服务器
        $result = fwrite($fp, $out);

        //接受服务器的返回结果
        //$s='';
        //while(!feof($fp)){
        //    $s.=fread($fp,1024);
        //}
        //echo $s;


        fclose($fp);
        var_dump('接口调用完毕');
        var_dump($result);
        //return $result;
    }

    /**
     * 正常接口a.php
     * @param $host string 主机地址
     * @param $path string 路径
     * @param $param array 请求参数
     */
    public function a()
    {
        $param = array(
            'name' => 'Jack',
            'age' => 30,
            'sex' => 'man'
        );
        $asyncData = $this->asyncRequest('localhost', '/b.php', $param);

        echo 'a.php success';
    }

}

$m = new test();
$m->a();
                                                                

b.php代码如下:

<?php


class test{

    public function b()
    {
        set_time_limit(0);

        $s = json_encode($_POST);
        file_put_contents('./a.txt',$s);

//        ignore_user_abort(true);//设置与客户机断开是否会终止执行
//        fastcgi_finish_request();//提高请求的处理速度  
        sleep(30);
        echo "耗时30秒";
        file_put_contents('./1.txt','第一个时间标记');


        sleep(20);
        echo "耗时20秒";

        file_put_contents('./2.txt','第二个时间标记');
        sleep(10);
        echo "耗时10秒";
        file_put_contents('./3.txt','第三个时间标记');

    }

}

$m = new test();
$m->b();

第二步:

通过浏览器地址栏访问: 192.168.30.190/a.php,

第三步:

通过浏览器地址栏访问, 浏览器迅速打印信息(迅速打印信息说明fsockopen()函数非阻塞效果已经生效)如下:

然后迅速的查看a.txt, 1.txt, 2.txt, 3.txt, 4.txt(不断的(每次可以间隔0.5秒)按键盘上的 “ ↑ ” 键、“ Enter ”键,去监测这几个文件是否有数据写入)目录中是否有内容被写入

如下:

可以看到a.txt是迅速被写入内容的, 紧接着随着sleep()函数的的休眠时间的不断流逝,  1.txt, 2.txt, 3.txt文件依次间隔一段时间被写入数据

结论:

通过以上实验, 说明fsockopen()函数中

        stream_set_blocking($fp, 0); //非阻塞

的非阻塞效果已经显现了, 请求a.php文件,迅速打印数据,  并未阻塞, 然后通过fsockopen()函数异步发送请求, 去请求b.php中的模拟的耗时任务, 最后将b.php中的耗时任务都执行完毕。

其他说明参考: https://blog.csdn.net/Hiking_Tsang/article/details/70332149

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值