0

0

PHP-CLI Web 服务器

php中文网

php中文网

发布时间:2016-07-25 08:47:37

|

1324人浏览过

|

来源于php中文网

原创

需要 pthreads 扩展
php 命令行模式运行

写的比较急,没时间优化,有时间我会抽空优化一下

来自源地址: http://www.haowei.me/archives/1009.html
  1. ini_set('display_errors', false);
  2. error_reporting(0);
  3. if(!class_exists('thread')) {
  4. logs('PHP runtime environment not support multi thread');
  5. exit(0);
  6. }
  7. if(!function_exists('mime_content_type')) {
  8. logs('PHP runtime environment not support function mime_content_type()');
  9. exit(0);
  10. }
  11. class pthread extends thread {
  12. protected $socket = null;
  13. protected $arguments = null;
  14. protected $connections = 0;
  15. protected $octet_stream = false;
  16. public function __construct($socket, $arguments = array()) {
  17. $this->socket = $socket;
  18. $this->arguments = $arguments;
  19. if(!isset($this->arguments['ServerTokens']))
  20. $this->arguments['ServerTokens'] = 'off';
  21. }
  22. public function run() {
  23. date_default_timezone_set('UTC');
  24. $clients = 1;
  25. $maxRequests = !isset($this->arguments['MaxRequests'])?
  26. intval($this->arguments['MaxRequests']):
  27. 100;
  28. $timeout = 5;
  29. $connfd = socket_accept($this->socket);
  30. socket_set_option($connfd, SOL_SOCKET, SO_RCVTIMEO, array('sec' => $timeout, 'usec' => 0));
  31. $session = 1;
  32. while($session) {
  33. $buffer = '';
  34. while (( $buffer .= socket_read($connfd, 1024, PHP_BINARY_READ) ))
  35. if(strpos($buffer, " ") !== false) break;
  36. if($buffer == '') {
  37. socket_close($connfd);
  38. $session = 0;
  39. }else{
  40. $availableRequests = $maxRequests - $clients;
  41. $clients++;
  42. $i = 0;
  43. $headers = array();
  44. array_push($headers, 'HTTP/1.1 200 OK');
  45. array_push($headers, 'Date: '. gmtdate());
  46. array_push($headers, 'Server: PHP-CLI/1.0');
  47. array_push($headers, 'Content-Type: text/html; charset=utf-8');
  48. array_push($headers, 'Connection: close');
  49. if($this->arguments['ServerTokens'] == 'on')
  50. $headers[2] = 'Server: PHP-CLI';
  51. $buffer = explode(" ", $buffer);
  52. $http_user_agent = '';
  53. $http_request_method = '';
  54. $http_request_file = '';
  55. $http_protocol = '';
  56. $extension = '';
  57. $mime_types = '';
  58. $this->octet_stream = false;
  59. foreach($buffer as $line) {
  60. $pattern = '/(GET|POST)s/(.*)s(HTTP/1.[0-1])$/';
  61. if(preg_match($pattern, $line)) {
  62. $http_request_method = preg_replace($pattern, '\1', $line);
  63. $http_request_file = preg_replace($pattern, '\2', $line);
  64. $http_protocol = preg_replace($pattern, '\3', $line);
  65. }
  66. $pattern = '/^User-Agent: (.+)$/';
  67. if(preg_match($pattern, $line)) {
  68. $http_user_agent = preg_replace($pattern, '\1', $line);
  69. }
  70. }
  71. $local_request_file = $this->arguments['DocumentRoot'].'/'. $http_request_file;
  72. if(file_exists($local_request_file) && is_file($local_request_file))
  73. $extension = pathinfo($local_request_file, PATHINFO_EXTENSION);
  74. if(file_exists($local_request_file)) {
  75. $array_key_exists = array_key_exists($extension, $this->arguments['MimeTypes']);
  76. if(is_file($local_request_file)) {
  77. if($array_key_exists) {
  78. $mime_types = $this->arguments['MimeTypes'][$extension];
  79. $headers[3] = sprintf('Content-Type: %s; charset=%s', $mime_types, 'utf-8');
  80. }else{
  81. $this->octet_stream = true;
  82. $headers[3] = sprintf('Content-Type: application/octet-stream');
  83. array_push($headers, 'Accept-Ranges: bytes');
  84. array_push($headers, 'Accept-Length: '.filesize($local_request_file));
  85. array_push($headers, 'Content-Disposition: attachment; filename='.basename($local_request_file));
  86. }
  87. }
  88. }
  89. $html = '';
  90. $code = '';
  91. $this->HttpStatusCode($local_request_file, $headers, $html, $code);
  92. if($availableRequests > 0) {
  93. $headers[4] = "Connection: keep-alive";
  94. $headers[5] = 'Keep-Alive: timeout='.$timeout.', max='.$maxRequests;
  95. }
  96. $headers[6] = 'Content-Length: '. strlen($html);
  97. $response = array(
  98. 'header'=> implode(" ", $headers) . " ",
  99. 'html'=> $html);
  100. socket_write($connfd, implode(" ", $response));
  101. if($availableRequests
  102. socket_close($connfd);
  103. $session = 0;
  104. }
  105. $length = strlen($html);
  106. socket_getpeername($connfd, $address, $port);
  107. logs(sprintf('%s:%.0f -- "%s %s %s" %s %.0f "-" "%s"',
  108. $address,
  109. $port,
  110. $http_request_method,
  111. '/'.$http_request_file,
  112. $http_protocol,
  113. $code,
  114. $length,
  115. $http_user_agent));
  116. //logs('times '. intval($clients - 1), false);
  117. }
  118. }
  119. }
  120. public function error_page($statusCode, $ServerTokens) {
  121. $httpStatus = array('403'=> '403 Forbidden', '404'=> '404 Not Found');
  122. $string = "
  123. %s
  124. %s


  125. %s
  126. ";
  127. if(!in_array($ServerTokens, array('on', 'off')))
  128. $ServerTokens = 'off';
  129. return (string) sprintf($string,
  130. $httpStatus[$statusCode],
  131. $httpStatus[$statusCode],
  132. $ServerTokens == 'off' ? 'PHP-CLI/1.0' : 'PHP-CLI');
  133. }
  134. public function HttpStatusCode($file, &$headers, &$html, &$code) {
  135. $code = '200';
  136. if(!file_exists($file)) {
  137. $headers[0] = 'HTTP/1.1 404 Not Found';
  138. $html = $this->error_page('404', $this->arguments['ServerTokens']);
  139. $code = '404';
  140. return 0;
  141. }
  142. if(is_dir($file)){
  143. $find = false;
  144. $directoryIndex = $this->arguments['DirectoryIndex'];
  145. if(empty($directoryIndex)) {
  146. $headers[0] = 'HTTP/1.1 403 Forbidden';
  147. $code = '403';
  148. }else{
  149. $list = explode(' ', $directoryIndex);
  150. foreach($list as $index) {
  151. if(file_exists($file .'/'. $index)) {
  152. $file .= '/'. $index;
  153. if(file_exists($file) && is_file($file))
  154. $extension = pathinfo($file, PATHINFO_EXTENSION);
  155. $array_key_exists = array_key_exists($extension, $this->arguments['MimeTypes']);
  156. if($array_key_exists) {
  157. $mime_types = $this->arguments['MimeTypes'][$extension];
  158. }else{
  159. $this->otect_stream = true;
  160. $headers[3] = sprintf('Content-Type: application/octet-stream');
  161. array_push($headers, 'Accept-Ranges: bytes');
  162. array_push($headers, 'Accept-Length: '.filesize($local_request_file));
  163. array_push($headers, 'Content-Disposition: attachment; filename='.basename($local_request_file));
  164. }
  165. $find = true;
  166. break;
  167. }
  168. }
  169. }
  170. if(!$find) {
  171. $html = $this->error_page('403', $this->arguments['ServerTokens']);
  172. }else{
  173. if(!$this->octet_stream)
  174. $headers[3] = sprintf('Content-Type: %s; charset=%s', $mime_types, 'utf-8');
  175. $html = $this->get_local_handle_buffer($file);
  176. }
  177. return -1;
  178. }else{
  179. $html = $this->get_local_handle_buffer($file);
  180. }
  181. return 1;
  182. }
  183. public function get_local_handle_buffer($file) {
  184. $handle = fopen($file, 'rb');
  185. return $this->get_buffer($handle);
  186. }
  187. public function get_buffer($handle) {
  188. $buffer = '';
  189. if(!is_resource($handle)) return null;
  190. while(!feof($handle))
  191. $buffer .= fgets($handle, 1024);
  192. fclose($handle);
  193. return $buffer;
  194. }
  195. }
  196. function gmtdate() {
  197. return (string) date('D, d M Y H:i:s'). ' GMT';
  198. }
  199. function logs($string, $perfix = true) {
  200. ob_start();
  201. echo $perfix ?
  202. sprintf("[ %s ] %s ", date('d-M-Y H:i:s'), $string) :
  203. sprintf("[ %s ] ", $string);
  204. ob_end_flush();
  205. }
  206. $mime_types = array(
  207. 'htm'=> 'text/html',
  208. 'html'=> 'text/html',
  209. 'jpg'=> 'image/jpeg',
  210. 'jpeg'=> 'image/jpeg',
  211. 'png'=> 'image/png',
  212. 'js'=> 'text/javascript',
  213. 'css'=> 'text/css',
  214. 'xml'=> 'text/xml');
  215. $conf = array(
  216. 'MimeTypes'=> $mime_types,
  217. 'ServerTokens'=> 'on',
  218. 'MaxRequests'=> 100,
  219. 'Timeout'=> 15,
  220. 'Listen'=> 8080,
  221. 'DocumentRoot'=> '/home/www',
  222. 'DirectoryIndex'=> 'index.htm index.html');
  223. error_reporting(E_ALL);
  224. logs('Initializing the operating environment');
  225. sleep(1);
  226. set_time_limit(0);
  227. logs('Initializing PHP-CLI execution timeout');
  228. sleep(1);
  229. $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
  230. logs('Initializing the socket');
  231. sleep(1);
  232. logs('Initialization bind local address any ip address');
  233. sleep(1);
  234. $int = socket_bind($socket, '0.0.0.0', $conf['Listen']);
  235. logs('Initialization bind local port '.$conf['Listen']);
  236. if(!$int){
  237. logs($conf['Listen'].' Port is occupied by other services'." ");
  238. exit(0);
  239. }
  240. sleep(1);
  241. socket_listen($socket, 1024);
  242. logs('Opening a socket listening');
  243. sleep(1);
  244. logs('Waiting for clients to access');
  245. echo " ";
  246. $i = 0;
  247. while(1) {
  248. $pthread[$i] = new pthread($socket, $conf);
  249. $pthread[$i]->start();
  250. $pthread[$i]->join();
  251. }
