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一些服务器端特性的配置加强php的安全
Oct 09 PHP
建立动态的WML站点(三)
Oct 09 PHP
php cout&amp;lt;&amp;lt;的一点看法
Jan 24 PHP
PHP下利用header()函数设置浏览器缓存的代码
Sep 01 PHP
怎样使用php与jquery设置和读取cookies
Aug 08 PHP
php使用反射插入对象示例分享
Mar 11 PHP
php更新mysql后获取改变行数的方法
Dec 25 PHP
php绘制一个矩形的方法
Jan 24 PHP
ThinkPHP中where()使用方法详解
Apr 19 PHP
遍历echsop的region表形成缓存的程序实例代码
Nov 01 PHP
YII2框架中使用RBAC对模块,控制器,方法的权限控制及规则的使用示例
Mar 18 PHP
Laravel框架源码解析之模型Model原理与用法解析
May 14 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中__get()和__set()的用法实例详解
2013/06/04 PHP
微信红包随机生成算法php版
2016/07/21 PHP
PHP PDOStatement::fetch讲解
2019/01/31 PHP
Jquery升级新版本后选择器的语法问题
2010/06/02 Javascript
js计算精度问题小结
2013/04/22 Javascript
自定义函数实现IE7与IE8不兼容js中trim函数的问题
2015/02/03 Javascript
nodejs通过phantomjs实现下载网页
2015/05/04 NodeJs
基于javascript实现图片懒加载
2016/01/05 Javascript
浅谈js中的in-for循环
2016/06/28 Javascript
图文详解JavaScript的原型对象及原型链
2016/08/02 Javascript
JavaScript中定义对象原型的两种使用方法
2016/12/15 Javascript
详谈$.data()的用法和作用
2017/02/13 Javascript
Vuex之理解state的用法实例
2017/04/19 Javascript
详解Vue2.0之去掉组件click事件的native修饰
2017/04/20 Javascript
详解使用Node.js 将txt文件转为Excel文件
2017/07/05 Javascript
用Vue.extend构建消息提示组件的方法实例
2017/08/08 Javascript
angularJS实现动态添加,删除div方法
2018/02/27 Javascript
详解Nodejs mongoose
2018/06/10 NodeJs
js嵌套的数组扁平化:将多维数组变成一维数组以及push()与concat()区别的讲解
2019/01/19 Javascript
用Golang运行JavaScript的实现示例
2019/11/25 Javascript
微信小程序实现菜单左右联动
2020/05/19 Javascript
[02:56]DOTA2英雄基础教程 巨魔战将
2013/12/10 DOTA
[02:02]特效爆炸!DOTA2珍宝之瓶待你开启
2018/08/21 DOTA
Python循环语句中else的用法总结
2016/09/11 Python
基于python判断目录或者文件代码实例
2019/11/29 Python
python进行二次方程式计算的实例讲解
2020/12/06 Python
怎样建立和理解非常复杂的声明?例如定义一个包含N 个指向返回 指向字符的指针的函数的指针的数组?
2013/03/19 面试题
运动会领导邀请函
2014/01/10 职场文书
机械个人求职信范文
2014/01/24 职场文书
环境监测与治理技术专业求职信
2014/07/06 职场文书
十佳少先队员演讲稿
2014/09/12 职场文书
大学新生军训自我鉴定范文
2014/09/13 职场文书
2014最新开业庆典策划方案(5篇)
2014/09/15 职场文书
学生党员批评与自我批评
2014/10/15 职场文书
2016大一新生军训感言
2015/12/08 职场文书
Navicat for MySQL的使用教程详解
2021/05/27 MySQL