1.为啥PHP需要异步操作?
一般来说PHP适用的场合是web页面展示等耗时比较短的任务,如果对于比较花时间的操作如resize图片、大数据导入、批量发送EDM、SMS等,就很容易出现操作超时情况。你可以说我可以设置无限超时时间,等等你也要知道PHP有一个工作模式是fastcgi,PHP无限不超时,不代表 fastcgi相应不超时……如果你还想说要fastcgi相应永不超时,我建议你应该跟你们的运维人员讨论去……
这个时候异步的操作就发挥他的作用了,由于是非阻塞操作,操作会即时返回,然后在后台再慢慢干活。管你超时不超时的,我就没有在当前的进程/线程下干活。看吧是不是很美好,不过其实这也是个坑……
2.PHP可以实现异步操作吗?
答案是肯定的,不过网上各种的纯PHP实现得就有点别扭了。socket模式、挂起进程模式、有的还直接fork进程。很好,各路神仙各显神通。如果运维人员看到的话,一定会×××××你们的,不把web server跑死才怪……
那还有其他更好的方法去实现这个异步操作的可能么?有,现在我们只有想怎么开外挂了。查一下PECL主流的外挂方案有一堆的××MQ(消息队列),其中有个用于任务分配的外挂进入了我们的视线Gearman(其实这家伙才是角,我就不详细介绍了,点连接看介绍)。
3.为啥选择Gearman?
别的不说,就说他的client多,支持很多语言的client,你可以使用大部分你喜欢的语言去写worker。我个人是很烦语言之争,你喜欢用神码语言写worker都随你喜欢。有数据持久化支持(就是把队列保存到数据库介质中,那故障恢复也好做),有群集支持(其实很多××MQ都有这些功能)。 PECL上有扩展,也有纯PHP实现扩展。反正这个Gearman也活了很久了,杂七杂八的问题都基本上解决了。
4.基本思路
有了Gearman这外挂就简单多了。就是向gearman发送一个任务,把执行的任务发出去,然后等待worker去调用PHP cli去运行我们的php代码。
我就写了一下一个python的worker(别问我为啥用python,1.我会python,2.linux下不用装runtime),你可以自己根据思路写一个PHP的worker,不过嘛,本人是不太信得过PHP跑的worker。其他语言饭可以用java、node.js 或者其他语言实现一个worker试试。对用Golang写worker有兴趣的朋友可以找我。
phpasync_worker_py
不好意思,里面是没有注释的。一个配置文件,一个py脚本。基本的功能也就是分析一下调用的参数,然后调用PHP Cli,就是那样子而已。要让py脚本跑起来请自行安装python的gearman模块。
然后到PHP的部分先上测试代码:
<ol> <li><span><span><?php </span></span></span></li> <li> <span>require_once</span><span> </span><span>'PHPAsyncClient.php'</span><span>; </span> </li> <li> <span>date_default_timezone_set(</span><span>'Asia/Shanghai'</span><span>); </span> </li> <li><span> </span></li> <li> <span>class</span><span> AsyncTest { </span> </li> <li><span> </span></li> <li> <span> </span><span>const</span><span> </span> </li> <li> <span> LOG_FILE = </span><span>'/debug.log'</span><span>; </span> </li> <li><span> </span></li> <li> <span> </span><span>static</span><span> </span><span>public</span><span> </span><span>function</span><span> run() { </span> </li> <li> <span> </span><span>if</span><span> (PHPAsyncClient::in_callback(</span><span>__FILE__</span><span>)) { </span> </li> <li> <span> self::log(</span><span>'php Async callback'</span><span>); </span> </li> <li><span> PHPAsyncClient::parse(); </span></li> <li> <span> </span><span>return</span><span>; </span> </li> <li><span> } </span></li> <li> <span> </span><span>if</span><span> (PHPAsyncClient::is_main(</span><span>__FILE__</span><span>)) { </span> </li> <li> <span> self::log(</span><span>'main run'</span><span>); </span> </li> <li> <span> </span><span>$async_call</span><span> = PHPAsyncClient::getInstance(); </span> </li> <li> <span> </span><span>$async_call</span><span>->AsyncCall(</span><span>'AsyncTest'</span><span>, </span><span>'callback'</span><span>, </span><span>array</span><span>( </span> </li> <li> <span> </span><span>'content'</span><span> => </span><span>'Hello World!!!'</span><span>, </span> </li> <li> <span> ), </span><span>array</span><span>( </span> </li> <li> <span> </span><span>'class'</span><span> => </span><span>'AsyncTest'</span><span>, </span> </li> <li> <span> </span><span>'method'</span><span> => </span><span>'callback'</span><span>, </span> </li> <li> <span> </span><span>'params'</span><span> => </span><span>array</span><span>( </span> </li> <li> <span> </span><span>'content'</span><span> => </span><span>'Hello Callback!'</span><span>, </span> </li> <li><span> ), </span></li> <li> <span> ), </span><span>__FILE__</span><span>); </span> </li> <li> <span> </span><span>return</span><span>; </span> </li> <li><span> } </span></li> <li><span> } </span></li> <li><span> </span></li> <li> <span> </span><span>static</span><span> </span><span>public</span><span> </span><span>function</span><span> callback(</span><span>$args</span><span>) { </span> </li> <li> <span> self::log(</span><span>'AsyncTest callback run'</span><span>); </span> </li> <li> <span> self::log(</span><span>'AsyncTest callback args:'</span><span>.print_r(</span><span>$args</span><span>, true)); </span> </li> <li><span> } </span></li> <li><span> </span></li> <li> <span> </span><span>static</span><span> </span><span>public</span><span> </span><span>function</span><span> log(</span><span>$content</span><span>) { </span> </li> <li> <span> </span><span>$fullname</span><span> = dirname(</span><span>__FILE__</span><span>).self::LOG_FILE; </span> </li> <li> <span> </span><span>$content</span><span> = </span><span>date</span><span>(</span><span>'[Y-m-d H:i:s]'</span><span>).</span><span>$content</span><span>.</span><span>"\n"</span><span>; </span> </li> <li> <span> </span><span>file_put_contents</span><span>(</span><span>$fullname</span><span>, </span><span>$content</span><span>, FILE_APPEND); </span> </li> <li><span> } </span></li> <li><span>} </span></li> <li><span> </span></li> <li><span>AsyncTest::run(); </span></li> </ol>
就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实现异步操作的研究,包括了php,关于方面的内容,希望对PHP教程有兴趣的朋友有所帮助。