复制代码


相关文章

PHP速学教程(入门到精通)
PHP速学教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

1044

2026.02.13

微博网页版主页入口与登录指南_官方网页端快速访问方法
微博网页版主页入口与登录指南_官方网页端快速访问方法

本专题系统整理微博网页版官方入口及网页端登录方式,涵盖首页直达地址、账号登录流程与常见访问问题说明,帮助用户快速找到微博官网主页,实现便捷、安全的网页端登录与内容浏览体验。

334

2026.02.13

Flutter跨平台开发与状态管理实战
Flutter跨平台开发与状态管理实战

本专题围绕Flutter框架展开,系统讲解跨平台UI构建原理与状态管理方案。内容涵盖Widget生命周期、路由管理、Provider与Bloc状态管理模式、网络请求封装及性能优化技巧。通过实战项目演示,帮助开发者构建流畅、可维护的跨平台移动应用。

213

2026.02.13

TypeScript工程化开发与Vite构建优化实践
TypeScript工程化开发与Vite构建优化实践

本专题面向前端开发者,深入讲解 TypeScript 类型系统与大型项目结构设计方法,并结合 Vite 构建工具优化前端工程化流程。内容包括模块化设计、类型声明管理、代码分割、热更新原理以及构建性能调优。通过完整项目示例,帮助开发者提升代码可维护性与开发效率。

