关于PHP实现异步操作的研究

 更新时间:2013年02月03日 23:47:49   投稿:mdxy-dxy  
一般来说PHP适用的场合是web页面展示等耗时比较短的任务,如果对于比较花时间的操作如resize图片、大数据导入、批量发送EDM、SMS等,就很容易出现操作超时情况

1.为啥PHP需要异步操作?

一般来说PHP适用的场合是web页面展示等耗时比较短的任务,如果对于比较花时间的操作如resize图片、大数据导入、批量发送EDM、SMS等,就很容易出现操作超时情况。你可以说我可以设置无限超时时间,等等你也要知道PHP有一个工作模式是fastcgi,PHP无限不超时,不代表fastcgi相应不超时……如果你还想说要fastcgi相应永不超时,我建议你应该跟你们的运维人员讨论去……

这个时候异步的操作就发挥他的作用了,由于是非阻塞操作,操作会即时返回,然后在后台再慢慢干活。管你超时不超时的,我就没有在当前的进程/线程下干活。看吧是不是很美好,不过其实这也是个坑……

2.PHP可以实现异步操作吗?

答案是肯定的,不过网上各种的纯PHP实现得就有点别扭了。socket模式、挂起进程模式、有的还直接fork进程。很好,各路神仙各显神通。如果运维人员看到的话,一定会×××××你们的,不把web server跑死才怪……

3.为啥选择Gearman?

别的不说,就说他的client多,支持很多语言的client,你可以使用大部分你喜欢的语言去写worker。我个人是很烦语言之争,你喜欢用神码语言写worker都随你喜欢。有数据持久化支持(就是把队列保存到数据库介质中,那故障恢复也好做),有群集支持(其实很多××MQ都有这些功能)。PECL上有扩展,也有纯PHP实现扩展。反正这个Gearman也活了很久了,杂七杂八的问题都基本上解决了。

4.基本思路

不好意思,里面是没有注释的。一个配置文件,一个py脚本。基本的功能也就是分析一下调用的参数,然后调用PHP Cli,就是那样子而已。要让py脚本跑起来请自行安装python的gearman模块。

然后到PHP的部分先上测试代码:

复制代码 代码如下:

<?php
require_once 'PHPAsyncClient.php';
date_default_timezone_set('Asia/Shanghai');

class AsyncTest {

    const
        LOG_FILE = '/debug.log';

    static public function run() {
        if (PHPAsyncClient::in_callback(__FILE__)) {
            self::log('php Async callback');
            PHPAsyncClient::parse();
            return;
        }
        if (PHPAsyncClient::is_main(__FILE__)) {
            self::log('main run');
            $async_call = PHPAsyncClient::getInstance();
            $async_call->AsyncCall('AsyncTest', 'callback', array(
                'content' => 'Hello World!!!',
            ), array(
                'class' => 'AsyncTest',
                'method' => 'callback',
                'params' => array(
                    'content' => 'Hello Callback!',
                ),
            ), __FILE__);
            return;
        }
    }

    static public function callback($args) {
        self::log('AsyncTest callback run');
        self::log('AsyncTest callback args:'.print_r($args, true));
    }

    static public function log($content) {
        $fullname = dirname(__FILE__).self::LOG_FILE;
        $content = date('[Y-m-d H:i:s]').$content."\n";
        file_put_contents($fullname, $content, FILE_APPEND);
    }
}
AsyncTest::run();

就3个静态方法,一个是用于调试的log方法,其他都是字面意思。这个例子是对这种调用方式有个初步印象。然后直接上PHP的所有源码:

php_async.zip

然后应该会有很多人会说,win下安装不了gearman……所以我把java版的gearman server也放上去吧。

java-gearman-service-0.6.6.zip

5.结论

经过以上配置犀牛一样大的家伙后(要装一个Gearman,还要跑个Py脚本),我们基本上就使PHP拥有了异步调用功能,当然其中还有一个状态维护神马的要自己去实现。所以发现,其实这个方案不咋样,太复杂了。还是使用一些web service的方式去做web callback会好点(问题是web callback一样会超时……),这个请留意后续。  

为防止上面的代码无法下载,脚本之家特打包下载

原文链接:http://my.oschina.net/wakanoc/blog/101789

相关文章

  • PHP封装mysqli基于面向对象的mysql数据库操作类与用法示例

    PHP封装mysqli基于面向对象的mysql数据库操作类与用法示例

    这篇文章主要介绍了PHP封装mysqli基于面向对象的mysql数据库操作类与用法,涉及php使用mysqli操作mysql数据库的连接、执行sql语句、关闭连接等相关操作技巧,需要的朋友可以参考下
    2019-02-02
  • php下判断数组中是否存在相同的值array_unique

    php下判断数组中是否存在相同的值array_unique

    今天在改一个N久以前写的程序 突然碰到一个问题 假设有一个数组$a中存在几个value 我如何判断这些value当中是否存在相同的值呢? 翻了好多资料,也问了兵哥哥,给我一些思路,想自己写来着~~~ 还是不肯放弃百度,最后搞了一次,居然找到这么一个函数 array_unique爽大了。
    2008-03-03
  • php中隐形字符65279(utf-8的BOM头)问题

    php中隐形字符65279(utf-8的BOM头)问题

    这篇文章主要介绍了php中隐形字符65279问题解决方法,其实就是utf-8文件的BOM头,本文给出了一个删除PHP文件BOM头的小程序,需要的朋友可以参考下
    2014-08-08
  • PHP提示Notice: Undefined variable的解决办法

    PHP提示Notice: Undefined variable的解决办法

    今天在调试程序的时候,很多网上提供的源码都会出现 Undefined variable错误,一般情况下php是不需要定义变量的,但如果服务器什么都报错的,就会出现错误,所以服务器上都是应该屏蔽这种错误的
    2012-11-11
  • php命令行用法入门实例教程

    php命令行用法入门实例教程

    这篇文章主要介绍了php命令行用法入门,以实例的形式分析了在命令行中运行php程序的方法,非常具有实用价值,需要的朋友可以参考下
    2014-10-10
  • PHP 金额数字转换成英文

    PHP 金额数字转换成英文

    找了很久,搜索的关键词总是词不达意似的。
    2010-05-05
  • 让Json更懂中文(JSON_UNESCAPED_UNICODE)

    让Json更懂中文(JSON_UNESCAPED_UNICODE)

    我们知道, 用PHP的json_encode来处理中文的时候, 中文都会被编码, 变成不可读的, 类似”\u***”的格式, 还会在一定程度上增加传输的数据量.
    2011-10-10
  • 解析php开发中的中文编码问题

    解析php开发中的中文编码问题

    其实php开发中的中文编码并没有想像的那么复杂,虽然定位和解决问题没有定规,各种运行环境也各不尽然,但后面的原理是一样的。了解字符集的知识是解决字符问题的基础
    2013-08-08
  • php实现微信公众平台账号自定义菜单类

    php实现微信公众平台账号自定义菜单类

    这篇文章主要介绍了php实现微信公众平台账号自定义菜单类的方法,涉及针对微信接口API的二次开发,是非常实用的技巧,需要的朋友可以参考下
    2014-12-12
  • PHP中PDO关闭连接的方法问题

    PHP中PDO关闭连接的方法问题

    这篇文章主要介绍了PHP中PDO关闭连接的方法问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01

最新评论