Press "Enter" to skip to content

关于PHP你可能不知道的-PHP的事件驱动化设计

最近在做一个需要用到异步PHP的项目, 翻阅PHP源码的时候,发现了三个没有用过的模块,sysvsem,sysvshm,sysvmsg,一番研究以后,受益非浅。
在PHP中有这么一族函数,他们是对UNIX的V IPC函数族的包装。
它们很少被人们用到,但是它们却很强大。巧妙的运用它们,可以让你事倍功半。
它们包括:

信号量(Semaphores)
共享内存(Shared Memory)
进程间通信(Inter-Process Messaging, IPC)

基于这些,我们完全有可能将PHP包装成一基于消息驱动的系统。
但是,首先,我们需要介绍几个重要的基础:
1. ftok

int ftok ( string pathname, string proj )
//ftok将一个路径名pathname和一个项目名(必须为一个字符), 转化成一个整形的用来使用系统V IPC的key

2. ticks
Ticks是从PHP 4.0.3开始才加入到PHP中的,它是一个在declare代码段中解释器每执行N条低级语句就会发生的事件。N的值是在declare中的directive部分用ticks=N来指定的。

function getStatus($arg){
 print_r connection_status();
 debug_print_backtrace();
}
reigster_tick_function("getStatus", true);
declare(ticks=1){
 for($i =1; $i<999; $i++){
 echo "hello";
 }
}
unregister_tick_function("getStatus");

这个就基本相当于:

function getStatus($arg){
 print_r connection_status();
 debug_print_backtrace();
}
reigster_tick_function("getStatus", true);
declare(ticks=1){
 for($i =1; $i<999; $i++){
 echo "hello"; getStatus(true);
 }
}
unregister_tick_function("getStatus");

消息,我现在用一个例子来说明,如何结合Ticks来实现PHP的消息通信。

$mesg_key = ftok(__FILE__, 'm');
$mesg_id = msg_get_queue($mesg_key, 0666);
function fetchMessage($mesg_id){
 if(!is_resource($mesg_id)){
 print_r("Mesg Queue is not Ready");
 }
 if(msg_receive($mesg_id, 0, $mesg_type, 1024, $mesg, false, MSG_IPC_NOWAIT)){
 print_r("Process got a new incoming MSG: $mesg ");
 }
}
register_tick_function("fetchMessage", $mesg_id);
declare(ticks=2){
 $i = 0;
 while(++$i < 100){
 if($i%5 == 0){
 msg_send($mesg_id, 1, "Hi: Now Index is :". $i);
 }
 }
}
//msg_remove_queue($mesg_id);

在这个例子中,首先将我们的PHP执行Process加入到一个由ftok生成的Key所获得的消息队列中。
然后,通过Ticks,没隔俩个语句,就去查询一次消息队列。
然后模拟了消息发送。
在浏览器访问这个脚本,结果如下:

Process got a new incoming MSG: s:19:"Hi: Now Index is :5";
Process got a new incoming MSG: s:20:"Hi: Now Index is :10";
Process got a new incoming MSG: s:20:"Hi: Now Index is :15";
Process got a new incoming MSG: s:20:"Hi: Now Index is :20";
Process got a new incoming MSG: s:20:"Hi: Now Index is :25";
Process got a new incoming MSG: s:20:"Hi: Now Index is :30";
Process got a new incoming MSG: s:20:"Hi: Now Index is :35";
Process got a new incoming MSG: s:20:"Hi: Now Index is :40";
Process got a new incoming MSG: s:20:"Hi: Now Index is :45";
Process got a new incoming MSG: s:20:"Hi: Now Index is :50";
Process got a new incoming MSG: s:20:"Hi: Now Index is :55";
Process got a new incoming MSG: s:20:"Hi: Now Index is :60";
Process got a new incoming MSG: s:20:"Hi: Now Index is :65";
Process got a new incoming MSG: s:20:"Hi: Now Index is :70";
Process got a new incoming MSG: s:20:"Hi: Now Index is :75";
Process got a new incoming MSG: s:20:"Hi: Now Index is :80";
Process got a new incoming MSG: s:20:"Hi: Now Index is :85";
Process got a new incoming MSG: s:20:"Hi: Now Index is :90";
Process got a new incoming MSG: s:20:"Hi: Now Index is :95";

看到这里是不是,大家已经对怎么模拟PHP为事件驱动已经有了一个概念了? 别急,我们继续完善。

2. 信号量
信号量的概念,大家应该都很熟悉。通过信号量,可以实现进程通信,竞争等。 再次就不赘述了,只是简单的列出PHP中提供的信号量函数集。

sem_acquire -- Acquire a semaphore
sem_get -- Get a semaphore id
sem_release -- Release a semaphore
sem_remove -- Remove a semaphore

具体信息,可以翻阅PHP手册。

