SimpleHttp.php 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. <?php
  2. namespace Man\Protocols;
  3. /**
  4. * http 协议解析 相关
  5. * 简单的实现 不支持header cookie
  6. * @author walkor <worker-man@qq.com>
  7. * */
  8. class SimpleHttp{
  9. /**
  10. * 构造函数
  11. */
  12. private function __construct(){}
  13. /**
  14. * http头
  15. * @var array
  16. */
  17. public static $header = array();
  18. /**
  19. * cookie
  20. * @var array
  21. */
  22. protected static $cookie = array();
  23. /**
  24. * 判断数据包是否全部接收完成
  25. *
  26. * @param string $data
  27. * @return int 0:完成 1:还要接收数据
  28. */
  29. public static function input($data)
  30. {
  31. // 查找\r\n\r\n
  32. $data_length = strlen($data);
  33. if(!strpos($data, "\r\n\r\n"))
  34. {
  35. return 1;
  36. }
  37. // POST请求还要读包体
  38. if(strpos($data, "POST"))
  39. {
  40. // 找Content-Length
  41. $match = array();
  42. if(preg_match("/\r\nContent-Length: ?(\d?)\r\n/", $data, $match))
  43. {
  44. $content_lenght = $match[1];
  45. }
  46. else
  47. {
  48. return 0;
  49. }
  50. // 看包体长度是否符合
  51. $tmp = explode("\r\n\r\n", $data);
  52. if(strlen($tmp[1]) >= $content_lenght)
  53. {
  54. return 0;
  55. }
  56. return 1;
  57. }
  58. else
  59. {
  60. return 0;
  61. }
  62. // var_export($header_data);
  63. return 0;
  64. }
  65. /**
  66. * 解析http协议包,并设置相应环境变量
  67. *
  68. * @param string $data
  69. * @return array
  70. */
  71. public static function decode($data)
  72. {
  73. $_SERVER = array(
  74. 'REQUEST_URI' => '/',
  75. 'HTTP_HOST' => '127.0.0.1',
  76. 'HTTP_COOKIE' => '',
  77. );
  78. $_POST = array();
  79. $_GET = array();
  80. $GLOBALS['HTTP_RAW_POST_DATA'] = array();
  81. // 将header分割成数组
  82. $header_data = explode("\r\n", $data);
  83. // 需要解析$_POST
  84. if(strpos($data, "POST") === 0)
  85. {
  86. $tmp = explode("\r\n\r\n", $data);
  87. parse_str($tmp[1], $_POST);
  88. // $GLOBALS['HTTP_RAW_POST_DATA']
  89. $GLOBALS['HTTP_RAW_POST_DATA'] = $tmp[1];
  90. }
  91. // REQUEST_URI
  92. $tmp = explode(' ', $header_data[0]);
  93. $_SERVER['REQUEST_URI'] = isset($tmp[1]) ? $tmp[1] : '/';
  94. // PHP_SELF
  95. $base_name = basename($_SERVER['REQUEST_URI']);
  96. $_SERVER['PHP_SELF'] = empty($base_name) ? 'index.php' : $base_name;
  97. unset($header_data[0]);
  98. foreach($header_data as $content)
  99. {
  100. // 解析HTTP_HOST
  101. if(strpos($content, 'Host') === 0)
  102. {
  103. $tmp = explode(':', $content);
  104. if(isset($tmp[1]))
  105. {
  106. $_SERVER['HTTP_HOST'] = $tmp[1];
  107. }
  108. if(isset($tmp[2]))
  109. {
  110. $_SERVER['SERVER_PORT'] = $tmp[2];
  111. }
  112. }
  113. // 解析Cookie
  114. elseif(strpos($content, 'Cookie') === 0)
  115. {
  116. $tmp = explode(' ', $content);
  117. if(isset($tmp[1]))
  118. {
  119. $_SERVER['HTTP_COOKIE'] = $tmp[1];
  120. }
  121. }
  122. }
  123. // 'REQUEST_TIME_FLOAT' => 1375774613.237,
  124. $_SERVER['REQUEST_TIME_FLOAT'] = microtime(true);
  125. $_SERVER['REQUEST_TIME'] = intval($_SERVER['REQUEST_TIME_FLOAT']);
  126. // GET
  127. parse_str(preg_replace('/^\/.*?\?/', '', $_SERVER['REQUEST_URI']), $_GET);
  128. unset($_GET['/']);
  129. }
  130. /**
  131. * 设置http头
  132. * @return bool
  133. */
  134. public static function header($content)
  135. {
  136. if(strpos($content, 'HTTP') === 0)
  137. {
  138. $key = 'Http-Code';
  139. }
  140. else
  141. {
  142. $key = strstr($content, ":", true);
  143. if(empty($key))
  144. {
  145. return false;
  146. }
  147. }
  148. self::$header[$key] = $content;
  149. return true;
  150. }
  151. /**
  152. *
  153. * @param string $name
  154. * @param string/int $value
  155. * @param int $expire
  156. */
  157. public static function setcookie($name, $value='', $expire=0)
  158. {
  159. // 待完善
  160. }
  161. /**
  162. * 清除header
  163. * @return void
  164. */
  165. public static function clear()
  166. {
  167. self::$header = array();
  168. }
  169. /**
  170. * 打包http协议,用于返回数据给nginx
  171. *
  172. * @param string $data
  173. * @return string
  174. */
  175. public static function encode($data)
  176. {
  177. // header
  178. $header = "Server: PHPServer/1.0\r\nContent-Length: ".strlen($data)."\r\n";
  179. // 没有Content-Type默认给个
  180. if(!isset(self::$header['Content-Type']))
  181. {
  182. $header = "Content-Type: text/html;charset=utf-8\r\n".$header;
  183. }
  184. // 没有http-code默认给个
  185. if(!isset(self::$header['Http-Code']))
  186. {
  187. $header = "HTTP/1.1 200 OK\r\n".$header;
  188. }
  189. else
  190. {
  191. $header = self::$header['Http-Code']."\r\n".$header;
  192. unset(self::$header['Http-Code']);
  193. }
  194. // 其它header
  195. foreach(self::$header as $content)
  196. {
  197. $header .= $content."\r\n";
  198. }
  199. $header .= "\r\n";
  200. self::clear();
  201. // 整个http包
  202. return $header.$data;
  203. }
  204. }