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 相关文章推荐
PHP在XP下IIS和Apache2服务器上的安装
Sep 05 PHP
php 获取可变函数参数的函数
Aug 26 PHP
PHP+Mysql+jQuery实现发布微博程序 jQuery篇
Oct 08 PHP
php数组函数序列之ksort()对数组的元素键名进行升序排序,保持索引关系
Nov 02 PHP
利用PHP生成静态HTML文档的原理
Oct 29 PHP
使用PHP强制下载PDF文件示例
Jan 17 PHP
PHP缓存集成库phpFastCache用法
Dec 15 PHP
PHP实现获取客户端IP并获取IP信息
Mar 17 PHP
php redis实现对200w用户的即时推送
Mar 04 PHP
PHP创建单例后台进程的方法示例
May 23 PHP
laravel 框架执行流程与原理简单分析
Feb 01 PHP
php获取小程序码的实现代码(B类接口)
Jun 13 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下过滤html代码的函数 提高程序安全性
2010/03/02 PHP
PHP 万年历实现代码
2012/10/18 PHP
ZF框架实现发送邮件的方法
2015/12/03 PHP
PHP开发的文字水印,缩略图,图片水印实现类与用法示例
2019/04/12 PHP
JavaScript中的其他对象
2008/01/16 Javascript
js修改原型的属性使用介绍
2014/01/26 Javascript
原生JS实现响应式瀑布流布局
2015/04/02 Javascript
JavaScript的removeChild()函数用法详解
2015/12/27 Javascript
jquery对象和DOM对象的相互转换详解
2016/10/18 Javascript
Bootstrap源码解读下拉菜单(4)
2016/12/23 Javascript
Node.js的Mongodb使用实例
2016/12/30 Javascript
如何用js判断dom是否有存在某class的值
2017/02/13 Javascript
JS仿QQ好友列表展开、收缩功能(第一篇)
2017/07/07 Javascript
JavaScript使用math.js进行精确计算操作示例
2018/06/19 Javascript
vue项目中,main.js,App.vue,index.html的调用方法
2018/09/20 Javascript
vue-cli3全面配置详解
2018/11/14 Javascript
详解vue中在循环中使用@mouseenter 和 @mouseleave事件闪烁问题解决方法
2020/04/07 Javascript
javascript 设计模式之享元模式原理与应用详解
2020/04/08 Javascript
python清除指定目录内所有文件中script的方法
2015/06/30 Python
Python中return语句用法实例分析
2015/08/04 Python
深入解析Python中的lambda表达式的用法
2015/08/28 Python
python下调用pytesseract识别某网站验证码的实现方法
2016/06/06 Python
Python机器学习logistic回归代码解析
2018/01/17 Python
python 定时任务去检测服务器端口是否通的实例
2019/01/26 Python
Ubuntu中配置TensorFlow使用环境的方法
2020/04/21 Python
python如何处理程序无法打开
2020/06/16 Python
python爬取天气数据的实例详解
2020/11/20 Python
python3实现简单飞机大战
2020/11/29 Python
python的setattr函数实例用法
2020/12/16 Python
New Balance波兰官方商城:始于1906年,百年慢跑品牌
2017/08/15 全球购物
马来西亚户外装备商店:PTT Outdoor
2019/07/13 全球购物
企业厂长岗位职责
2013/12/17 职场文书
煤矿安全生产月活动总结
2014/07/05 职场文书
党支部工作总结2015
2015/04/01 职场文书
创业计划书之餐饮馄饨店
2019/07/18 职场文书
oracle delete误删除表数据后如何恢复
2022/06/28 Oracle