3. 内存共享
PHP sysvshm提供了一个内存共享方案:sysvshm,它是和sysvsem,sysvmsg一个系列的,但在此处,我并没有使用它,我使用的shmop系列函数,结合TIcks

function memoryUsage(){
 printf("%s: %s<br/>", date("H:i:s", $now), memory_get_usage());
 //var_dump(debug_backtrace());
 //var_dump(__FUNCTION__);
 //debug_print_backtrace();
}
register_tick_function("memoryUsage");
declare(ticks=1){
$shm_key = ftok(__FILE__, 's');
$shm_id = shmop_open($shm_key, 'c', 0644, 100);
}
printf("Size of Shared Memory is: %s<br/>", shmop_size($shm_id));
$shm_text = shmop_read($shm_id, 0, 100);
eval($shm_text);
if(!empty($share_array)){
 var_dump($share_array);
 $share_array['id'] += 1;
}else{
 $share_array = array('id' => 1);
}
$out_put_str = "$share_array = " . var_export($share_array, true) .";";
$out_put_str = str_pad($out_put_str, 100, " ", STR_PAD_RIGHT);
shmop_write($shm_id, $out_put_str, 0);
?>

运行这个例子,不断刷新,我们可以看到index在递增。
单单使用这个shmop就能完成一下,PHP脚本之间共享数据的功能:以及,比如缓存,计数等等。
未完待续