35

2026.02.13

Redis高可用架构与分布式缓存实战
Redis高可用架构与分布式缓存实战

本专题围绕 Redis 在高并发系统中的应用展开,系统讲解主从复制、哨兵机制、Cluster 集群模式及数据分片原理。内容涵盖缓存穿透与雪崩解决方案、分布式锁实现、热点数据优化及持久化策略。通过真实业务场景演示,帮助开发者构建高可用、可扩展的分布式缓存系统。

111

2026.02.13

c语言 数据类型
c语言 数据类型

本专题整合了c语言数据类型相关内容,阅读专题下面的文章了解更多详细内容。

77

2026.02.12

雨课堂网页版登录入口与使用指南_官方在线教学平台访问方法
雨课堂网页版登录入口与使用指南_官方在线教学平台访问方法

本专题系统整理雨课堂网页版官方入口及在线登录方式,涵盖账号登录流程、官方直连入口及平台访问方法说明,帮助师生用户快速进入雨课堂在线教学平台,实现便捷、高效的课程学习与教学管理体验。

17

2026.02.12

豆包AI网页版入口与智能创作指南_官方在线写作与图片生成使用方法
豆包AI网页版入口与智能创作指南_官方在线写作与图片生成使用方法

本专题汇总豆包AI官方网页版入口及在线使用方式,涵盖智能写作工具、图片生成体验入口和官网登录方法,帮助用户快速直达豆包AI平台,高效完成文本创作与AI生图任务,实现便捷智能创作体验。

813

2026.02.12

PostgreSQL性能优化与索引调优实战
PostgreSQL性能优化与索引调优实战

本专题面向后端开发与数据库工程师,深入讲解 PostgreSQL 查询优化原理与索引机制。内容包括执行计划分析、常见索引类型对比、慢查询优化策略、事务隔离级别以及高并发场景下的性能调优技巧。通过实战案例解析,帮助开发者提升数据库响应速度与系统稳定性。

97

2026.02.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Python 教程
Python 教程

共137课时 | 10万人学习

PHP课程
PHP课程

共137课时 | 12.3万人学习

Java 教程
Java 教程

共578课时 | 70.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号