PHP编写daemon process 实例详解


Posted in PHP onNovember 13, 2016

PHP编写daemon process

今天下午在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&amp;mysql(三)
Oct 09 PHP
php下的权限算法的实现
Apr 28 PHP
深入分析php中接口与抽象类的区别
Jun 08 PHP
zend optimizer在wamp的基础上安装图文教程
Oct 26 PHP
PHP数据库万能引擎类adodb配置使用以及实例集锦
Jun 12 PHP
3种php生成唯一id的方法
Nov 23 PHP
php session实现多级目录存放实现代码
Feb 03 PHP
PHP上传图片类显示缩略图功能
Jun 30 PHP
thinkPHP分组后模板无法加载问题解决方法
Jul 12 PHP
浅析Laravel5中队列的配置及使用
Aug 04 PHP
小程序微信退款功能实现方法详解【基于thinkPHP】
May 05 PHP
微信推送功能实现方式图文详解
Jul 12 PHP
php版微信小店API二次开发及使用示例
Nov 12 #PHP
PHP Mysqli 常用代码集合
Nov 12 #PHP
PHP版微信小店接口开发实例
Nov 12 #PHP
PHP错误和异常处理功能模块示例
Nov 12 #PHP
php版微信小店调用api示例代码
Nov 12 #PHP
php实用代码片段整理
Nov 12 #PHP
php中strlen和mb_strlen用法实例分析
Nov 12 #PHP
You might like
超级好用的一个php上传图片类(随机名,缩略图,加水印)
2010/06/30 PHP
PHP通过API获取手机号码归属地
2015/05/28 PHP
详解Laravel视图间共享数据与视图Composer
2016/08/04 PHP
jquery 必填项判断表单是否为空的方法
2008/09/14 Javascript
javascript控制frame,iframe的src属性代码
2009/12/31 Javascript
js鼠标左右键 键盘值小结
2010/06/11 Javascript
jQuery中contents()方法用法实例
2015/01/08 Javascript
浅谈jQuery中的eq()与DOM中element.[]的区别
2016/10/28 Javascript
JQuery 动态生成Table表格实例代码
2016/12/02 Javascript
js简易版购物车功能
2017/06/17 Javascript
详解Vue CLI3配置解析之css.extract
2018/09/14 Javascript
ng-repeat指令在迭代对象时的去重方法
2018/10/02 Javascript
node.js ws模块搭建websocket服务端的方法示例
2019/04/25 Javascript
详解小程序毫秒级倒计时(适用于拼团秒杀功能)
2019/05/05 Javascript
解决vue项目中页面调用数据 在数据加载完毕之前出现undefined问题
2019/11/14 Javascript
ES6箭头函数和扩展实例分析
2020/05/23 Javascript
Python中的字典与成员运算符初步探究
2015/10/13 Python
Python计算字符宽度的方法
2016/06/14 Python
Python3.4学习笔记之常用操作符,条件分支和循环用法示例
2019/03/01 Python
python psutil模块使用方法解析
2019/08/01 Python
python实现两个一维列表合并成一个二维列表
2019/12/02 Python
在Python中使用MongoEngine操作数据库教程实例
2019/12/03 Python
html5文本内容_动力节点Java学院整理
2017/07/11 HTML / CSS
HTML5头部标签的一些常用信息小结
2016/10/23 HTML / CSS
HTML5基于flash实现播放RTMP协议视频的示例代码
2020/12/04 HTML / CSS
阿里健康大药房:阿里自营网上药店
2017/08/01 全球购物
中国茶叶、茶具一站式网上购物商城:醉品茶城
2018/07/03 全球购物
Sarenza德国:法国最大的时尚鞋和包包网上商店
2019/06/08 全球购物
C++:memset ,memcpy和strcpy的根本区别
2013/04/27 面试题
简述DNS进行域名解析的过程
2013/12/02 面试题
商务主管岗位职责
2013/12/08 职场文书
党员2014两会学习心得体会
2014/03/17 职场文书
横幅标语大全
2014/06/17 职场文书
党员个人自我剖析材料
2014/10/08 职场文书
委托书的样本
2015/01/28 职场文书
售后服务质量承诺书
2015/04/29 职场文书