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 相关文章推荐
dede3.1分页文字采集过滤规则详说(图文教程)续二
Apr 03 PHP
php模拟ping命令(php exec函数的使用方法)
Oct 25 PHP
PHP 5.3和PHP 5.4出现FastCGI Error解决方法
Feb 12 PHP
php实现随机生成易于记忆的密码
Jun 19 PHP
ThinkPHP中数据操作案例分析
Sep 27 PHP
php简单日历函数
Oct 28 PHP
CodeIgniter扩展核心类实例详解
Jan 20 PHP
yii2中的rules 自定义验证规则详解
Apr 19 PHP
PHP依赖注入(DI)和控制反转(IoC)详解
Jun 12 PHP
PHP正则表达式笔记与实例详解
May 09 PHP
php数组函数array_push()、array_pop()及array_shift()简单用法示例
Jan 26 PHP
TP3.2框架分页相关实现方法分析
Jun 03 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
地摊中国 - 珍藏老照片
2020/08/18 杂记
PHP 计算至少是其他数字两倍的最大数的实现代码
2020/05/26 PHP
关于JavaScript的一些看法
2009/05/27 Javascript
javascript 动态修改样式和层叠样式表代码
2010/04/27 Javascript
javascript 精粹笔记
2010/05/09 Javascript
实现点击列表弹出列表索引的两种方式
2013/03/08 Javascript
JQuery+CSS提示框实现思路及代码(纯手工打造)
2013/05/07 Javascript
jquery中通过父级查找进行定位示例
2013/06/28 Javascript
javascript生成随机大小写字母的方法
2014/02/20 Javascript
浅谈Javascript数组的使用
2015/07/29 Javascript
完美解决IE9浏览器出现的对象未定义问题
2016/09/29 Javascript
Angular下H5上传图片的方法(可多张上传)
2017/01/09 Javascript
Angular组件化管理实现方法分析
2017/03/17 Javascript
JavaScript定时器setTimeout()和setInterval()详解
2017/08/18 Javascript
webstrom Debug 调试vue项目的方法步骤
2018/07/17 Javascript
解决node-sass偶尔安装失败的方法小结
2018/12/05 Javascript
nodejs简单抓包工具使用详解
2019/08/23 NodeJs
解决layer.open弹出框不能获取input框的值为空的问题
2019/09/10 Javascript
vue 解决数组赋值无法渲染在页面的问题
2019/10/28 Javascript
Vue 实现显示/隐藏层的思路(加全局点击事件)
2019/12/31 Javascript
JavaScript实现下拉列表
2021/01/20 Javascript
[54:08]LGD女子刀塔学院 DOTA2炼金术士教学
2014/01/09 DOTA
[01:02:10]DOTA2上海特级锦标赛B组小组赛#2 VG VS Fnatic第一局
2016/02/26 DOTA
[05:06]2017亚洲邀请赛DAC回顾片
2017/04/19 DOTA
详解python 发送邮件实例代码
2016/12/22 Python
Python一个简单的通信程序(客户端 服务器)
2019/03/06 Python
不到20行代码用Python做一个智能聊天机器人
2019/04/19 Python
Python模块的制作方法实例分析
2019/12/21 Python
浅谈Django QuerySet对象(模型.objects)的常用方法
2020/03/28 Python
pip已经安装好第三方库但pycharm中import时还是标红的解决方案
2020/10/09 Python
专业销售业务员求职信
2013/11/18 职场文书
新娘父亲婚礼致辞
2014/01/16 职场文书
学习标兵获奖感言
2014/02/20 职场文书
采购求职信
2014/03/17 职场文书
2015年党员岗位承诺书
2015/04/27 职场文书
反腐倡廉影片观后感
2015/06/08 职场文书