tomodifyDataNaphPsession,startTheSessionWithSession_start(),然后使用$ _sessionToset,修改,orremovevariables.1)startThesession.2)setthesession.2)使用$ _session.3)setormodifysessessvariables.3)emovervariableswithunset()

在PHP会话中可以存储数组。1.启动会话,使用session_start()。2.创建数组并存储在$_SESSION中。3.通过$_SESSION检索数组。4.优化会话数据以提升性能。

PHP会话垃圾回收通过概率机制触发,清理过期会话数据。1)配置文件中设置触发概率和会话生命周期;2)可使用cron任务优化高负载应用;3)需平衡垃圾回收频率与性能,避免数据丢失。

PHP中追踪用户会话活动通过会话管理实现。1)使用session_start()启动会话。2)通过$_SESSION数组存储和访问数据。3)调用session_destroy()结束会话。会话追踪用于用户行为分析、安全监控和性能优化。

利用数据库存储PHP会话数据可以提高性能和可扩展性。1)配置MySQL存储会话数据:在php.ini或PHP代码中设置会话处理器。2)实现自定义会话处理器:定义open、close、read、write等函数与数据库交互。3)优化和最佳实践:使用索引、缓存、数据压缩和分布式存储来提升性能。

phpsessionstrackuserdataacrossmultiplepagerequestsusingauniqueIdStoredInacookie.here'showtomanageThemeffectionaly:1)startAsessionWithSessionwwithSession_start()和stordoredAtain $ _session.2)

在PHP中,遍历会话数据可以通过以下步骤实现:1.使用session_start()启动会话。2.通过foreach循环遍历$_SESSION数组中的所有键值对。3.处理复杂数据结构时,使用is_array()或is_object()函数,并用print_r()输出详细信息。4.优化遍历时,可采用分页处理,避免一次性处理大量数据。这将帮助你在实际项目中更有效地管理和使用PHP会话数据。

会话通过服务器端的状态管理机制实现用户认证。1)会话创建并生成唯一ID,2)ID通过cookies传递,3)服务器存储并通过ID访问会话数据,4)实现用户认证和状态管理,提升应用安全性和用户体验。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

VSCode Windows 64位 下载
微软推出的免费、功能强大的一款IDE编辑器

SublimeText3 Linux新版
SublimeText3 Linux最新版

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

mPDF
mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),