> 백엔드 개발 > PHP 튜토리얼 > PHP-CLI 웹 서버

PHP-CLI 웹 서버

WBOY
풀어 주다: 2016-07-25 08:47:37
원래의
1196명이 탐색했습니다.
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. 로그('PHP 런타임 환경은 mime_content_type() 함수를 지원하지 않습니다.');
  9. exit(0);
  10. }
  11. class pthread 확장 스레드 {
  12. protected $ 소켓 = null;
  13. protected $arguments = null;
  14. protected $connections = 0;
  15. protected $octet_stream = false;
  16. 공용 함수 __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. 공용 함수 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('초' => $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. 소켓_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, '날짜: '.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($ 패턴, '\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->인수['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] = "연결: 연결 유지";
  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 <= 0) {
  102. socket_close($connfd);
  103. $session = 0;
  104. }
  105. $length = strlen($html);
  106. 소켓_getpeername($connfd, $address, $port);
  107. 로그(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. 공개 함수 error_page($statusCode, $ServerTokens) {
  121. $httpStatus = array('403'=> '403 금지됨' , '404'=> '404 찾을 수 없음');
  122. $string = "
  123. %s
  124. < /head>
  125. %s

  126. <시간 />
  127. %s< ;/center>
  128. ";
  129. if(!in_array($ServerTokens, array('on', 'off')))
  130. $ServerTokens = 'off';
  131. 반환(문자열) sprintf($string,
  132. $httpStatus[$statusCode],
  133. $httpStatus[$statusCode],
  134. $ServerTokens == '끄다' ? 'PHP-CLI/1.0' : 'PHP-CLI');
  135. }
  136. 공개 함수 HttpStatusCode($file, &$headers, &$html, &$code) {
  137. $code = '200';
  138. if(!file_exists($file)) {
  139. $headers[0] = 'HTTP/1.1 404 찾을 수 없음';
  140. $html = $this ->error_page('404', $this->arguments['ServerTokens']);
  141. $code = '404';
  142. return 0;
  143. }
  144. if( is_dir($file)){
  145. $find = false;
  146. $directoryIndex = $this->arguments['DirectoryIndex'];
  147. if(empty($directoryIndex)) {
  148. $headers [0] = 'HTTP/1.1 403 금지됨';
  149. $code = '403';
  150. }else{
  151. $list = 폭발(' ', $directoryIndex);
  152. foreach($list as $index) {
  153. if(file_exists($file .'/'. $index)) {
  154. $file .= '/'. $index;
  155. if(file_exists($file) && is_file($file))
  156. $extension = pathinfo($file, PATHINFO_EXTENSION);
  157. $array_key_exists = array_key_exists($extension, $this-> 인수['MimeTypes']);
  158. if($array_key_exists) {
  159. $mime_types = $this->arguments['MimeTypes'][$extension];
  160. }else{
  161. $this ->otect_stream = true;
  162. $headers[3] = sprintf('Content-Type: application/octet-stream');
  163. array_push($headers, 'Accept-Ranges: bytes');
  164. array_push($headers, 'Accept-Length: '.filesize($local_request_file));
  165. array_push($headers, 'Content-Disposition: attachment; filename='.basename($local_request_file));
  166. }
  167. $find = true;
  168. break;
  169. }
  170. }
  171. }
  172. if(!$find) {
  173. $html = $this->error_page ('403', $this->arguments['ServerTokens']);
  174. }else{
  175. if(!$this->octet_stream)
  176. $headers[3] = sprintf('Content -유형: %s; charset=%s', $mime_types, 'utf-8');
  177. $html = $this->get_local_handle_buffer($file);
  178. }
  179. 반환 -1;
  180. }else{
  181. $html = $this->get_local_handle_buffer($file);
  182. }
  183. return 1;
  184. }
  185. 공용 함수 get_local_handle_buffer($file) {
  186. $handle = fopen($file, 'rb');
  187. return $this->get_buffer($handle);
  188. }
  189. 공용 함수 get_buffer($handle) {
  190. $buffer = '';
  191. if(!is_resource($handle)) return null;
  192. while(!feof($handle) )
  193. $buffer .= fgets($handle, 1024);
  194. fclose($handle);
  195. return $buffer;
  196. }
  197. }
  198. 함수 gmtdate() {
  199. (문자열) date('D, d M Y H:i:s')를 반환합니다. ' GMT';
  200. }
  201. 함수 로그($string, $perfix = true) {
  202. ob_start();
  203. echo $perfix ?
  204. sprintf("[ %s ] %sn", date('d-M-Y H:i:s'), $string) :
  205. sprintf(" [ %s ]n", $string);
  206. ob_end_flush();
  207. }
  208. $mime_types = array(
  209. 'htm'=> 'text/html',
  210. 'html'=> 'text/html',
  211. 'jpg'=> 'image/jpeg',
  212. 'jpeg'=> 'image/jpeg',
  213. 'png'=> 'image/png',
  214. 'js'=> ,
  215. 'css'=> 'text/css',
  216. 'xml'=> 'text/xml');
  217. $conf = array(
  218. 'MimeTypes'= > $mime_types,
  219. 'ServerTokens'=> 'on',
  220. 'MaxRequests'=> 100,
  221. 'Timeout'=> ,
  222. 'DocumentRoot'=> '/home/www',
  223. 'DirectoryIndex'=> 'index.htm index.html');
  224. error_reporting(E_ALL);
  225. logs('운영 환경 초기화');
  226. sleep(1);
  227. set_time_limit(0);
  228. logs('PHP-CLI 실행 시간 초과 초기화');
  229. sleep(1 );
  230. $socket = 소켓_create(AF_INET, SOCK_STREAM, SOL_TCP);
  231. logs('소켓 초기화 중');
  232. sleep(1);
  233. logs('초기화 로컬 주소를 모든 IP 주소에 바인딩');
  234. sleep(1);
  235. $int = 소켓_bind($socket, '0.0.0.0', $conf['Listen']);
  236. logs ('초기화 바인드 로컬 포트 ​​'.$conf['Listen']);
  237. if(!$int){
  238. logs($conf['Listen'].' 포트가 다른 서비스에 의해 사용되고 있습니다.'" n");
  239. exit(0);
  240. }
  241. sleep(1);
  242. socket_listen($socket, 1024);
  243. logs('소켓 열기 듣기') ;
  244. sleep(1);
  245. logs('클라이언트 액세스 대기 중');
  246. echo "n";
  247. $i = 0;
  248. while( 1) {
  249. $pthread[$i] = new pthread($socket, $conf);
  250. $pthread[$i]->start();
  251. $pthread[$i]-> ;join();
  252. }
复代码

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