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 正则学习实例
Jul 30 PHP
PHP Stream_*系列函数
Aug 01 PHP
php中利用post传递字符串重定向的实现代码
Apr 21 PHP
php截取中文字符串不乱码的方法
Dec 25 PHP
zf框架的zend_cache缓存使用方法(zend框架)
Mar 14 PHP
php通过session防url攻击方法
Dec 10 PHP
php序列化函数serialize() 和 unserialize() 与原生函数对比
May 08 PHP
Ajax PHP JavaScript MySQL实现简易无刷新在线聊天室
Aug 17 PHP
PHP文件上传操作实例详解
Sep 27 PHP
PHP 中常量的知识整理
Apr 14 PHP
学习thinkphp5.0验证类使用方法
Nov 16 PHP
php实现解析xml并生成sql语句的方法
Feb 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/07/13 国漫
学习php设计模式 php实现适配器模式
2015/12/07 PHP
PHP/ThinkPHP实现批量打包下载文件的方法示例
2017/07/31 PHP
Redis在Laravel项目中的应用实例详解
2017/08/11 PHP
Mootools 1.2 手风琴(Accordion)教程
2009/09/15 Javascript
JavaScript italics方法入门实例(把字符串显示为斜体)
2014/10/17 Javascript
Javascript前端UI框架Kit使用指南之Kitjs简介
2014/11/28 Javascript
JavaScript DOM事件(笔记)
2015/04/08 Javascript
四种参数传递的形式——URL,超链接,js,form表单
2015/07/24 Javascript
Javascript基础学习笔记(菜鸟必看篇)
2016/07/22 Javascript
浅析Javascript的自动分号插入(ASI)机制
2016/09/29 Javascript
AngularJS出现$http异步后台无法获取请求参数问题的解决方法
2016/11/03 Javascript
基于jQuery实现简单人工智能聊天室
2017/02/10 Javascript
详解nodeJS中读写文件方法的区别
2017/03/06 NodeJs
ES6新特性一: let和const命令详解
2017/04/20 Javascript
JavaScript中splice与slice的区别
2017/05/09 Javascript
原生JS实现日历组件的示例代码
2017/09/22 Javascript
解决vue中el-tab-pane切换的问题
2020/07/19 Javascript
Vue实现点击导航栏当前标签后变色功能
2020/08/19 Javascript
Python中运行并行任务技巧
2015/02/26 Python
django模型层(model)进行建表、查询与删除的基础教程
2017/11/21 Python
使用python采集脚本之家电子书资源并自动下载到本地的实例脚本
2018/10/23 Python
Python 加密与解密小结
2018/12/06 Python
Python Pandas 转换unix时间戳方式
2019/12/07 Python
为什么是 Python -m
2020/06/19 Python
keras使用Sequence类调用大规模数据集进行训练的实现
2020/06/22 Python
应届毕业生应聘自荐信
2013/12/07 职场文书
预防艾滋病宣传标语
2014/06/25 职场文书
法人单位适用的授权委托书
2014/09/19 职场文书
2015年员工试用期工作总结
2014/12/12 职场文书
幼儿园百日安全活动总结
2015/05/07 职场文书
公司开业致辞
2015/07/29 职场文书
《月光曲》教学反思
2016/02/16 职场文书
Python实现制作销售数据可视化看板详解
2021/11/27 Python
Python通过loop.run_in_executor执行同步代码 同步变为异步
2022/04/11 Python
海康机器人重磅发布全新算法开发平台VM4.2
2022/04/21 数码科技