ホームページ  >  記事  >  バックエンド開発  >  PHP-CLI Webサーバー

PHP-CLI Webサーバー

WBOY
WBOYオリジナル
2016-07-25 08:47:371132ブラウズ
実行するには 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 ランタイム環境はマルチスレッドをサポートしていません' );
  5. exit(0);
  6. }
  7. if(!function_exists('mime_content_type')) {
  8. logs('PHP ランタイム環境は function mime_content_type() をサポートしていません');
  9. exit(0);
  10. }
  11. class pthread はスレッドを拡張します {
  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 =ソケット_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 .=ソケット_read($connfd, 1024, PHP_BINARY_READ) ))
  35. if(strpos ($buffer, "rnrn") !== false) Break;
  36. if($buffer == '') {
  37. ソケット_クローズ($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, '日付: '. gmtdate());
  46. array_push($headers, 'サーバー: PHP-CLI/1.0');
  47. array_push($headers, 'Content-Type: text/html; charset=utf-8');
  48. array_push($headers , '接続: 閉じる');
  49. if($this->arguments['ServerTokens'] == 'on')
  50. $headers[2] = 'サーバー: PHP-CLI';
  51. $buffer = 爆発("rn", $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-Range: 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] = "接続: キープアライブ";
  94. $headers[5] = 'キープアライブ: timeout='.$timeout.', max='.$maxRequests;
  95. }
  96. $headers[6] = 'コンテンツの長さ: '。 strlen($html);
  97. $response = array(
  98. 'header'=> implode("rn", $headers) . "rn",
  99. 'html'=> $html);
  100. socket_write($connfd, implode("rn ", $response));
  101. if($availableRequests ソケットクローズ($connfd);
  102. $session = 0;
  103. }
  104. $length = strlen($html);
  105. socket_getpeername($connfd, $address, $port);
  106. logs(sprintf('%s:%.0f -- "%s %s %s" %s % .0f "-" "%s"',
  107. $address,
  108. $port,
  109. $http_request_method,
  110. '/'.$http_request_file,
  111. $http_protocol,
  112. $code,
  113. $length,
  114. $http_user_agent));
  115. //logs('times '. intval($clients - 1), false);
  116. }
  117. }
  118. }
  119. public function error_page($statusCode, $ServerTokens) {
  120. $httpStatus = array('403'= > '403 禁止', '404'=> '404 が見つかりません');
  121. $string = "
  122. %s
  123. %s

    gt;

  124. %s
  125. ";
  126. if(!in_array($ServerTokens, array('on', 'off')))
  127. $ServerTokens = 'off';
  128. return (string) sprintf($string,
  129. $httpStatus[$statusCode],
  130. $httpStatus[$statusCode],
  131. $ServerTokens == 'off' ? 'PHP-CLI/1.0' : 'PHP-CLI');
  132. }
  133. public function HttpStatusCode($file) , &$headers, &$html, &$code) {
  134. $code = '200';
  135. if(!file_exists($file)) {
  136. $headers[0] = 'HTTP/1.1 404 が見つかりません';
  137. $html = $this->error_page('404', $this->arguments['ServerTokens']);
  138. $code = '404';
  139. return 0;
  140. }
  141. if(is_dir($file) )){
  142. $find = false;
  143. $directoryIndex = $this->arguments['DirectoryIndex'];
  144. if(empty($directoryIndex)) {
  145. $headers[0] = 'HTTP/1.1 403 禁止';
  146. $code = '403';
  147. }else{
  148. $list =explode(' ', $directoryIndex);
  149. foreach($list as $index) {
  150. if(file_exists($file .'/'. $index)) {
  151. $file .= '/'。 $index;
  152. if(file_exists($file) && is_file($file))
  153. $extension = pathinfo($file, PATHINFO_EXTENSION);
  154. $array_key_exists = array_key_exists($extension, $this->arguments['MimeTypes'] );
  155. if($array_key_exists) {
  156. $mime_types = $this->arguments['MimeTypes'][$extension];
  157. }else{
  158. $this->otect_stream = true;
  159. $headers[3] = sprintf('Content-Type: application/octet-stream');
  160. array_push($headers, 'Accept-Ranges: bytes');
  161. array_push($headers, 'Accept-Length: '.filesize($local_request_file));
  162. array_push($headers, 'Content-Disposition:attachment; filename='.basename($local_request_file));
  163. }
  164. $find = true;
  165. Break;
  166. }
  167. }
  168. }
  169. if(!$find) {
  170. $html = $this->error_page('403', $this->arguments['ServerTokens']);
  171. }else{
  172. if(!$this->octet_stream)
  173. $headers[3] = sprintf('Content-Type: %s; charset=%s', $mime_types, 'utf-8');
  174. $html = $this->get_local_handle_buffer($file);
  175. }
  176. return -1;
  177. }else{
  178. $html = $this->get_local_handle_buffer($file);
  179. }
  180. return 1;
  181. }
  182. public function get_local_handle_buffer($file) {
  183. $handle = fopen($file, ' rb');
  184. return $this->get_buffer($handle);
  185. }
  186. public function get_buffer($handle) {
  187. $buffer = '';
  188. if(!is_resource($handle)) return null;
  189. while(!feof($handle))
  190. $buffer .= fgets($handle, 1024);
  191. fclose($handle);
  192. return $buffer;
  193. }
  194. }
  195. function gmtdate() {
  196. return (string) ) date('D, d M Y H:i:s')。 ' GMT';
  197. }
  198. function logs($string, $perfix = true) {
  199. ob_start();
  200. echo $perfix ?
  201. sprintf("[ %s ] %sn", date('d-M-Y H:i:s'), $string) :
  202. sprintf(" [ %s ]n", $string);
  203. ob_end_flush();
  204. }
  205. $mime_types = array(
  206. 'htm'=> 'text/html',
  207. 'html'=> 'text/html',
  208. 'jpg'=> 'image/jpeg',
  209. 'jpeg' => '画像/jpeg',
  210. 'png'=> '画像/png',
  211. 'css'=> xml'=> 'text/xml');
  212. $conf = array(
  213. 'MimeTypes'=> $mime_types,
  214. 'ServerTokens'=> 'on',
  215. 'MaxRequests'=> 100,
  216. 'タイムアウト'=> 15,
  217. 'Listen'=> '/home/www',
  218. 'DirectoryIndex'=> error_reporting(E_ALL);
  219. logs('動作環境の初期化');
  220. sleep(1);
  221. set_time_limit(0);
  222. logs('PHP-CLI実行タイムアウトの初期化');
  223. sleep(1);
  224. $socket =ソケット_create(AF_INET, SOCK_STREAM, SOL_TCP);
  225. logs('ソケットの初期化');
  226. sleep(1);
  227. logs('初期化バインドローカルアドレス任意のIPアドレス');
  228. sleep(1);
  229. $int =ソケット_バインド($socket, '0.0.0.0', $conf['Listen']);
  230. logs('初期化バインドローカルポート'.$conf['Listen']);
  231. if(!$int) {
  232. logs($conf['Listen'].' ポートは他のサービスによって占有されています'."n");
  233. exit(0);
  234. }
  235. sleep(1);
  236. socket_listen($socket, 1024);
  237. logs('ソケットをリッスンしている');
  238. sleep(1);
  239. logs('クライアントのアクセスを待機中');
  240. echo "n";
  241. $i = 0;
  242. while(1) {
  243. $pthread[$i] = new pthread($socket, $conf);
  244. $pthread[$i]->start();
  245. $pthread[$i]->join();
  246. }
  247. 复制幣
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。