PHP异步 fsockopen篇

项目中遇到发布一个信息后需要给关联用户推送模板消息,这个想都不用想肯定是要抛异步任务的

可是PHP不能异步,可怜我又不会其他语言,swoole我还没有用过,也来不及现在研究,而且还有装扩展的,实在是太麻烦

百度了下可以说是可以用fsockopen,在项目中已经实现了,今天来做下笔记

// 先看下网上找的例子
// 例1
<?php
/*利用php的系统调用,开启新的进程来实现。

php 提供了fsockopen函数,此函数的功能为初始化一个套接字连接到指定主机,默认情况下将以阻塞模式开启套接字连接。当然你可以通过stream_set_blocking()将它转换到非阻塞模式。这是关键。所以,思路就是:开启一个非阻塞的套接字连接到本机,本机收到之后作一些耗时处理。

类似这样的处理代码(文件posttest.php):*/

$fp = fsockopen($php_Path,80);
if (!$fp) {
    LMLog::error("fsockopen:err" );
} else {
    $out = "GET /album/action/album_write_friends_thread_record.php?key=&u=   HTTP/1.1\r\n";
    $out .= "Host: ".$php_Path."\r\n";
    $out .= "Connection: Close\r\n\r\n";
    stream_set_blocking($fp,true);
    stream_set_timeout($fp,1);
    fwrite($fp, $out);
    usleep(1000);
    fclose($fp);
}

/*这里,usleep(1000) 非常关键,它能保证这个请求能发出去。*/
?>

<?php
/*我们在来看处理的代码逻辑(文件album_write_friends_thread_record.php)*/

/**
 * 客户端调用服务器接口页面
 * user: guwen
 */
sleep(20);// 睡眠20s
?>

// 例2
<?php 
    
$url = 'http://www.example.com/doRequest.php'; 
$param = array( 
  'name'=>'fdipzone', 
  'gender'=>'male', 
  'age'=>30 
); 
    
doRequest($url, $param); 
    
function doRequest($url, $param=array()){ 
    
  $urlinfo = parse_url($url); 
    
  $host = $urlinfo['host']; 
  $path = $urlinfo['path']; 
  $query = isset($param)? http_build_query($param) : ''; 
    
  $port = 80; 
  $errno = 0; 
  $errstr = ''; 
  $timeout = 10; 
    
  $fp = fsockopen($host, $port, $errno, $errstr, $timeout); 
    
  $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; 
    
  fputs($fp, $out); 
  fclose($fp); 
} 

	
//注意:当执行过程中,客户端连接断开或连接超时,都会有可能造成执行不完整,因此需要加上
ignore_user_abort(true); // 忽略客户端断开 
set_time_limit(0);    // 设置执行不超时

例子的原贴地址

例1 https://www.cnblogs.com/JDtech/p/6418438.html

例2 http://www.php.cn/php-weizijiaocheng-383499.html

 

下面是我在yii1的使用部分代码

<?php
/**
 * 模板消息发送api
 * User: lewiss
 * Date: 2018/8/24
 * Time: 17:12
 */

class TempController extends Api_pubController {

    public function actionIndex() {

        $limit = 50;

        $get_last_id = !empty($_GET['last_id']) ? (int)$_GET['last_id'] : 0;

        $list = Yii::app()->db->createCommand()
            ->select("user.id,user.wxopenid,member.m_name")
            ->from("{{school_member}} member")
            ->join("{{user}} user", "member.user_id=user.id")
            ->where("class_id=:class_id and member.type=3 and user.id>:last_id",
                [":class_id" => (int)$_GET['class_id'], ':last_id' => $get_last_id])
            ->order("user.id")
            ->limit($limit)
            ->queryAll();

        $data = [
            "school_id" => $_GET['school_id'],
            "class_id" => $_GET['class_id'],
            "class_name" => $_GET['class_name'],
            "teacher" => $_GET['teacher'],
            "title" => $_GET['title'],
        ];

        $school_id = Fun_filter::wwy_md5_set($_GET["school_id"]);
        $last_id = 0;
        foreach ($list as $value) {
            $last_id = $value['id'];
            $data['openid'] = $value['wxopenid'];
            $data['m_name'] = $value['m_name'];
            $data['url'] = "http://ktkids.cn/kt_edu/index.php?r=wap/default/class_trends&school_id={$school_id}&trend_id={$_GET['trend_id']}&trend_class_id={$_GET['class_id']}";
            $this->fso("/kt_edu/index.php?r=temp/send", $data);
        }

        if ($last_id) {
            $data['last_id'] = $last_id;
            $data['trend_id'] = $_GET['trend_id'];
            $this->fso('/kt_edu/index.php?r=temp', $data);
        }
    }

    public function actionSend() {
        $m_name = Yii::app()->request->getParam('m_name');
        $class_name = Yii::app()->request->getParam('class_name');
        $teacher = Yii::app()->request->getParam('teacher');
        $title = Yii::app()->request->getParam('title');
        $openid = Yii::app()->request->getParam('openid');
        $school_id = Yii::app()->request->getParam('school_id');
        $url = Yii::app()->request->getParam('url');


        $template_id = "SsiA1yYA2q6yq7lJiREgravOFf0ySAeOKkLiXxd_bl4";
        $data = array(
            '1' => array('name' => 'first', 'value' => '您好,亲爱的' . $m_name . '家长', 'color' => '#173177'),
            '2' => array('name' => 'keyword1', 'value' => $class_name, 'color' => '#173177'),
            '3' => array('name' => 'keyword2', 'value' => $teacher, 'color' => '#173177'),
            '4' => array('name' => 'keyword3', 'value' => date("Y年m月d日 H:i"), 'color' => '#173177'),
            '5' => array('name' => 'keyword4', 'value' => $title, 'color' => '#173177'),
            '6' => array('name' => 'remark', 'value' => '点击查看通知详情', 'color' => '#173177'),
        );
        $result = Fun_temp_kt::template($school_id, $template_id, $data, $openid, $url);
        Yii::log("rsp----" . json_encode($result));
    }

    private function fso($uri, $data) {
        $param = http_build_query($data);
        $host = "xxxx.cn";
        $fp = fsockopen($host, 80);
        $out = "GET {$uri}&{$param}   HTTP/1.1\r\n";
        $out .= "Host: " . $host . "\r\n";
        $out .= "Connection: Close\r\n\r\n";
        stream_set_blocking($fp, true);
        stream_set_timeout($fp, 1);
        fwrite($fp, $out);
        usleep(1000);
        fclose($fp);
    }

}

我在本地测试时候$host写127.0.0.1是没有问题,我想在服务器上写127.0.0.1也应该没有问题,因为都是请求的本机项目,不过好像失败了,不知道是不是nginx没有配置,后来改成了域名就ok了.

这里是以上代码实例的代码码云地址

https://gitee.com/JFliuxian/PhpDemo/blob/master/PHP%E5%BC%82%E6%AD%A5/PHP%E4%B8%AD%E6%96%87%E7%BD%91fsckopenPOST%E4%BE%8B%E5%AD%90.php

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值