PHP编写daemon process详解及实例代码


Posted in PHP onSeptember 30, 2016

今天下午在segmentfault.com看到一个提问,提问标题是“PHP怎么做服务化”,其中问道php是不是只能以web方式调用。其实很多人对PHP的使用场景都有误解,认为php只能用于编写web脚本,实际上,从PHP4开始,php的使用场景早已不限于处理web请求。 从php的架构体系来说,php分为三个层次:sapi、php core和zend engine。php core本身和web没有任何耦合,php通过sapi与其它应用程序通信,例如mod_php就是为apache编写的sapi实现,同样,fpm是一个基于fastcgi协议的sapi实现,这些sapi都是与web server配合用于处理web请求的。但是也有许多sapi与web无关,例如cli sapi可以使得在命令行环境下直接执行php,embed sapi可以将php嵌入其它语言(如Lua)那样。这里我并不打算详细讨论php的架构体系和sapi的话题,只是说明从架构体系角度目前的php早已被设计为支持各种环境,而非为web独有。 除了架构体系的支持外,php丰富的扩展模块也为php在不同环境发挥作用提供了后盾,例如本文要提到的pcntl模块和posix模块配合可以实现基本的进程管理、信号处理等操作系统级别的功能,而sockets模块可以使php具有socket通信的能力。因此php完全可以用于编写类似于shell或perl常做的工具性脚本,甚至是具有server性质的daemon process。 为了展示php如何编写daemon server,我用php编写了一个简单的http server,这个server以daemon process的形式运行。当然,为了把重点放在如何使用php编写daemon,我没有为这个http server实现具体业务逻辑,但它可以监听指定端口,接受http请求并返回给客户端一条固定的文本,整个过程通过socket实现,全部由php编写而成。

代码实例

下面是这个程序的完整代码:

<?php
 
