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数组实现无限分类,不使用数据库,不使用递归.
Dec 09 PHP
PHP中的string类型使用说明
Jul 27 PHP
php实现改变图片直接打开为下载的方法
Apr 14 PHP
php实现scws中文分词搜索的方法
Dec 25 PHP
php实现的一段简单概率相关代码
May 30 PHP
thinkphp自带验证码全面解析
Sep 18 PHP
php5.3后静态绑定用法详解
Nov 11 PHP
php防止sql注入的方法详解
Feb 20 PHP
thinkPHP实现签到功能的方法
Mar 15 PHP
PHP实现的简单适配器模式示例
Jun 22 PHP
PHP在同一域名下两个不同的项目做独立登录机制详解
Sep 22 PHP
PHP后期静态绑定之self::限制实例分析
Dec 21 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
UTF8编码内的繁简转换的PHP类
2009/07/09 PHP
深入理解PHP原理之错误抑制与内嵌HTML分析
2011/05/02 PHP
php中利用str_pad函数生成数字递增形式的产品编号
2013/09/30 PHP
laravel 操作数据库常用函数的返回值方法
2019/10/11 PHP
为JS扩展Array.prototype.indexOf引发的问题探讨及解决
2013/04/24 Javascript
js截取固定长度的中英文字符的简单实例
2013/11/22 Javascript
jQuery实现的可编辑表格完整实例
2016/06/20 Javascript
基于jQuery实现滚动切换效果
2016/12/02 Javascript
ReactNative短信验证码倒计时控件的实现代码
2017/07/20 Javascript
VUE实现一个分页组件的示例
2017/09/13 Javascript
妙用缓存调用链实现JS方法的重载
2018/04/30 Javascript
从0到1搭建Element的后台框架的方法步骤
2019/04/10 Javascript
jquery实现Ajax请求的几种常见方式总结
2019/05/28 jQuery
详解vue-template-admin三级路由无法缓存的解决方案
2020/03/10 Javascript
如何在VUE中使用vue-awesome-swiper
2021/01/04 Vue.js
python实现list由于numpy array的转换
2018/04/04 Python
Python使用matplotlib模块绘制图像并设置标题与坐标轴等信息示例
2018/05/04 Python
Pycharm 文件更改目录后,执行路径未更新的解决方法
2019/07/19 Python
python tkinter基本属性详解
2019/09/16 Python
详解使用django-mama-cas快速搭建CAS服务的实现
2019/10/30 Python
flask框架url与重定向操作实例详解
2020/01/25 Python
Django haystack实现全文搜索代码示例
2020/11/28 Python
水上运动奥特莱斯:Wasterports Outlet
2018/08/08 全球购物
夜大毕业生自我评价分享
2013/11/10 职场文书
成功经营餐厅的创业计划书范文
2013/12/26 职场文书
《蚕姑娘》教学反思
2014/04/15 职场文书
奥运会口号
2014/06/13 职场文书
舞蹈兴趣小组活动总结
2014/07/07 职场文书
党员学习新党章思想汇报
2014/10/25 职场文书
学前班语言教学计划
2015/01/20 职场文书
活动费用申请报告
2015/05/15 职场文书
2015年教师业务工作总结
2015/05/26 职场文书
董事长秘书工作总结
2015/08/14 职场文书
phpQuery解析HTML乱码问题(补充官网未列出的乱码解决方案)
2021/04/01 PHP
Python 高级库15 个让新手爱不释手(推荐)
2021/05/15 Python
详解Laravel框架的依赖注入功能
2021/05/27 PHP