53 Comments

  1. iamwilliam
    iamwilliam November 16, 2022

    <?php

    function getStatus($arg)
    {
    print_r(connection_status());
    debug_print_backtrace();
    }

    register_tick_function("getStatus", true);

    declare(ticks=1) {
    for ($i = 1; $i < 999; $i++) {
    echo "hello";
    }
    }
    unregister_tick_function("getStatus");

    文中,有语法/拼写错误,应该为:
    print_r(connection_status());
    register_tick_function("getStatus", true);

  2. Zhanghui Ming
    Zhanghui Ming December 17, 2018

    这个需要哪些扩展?还有php版本最小是多少?

  3. 超人気ブランドコピーN級品激安通販専門店
    ブランドコピーブランド優良店、偽物時計n級品海外激安通販専門店!
    ロレックス、ウブロをはじめとした、
    様々なブランドコピー時計の販売・
    サイズ調整をご 提供しております。
    ブランドコピーなら当店で!
    N品激安通販専門店 http://www.giginza.com

  4. If you are going for best contents like me, just pay a quick visit this web page everyday because it offers feature contents, thanks

  5. Zoe Collins
    Zoe Collins January 31, 2015

    brilliant use of language in the piece, it really did help when i was
    reading

  6. Brooklyn Jenkins
    Brooklyn Jenkins January 30, 2015

    fantastic usage of vocabulary within the piece, it really did help when i was surfing around

  7. Luke Collins
    Luke Collins January 27, 2015

    I hate reading extensive articles, only as i have got some
    dislexia, but i really liked this article

  8. Alexander Garcia
    Alexander Garcia January 24, 2015

    At the least this is more informative than one of the reality TV stars, kim who?
    Joey what?

  9. Hannah
    Hannah January 14, 2015

    wonderful issues altogether, you just won a emblem new reader.
    What could you suggest in regards to your submit that you simply made some days in the past?
    Any certain?
    web page (Hannah)

  10. Owen Long
    Owen Long December 5, 2014

    At the least it’s more enlightening than one of the reality TV stars, kim who?
    Joey what?

  11. Elizabeth Davis
    Elizabeth Davis November 30, 2014

    One of the outstanding pieces i have read in the week.

  12. Zoe Thomas
    Zoe Thomas November 30, 2014

    This has to be my second favorite piece in the week, i’m not able to’t
    inform you number one, it may offend you!

  13. Ava Jackson
    Ava Jackson November 17, 2014

    At the least it is more instructive than one of our reality TV stars,
    kim who? Joey what?

  14. Jacob Powell
    Jacob Powell October 17, 2014

    Hi, important suggestion and an interesting article post, it’s going to be exciting if this is still the situation in a few years time

  15. fifa 14 hack rar password
    fifa 14 hack rar password October 1, 2014

    Have you ever considered publishing an e-book or guest authoring on other
    sites? I have a blog centered on the same ideas you discuss and would really like to
    have you share some stories/information. I know my audience would value your work.
    If you’re even remotely interested, feel free to shoot me an e-mail.

  16. Anna Cole
    Anna Cole September 19, 2014

    Hi, great advice and an fascinating post, it
    is going to be interesting if this is still the case in a few
    years time

  17. swing copters hack
    swing copters hack August 27, 2014

    Rather than wait here for all eternity, and nothing to be changed,
    you should take a gambit and make the trade. An intern in a hospital is dispatched to the
    morgue located in the basement of the building.
    This year’s Lunar Revel reveals three new lively and
    limited time celebratory skins.
    My web site swing copters hack

  18. Sofia Adams
    Sofia Adams August 24, 2014

    I seldom comment on these posts, but I thought this on deserved a well done you

  19. Luke Williams
    Luke Williams August 8, 2014

    Exceptionally fascinating critique

  20. Ryan Rogers
    Ryan Rogers August 8, 2014

    Magnificent Read, I enjoyed the communication for all literacy section

  21. Sophia Lewis
    Sophia Lewis August 6, 2014

    Awfully exciting short article

  22. 小路
    小路 April 3, 2014

    貌似ticks是在php5.3.0引入的吧

  23. infoqta
    infoqta October 11, 2013

    呵呵, 事半功倍…

  24. Having read this I thought it was really enlightening.
    I appreciate you finding the time and effort to put
    this informative article together. I once again find myself personally spending a
    significant amount of time both reading and commenting.
    But so what, it was still worthwhile!

  25. Chatroulette
    Chatroulette July 1, 2013

    Thanks to my father who shared with me on the topic of this weblog, this web site is really amazing.

  26. I am really inspired with your writing skills as
    smartly as with the structure for your weblog. Is this a
    paid subject matter or did you customize it your self? Either way keep up the nice
    quality writing, it is rare to peer a great blog like
    this one today..

  27. Marianne
    Marianne June 16, 2013

    Thanks for sharing your thoughts. I really appreciate
    your efforts and I am waiting for your next write ups thanks once again.

  28. Electronic cigarettes
    Electronic cigarettes June 15, 2013

    Just want to say your article is as astounding. The clarity in your post is
    simply great and i can assume you are an expert on this subject.
    Well with your permission allow me to grab your RSS
    feed to keep up to date with forthcoming post. Thanks a million and please keep up the rewarding work.

  29. hcg 1234
    hcg 1234 June 15, 2013

    I don’t know if it’s just me or if perhaps everyone else encountering problems with your blog.
    It looks like some of the text in your posts are running
    off the screen. Can someone else please provide feedback
    and let me know if this is happening to them too?
    This may be a problem with my browser because I’ve had this happen previously. Thanks

  30. young
    young November 5, 2012

    ticks 指令在 PHP 5.3.0 中是过时指令,将会从 PHP 6.0.0 移除。

  31. 坐坐吧
    坐坐吧 March 27, 2012

    小错误:文章开头“事半功倍”,呵呵

    • hellozq
      hellozq August 5, 2022

      哈哈,发现鸟哥的小bug

  32. comeon
    comeon January 5, 2012

    这个可以用来发送邮件吗?如果不能,如果想批量发送邮件,怎么样实现呢?请教!

  33. bobo
    bobo December 29, 2010

    我的项目中,用sysvshm实现了本地缓存数据共享,其实主要目的就是避开memcache的网络连接那一步,

  34. leeon
    leeon December 21, 2010

    ipc:信号量,共享内存,消息队列。

  35. phpzxh
    phpzxh December 20, 2010

    Call to undefined function msg_stat_queue()
    报这个函数未定义。
    是不是在windos下用不了?

  36. 商洛SEO
    商洛SEO December 17, 2010

    学习了哈~!

  37. tz
    tz July 20, 2010

    文中所说的消息队列是linux系统本身的那个消息队列吧

  38. jackie
    jackie June 28, 2010

    怎么没有下文了?我最近在学习多线程。。。感觉有点晕。。。
    博主牛人啊,先在雅虎后在百度,不知现在在哪里高就呢?
    向你学习~

  39. […] 传统的B/S结构的应用程序,都是采用”客户端拉”结束来实现客户端和服务器端的数据交换。 本文将通过结合Ticks(可以参看我的另外一篇文章:关于PHP你可能不知道的-PHP的事件驱动化设计),来实现一个服务器推的PHP聊天室简单构想。 […]

  40. Rodin
    Rodin December 2, 2008

    hi
    SYSVSHM, SYSVSEM, SYSVMSG就是
    shm_* sem_* , msg_* 系列函数是吧?
    另,php_event.dll这个是什么东西?有研究过么?

    • 雪候鸟
      雪候鸟 December 2, 2008

      @Rodin, 恩, php_event.dll是 Pecl中event包的win32版本。
      要是使用这个那就更方便了,呵呵。

  41. Rodin
    Rodin November 21, 2008

    哇,好东西唉~~从来没看过这些呢~
    拜一拜博主~~学习SHM和SEM中……

  42. Bun Wong
    Bun Wong November 17, 2008

    为什么我用了 register_tick_function 设置回调并且 declare(ticks = 1) 后,页面就提示 apache 错误了?救命。。。

  43. 雪候鸟
    雪候鸟 August 31, 2008

    呵呵, 事半功倍…

  44. ssword
    ssword August 31, 2008

    巧妙的运用它们,可以让你事倍功半。
    —————————————
    为什么要事倍功半丫 ,囧

Comments are closed.