//Accpet the http client request and generate response content.
//As a demo, this function just send "PHP HTTP Server" to client.
function handle_http_request($address, $port)
{
  $max_backlog = 16;
  $res_content = "HTTP/1.1 200 OK
Content-Length: 15
Content-Type: text/plain; charset=UTF-8
 
PHP HTTP Server";
  $res_len = strlen($res_content);
 
  //Create, bind and listen to socket
  if(($socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === FALSE)
  {
    echo "Create socket failed!\n";
    exit;
  }  
 
  if((socket_bind($socket, $address, $port)) === FALSE)
  {
    echo "Bind socket failed!\n";
    exit;
  }
   
  if((socket_listen($socket, $max_backlog)) === FALSE)
  {
    echo "Listen to socket failed!\n";
    exit;
  }
 
  //Loop
  while(TRUE)
  {
    if(($accept_socket = socket_accept($socket)) === FALSE)
    {
      continue;
    }
    else
    {
      socket_write($accept_socket, $res_content, $res_len);  
      socket_close($accept_socket);
    }
  }
}
 
//Run as daemon process.
function run()
{
  if(($pid1 = pcntl_fork()) === 0)
  //First child process
  {
    posix_setsid(); //Set first child process as the session leader.
     
    if(($pid2 = pcntl_fork()) === 0)
    //Second child process, which run as daemon.
    {
      //Replaced with your own domain or address.
      handle_http_request('www.codinglabs.org', 9999); 
    }
    else
    {
      //First child process exit;
      exit;
    }
  }
  else
  {
    //Wait for first child process exit;
    pcntl_wait($status);
  }
}
 
//Entry point.
run();
 
?>

这里我假设各位对Unix环境编程都比较了解,所以不做太多细节的解释,只梳理一下。简单来看,这个程序主要由两个部分组成,handle_http_request函数负责处理http请求,其编写方法与用C编写的tcp server类似:创建socket、绑定、监听,然后通过一个循环处理每个connect过来的客户端,一旦accept到一个连接...

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

PHP 相关文章推荐
phplock(php进程锁) v1.0 beta1
Nov 24 PHP
php+mysql事务rollback&amp;commit示例
Feb 08 PHP
解析php mysql 事务处理回滚操作(附实例)
Aug 05 PHP
php根据操作系统转换文件名大小写的方法
Feb 24 PHP
php中数字0和空值的区别分析
Jun 05 PHP
linux下使用crontab实现定时PHP计划任务失败的原因分析
Jul 05 PHP
PHP的运行机制与原理(底层)
Nov 16 PHP
thinkPHP基于ajax实现的菜单与分页示例
Jul 12 PHP
注释PHP和html混合代码的小技巧(分享)
Nov 03 PHP
thinkPHP简单实现多个子查询语句的方法
Dec 05 PHP
PHP中include()与require()的区别说明
Feb 14 PHP
如何在Mac上通过docker配置PHP开发环境
May 29 PHP
PHP 极验验证码实例讲解
Sep 29 #PHP
php自定义函数转换html标签示例
Sep 29 #PHP
php自定义函数实现汉字转换utf8编码的方法
Sep 29 #PHP
php自定义函数实现二维数组按指定key排序的方法
Sep 29 #PHP
分享一个漂亮的php验证码类
Sep 29 #PHP
你不知道的文件上传漏洞php代码分析
Sep 29 #PHP
PHP的Json中文处理解决方案
Sep 29 #PHP
You might like
php源码加密 仿微盾PHP加密专家(PHPCodeLock)
2010/05/06 PHP
php调用C代码的实现方法
2014/03/11 PHP
46 个非常有用的 PHP 代码片段
2016/02/16 PHP
php数组实现根据某个键值将相同键值合并生成新二维数组的方法
2017/04/26 PHP
js 多种变量定义(对象直接量,数组直接量和函数直接量)
2010/05/24 Javascript
textarea中的手动换行处理的jquery代码
2011/02/26 Javascript
Draggable Elements 元素拖拽功能实现代码
2011/03/30 Javascript
JS动态添加与删除select中的Option对象(示例代码)
2013/12/25 Javascript
使用javascript实现有效时间的控制,并显示将要过期的时间
2014/01/02 Javascript
在Javascript中处理字符串之big()方法的使用
2015/06/08 Javascript
BootStrap无限级分类(无限极分类封装版)
2016/08/26 Javascript
jquery 判断div show的状态实例
2016/12/03 Javascript
深入理解ES6中let和闭包
2018/02/22 Javascript
Koa从零搭建到Api实现项目的搭建方法
2019/07/30 Javascript
Element-Ui组件 NavMenu 导航菜单的具体使用
2019/10/24 Javascript
Vue路由切换页面不更新问题解决方案
2020/07/10 Javascript
jquery实现有过渡效果的tab切换
2020/07/17 jQuery
详解如何使用React Hooks请求数据并渲染
2020/10/18 Javascript
[03:04]2018年国际邀请赛典藏宝瓶&莱恩声望物品展示 片尾有彩蛋
2018/06/04 DOTA
[47:52]DOTA2-DPC中国联赛正赛 iG vs LBZS BO3 第二场 3月4日
2021/03/11 DOTA
基于python神经卷积网络的人脸识别
2018/05/24 Python
Python3模拟curl发送post请求操作示例
2019/05/03 Python
django中账号密码验证登陆功能的实现方法
2019/07/15 Python
解决python3输入的坑——input()
2020/12/05 Python
Python绘制数码晶体管日期
2021/02/19 Python
AJAX都有哪些有点和缺点
2012/11/03 面试题
应届生幼儿园求职信
2013/11/12 职场文书
《庐山的云雾》教学反思
2014/04/22 职场文书
幼儿园六一亲子活动方案
2014/08/26 职场文书
颐和园导游词
2015/01/30 职场文书
2015年世界粮食日演讲稿
2015/03/20 职场文书
商场收银员岗位职责
2015/04/07 职场文书
手术室消毒隔离制度
2015/08/05 职场文书
团队合作精神学习心得体会
2016/01/19 职场文书
python 实现德洛内三角剖分的操作
2021/04/22 Python
用Python爬取某乎手机APP数据
2021/06/15 Python