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 相关文章推荐
多重?l件?合查?(一)
Oct 09 PHP
PHP大批量数据操作时临时调整内存与执行时间的方法
Apr 20 PHP
JS与PHP向函数传递可变参数的区别实例代码
May 18 PHP
php的memcache类分享(memcache队列)
Mar 26 PHP
php获取mysql字段名称和其它信息的例子
Apr 14 PHP
ThinkPHP中的create方法与自动令牌验证实例教程
Aug 22 PHP
php中cookie实现二级域名可访问操作的方法
Nov 11 PHP
全面了解PHP中的全局变量
Jun 17 PHP
PHP入门教程之上传文件实例详解
Sep 11 PHP
PHP基于双向链表与排序操作实现的会员排名功能示例
Dec 26 PHP
swoole_process实现进程池的方法示例
Oct 29 PHP
Laravel创建数据库表结构的例子
Oct 09 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
解析 thinkphp 框架中的部分方法
2017/05/07 PHP
php屏蔽错误及提示的方法
2020/05/10 PHP
一个简单的jQuery插件制作 学习过程及实例
2010/04/25 Javascript
jquery监控数据是否变化(修正版)
2011/04/12 Javascript
javascript游戏开发之《三国志曹操传》零部件开发(四)用地图块拼成大地图
2013/01/23 Javascript
JS加jquery简单实现标签元素的显示或隐藏
2013/09/23 Javascript
js插件YprogressBar实现漂亮的进度条效果
2015/04/20 Javascript
JavaScript 基础函数_深入剖析变量和作用域
2016/05/18 Javascript
vue组件父子间通信详解(三)
2017/11/07 Javascript
10行原生JS实现文字无缝滚动(超简单)
2018/01/02 Javascript
Vue组件开发技巧总结
2018/03/04 Javascript
vue iView 上传组件之手动上传功能
2018/03/16 Javascript
express.js中间件说明详解
2019/03/19 Javascript
Vue中keep-alive 实现后退不刷新并保持滚动位置
2020/03/17 Javascript
js+canvas实现画板功能
2020/09/13 Javascript
[49:35]LGD vs OG 2018国际邀请赛淘汰赛BO3 第二场 8.25
2018/08/29 DOTA
用Python的Django框架完成视频处理任务的教程
2015/04/02 Python
详细介绍Ruby中的正则表达式
2015/04/10 Python
Numpy中stack(),hstack(),vstack()函数用法介绍及实例
2018/01/09 Python
django 使用 request 获取浏览器发送的参数示例代码
2018/06/11 Python
python打包生成的exe文件运行时提示缺少模块的解决方法
2018/10/31 Python
解决在Python编辑器pycharm中程序run正常debug错误的问题
2019/01/17 Python
python中的split()函数和os.path.split()函数使用详解
2019/12/21 Python
解决Python spyder显示不全df列和行的问题
2020/04/20 Python
详解selenium + chromedriver 被反爬的解决方法
2020/10/28 Python
贝玲妃美国官方网站:Benefit美国
2016/08/28 全球购物
幼儿如何来做好自我评价
2013/11/05 职场文书
《金色的脚印》教后反思
2014/04/23 职场文书
民族团结好少年事迹材料
2014/08/19 职场文书
物联网工程专业推荐信
2014/09/08 职场文书
运动会搞笑广播稿
2014/10/14 职场文书
亮剑精神观后感
2015/06/05 职场文书
2019让人心动的商业计划书
2019/06/27 职场文书
Java用自带的Image IO给图片添加水印
2021/06/15 Java/Android
MySQL详解进行JDBC编程与增删改查方法
2022/06/16 MySQL
SQLyog的下载、安装、破解、配置教程(MySQL可视化工具安装)
2022/09/23 MySQL