php 解析http,PHP解析Http协议&协议复习

PHP解析Http协议&协议复习

最近在整理自己的知识体系,发现很多基础已经忘得差不多了,所以重新学习一次。

Http协议

HTTP是一个应用层协议,由请求和响应构成,是一个标准的客户端服务器模型。HTTP是一个无状态的协议。

请求报文示例

596715dbca72542e3c2c5312a7fbfa04.png

GET /public/api/index?id=1 HTTP/1.1

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8

Accept-Encoding: gzip, deflate

Accept-Language: zh-CN,zh;q=0.9

Cache-Control: max-age=0

Connection: keep-alive

Host: 192.168.10.10:8088

Upgrade-Insecure-Requests: 1

User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36

响应报文示例

317988dde310ba7fd2ce732f034698da.png

HTTP/1.1 200 OK

Date: Sun, 25 Oct 2015 15:43:47 GMT

Server: Apache

Set-Cookie: PHPSESSID=4v2actjf96v614r2kh36380kq6; path=/

Expires: Thu, 19 Nov 1981 08:52:00 GMT

Cache-Control: private

Pragma: no-cache

Vary: Accept-Encoding

Content-Length: 5105

Connection: close

Content-Type: text/html; charset=utf-8

....

代码

$_GET, 'post'=>$_POST, 'cookie'=>$_COOKIE, 'server'=>$_SERVER, 'files'=>$_FILES))));

fclose($conn);

}

}

}else{

die($errstr);

}

//响应

function response($str){

$content = "HTTP/1.1 200 OK\r\nServer: vruan_web/1.0.0\r\nContent-Length: " . strlen($str)."\r\nContent-type: application/json;charset=UTF-8"."\r\n\r\n{$str}";

return $content;

}

/*

* 函数:parse_http

* 描述:解析http协议

*/

function parse_http($http)

{

// 初始化

$_POST = $_GET = $_COOKIE = $_REQUEST = $_SESSION = $_FILES = array();

$GLOBALS['HTTP_RAW_POST_DATA'] = '';

// 需要设置的变量名

$_SERVER = array (

'QUERY_STRING' => '',

'REQUEST_METHOD' => '',

'REQUEST_URI' => '',

'SERVER_PROTOCOL' => '',

'SERVER_SOFTWARE' => '',

'SERVER_NAME' => '',

'HTTP_HOST' => '',

'HTTP_USER_AGENT' => '',

'HTTP_ACCEPT' => '',

'HTTP_ACCEPT_LANGUAGE' => '',

'HTTP_ACCEPT_ENCODING' => '',

'HTTP_COOKIE' => '',

'HTTP_CONNECTION' => '',

'REMOTE_ADDR' => '',

'REMOTE_PORT' => '0',

);

// 将header分割成数组

list($http_header, $http_body) = explode("\r\n\r\n", $http, 2);

$header_data = explode("\r\n", $http_header);

list($_SERVER['REQUEST_METHOD'], $_SERVER['REQUEST_URI'], $_SERVER['SERVER_PROTOCOL']) = explode(' ', $header_data[0]);

unset($header_data[0]);

foreach($header_data as $content)

{

// \r\n\r\n

if(empty($content))

{

continue;

}

list($key, $value) = explode(':', $content, 2);

$key = strtolower($key);

$value = trim($value);

switch($key)

{

// HTTP_HOST

case 'host':

$_SERVER['HTTP_HOST'] = $value;

$tmp = explode(':', $value);

$_SERVER['SERVER_NAME'] = $tmp[0];

if(isset($tmp[1]))

{

$_SERVER['SERVER_PORT'] = $tmp[1];

}

break;

// cookie

case 'cookie':

$_SERVER['HTTP_COOKIE'] = $value;

//将字符串解析成多个变量

parse_str(str_replace('; ', '&', $_SERVER['HTTP_COOKIE']), $_COOKIE);

break;

// user-agent

case 'user-agent':

$_SERVER['HTTP_USER_AGENT'] = $value;

break;

// accept

case 'accept':

$_SERVER['HTTP_ACCEPT'] = $value;

break;

// accept-language

case 'accept-language':

$_SERVER['HTTP_ACCEPT_LANGUAGE'] = $value;

break;

// accept-encoding

case 'accept-encoding':

$_SERVER['HTTP_ACCEPT_ENCODING'] = $value;

break;

// connection

case 'connection':

$_SERVER['HTTP_CONNECTION'] = $value;

break;

case 'referer':

$_SERVER['HTTP_REFERER'] = $value;

break;

case 'if-modified-since':

$_SERVER['HTTP_IF_MODIFIED_SINCE'] = $value;

break;

case 'if-none-match':

$_SERVER['HTTP_IF_NONE_MATCH'] = $value;

break;

case 'content-type':

// 不同的请求类型:application/x-www-form-urlencoded application/json multipart/form-data text/xml

//demo: Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryrGKCBY7qhFd3TrwA

if(!preg_match('/boundary="?(\S+)"?/', $value, $match))

{

$_SERVER['CONTENT_TYPE'] = $value;

}

else

{

$_SERVER['CONTENT_TYPE'] = 'multipart/form-data';

$http_post_boundary = '--'.$match[1];

}

break;

}

}

// 需要解析$_POST

if($_SERVER['REQUEST_METHOD'] === 'POST')

{

//上传文件处理

if(isset($_SERVER['CONTENT_TYPE']) && $_SERVER['CONTENT_TYPE'] === 'multipart/form-data')

{

parse_upload_files($http_body, $http_post_boundary);

}

else

{

parse_str($http_body, $_POST);

// $GLOBALS['HTTP_RAW_POST_DATA']

$GLOBALS['HTTP_RAW_POST_DATA'] = $http_body;

}

}

// QUERY_STRING

$_SERVER['QUERY_STRING'] = parse_url($_SERVER['REQUEST_URI'], PHP_URL_QUERY);

if($_SERVER['QUERY_STRING'])

{

// $GET

parse_str($_SERVER['QUERY_STRING'], $_GET);

}

else

{

$_SERVER['QUERY_STRING'] = '';

}

// REQUEST

// $_REQUEST = array_merge($_GET, $_POST);

return array($_GET, $_POST, $_COOKIE, $_SERVER, $_FILES);

}

/*

* 函数:parse_upload_files

* 描述:解析上传的文件

*/

function parse_upload_files($http_body, $http_post_boundary)

{

//去除最后一行boundary

$http_body = substr($http_body, 0, strlen($http_body) - (strlen($http_post_boundary) + 4));

$boundary_data_array = explode($http_post_boundary."\r\n", $http_body);

if($boundary_data_array[0] === '')

{

unset($boundary_data_array[0]);

}

foreach($boundary_data_array as $boundary_data_buffer)

{

/**

Content-Disposition: form-data; name="text"

title

------WebKitFormBoundaryrGKCBY7qhFd3TrwA

Content-Disposition: form-data; name="file"; filename="chrome.png"

Content-Type: image/png

PNG ... content of chrome.png ...

*/

list($boundary_header_buffer, $boundary_value) = explode("\r\n\r\n", $boundary_data_buffer, 2);

// 去掉末尾\r\n

$boundary_value = substr($boundary_value, 0, -2);

foreach (explode("\r\n", $boundary_header_buffer) as $item)

{

list($header_key, $header_value) = explode(": ", $item);

$header_key = strtolower($header_key);

switch ($header_key)

{

case "content-disposition":

// 是文件

if(preg_match('/name=".*?"; filename="(.*?)"$/', $header_value, $match))

{

$_FILES[] = array(

'file_name' => $match[1],

'file_data' => $boundary_value,

'file_size' => strlen($boundary_value),

);

continue;

}

// 是post field

else

{

// 收集post

if(preg_match('/name="(.*?)"$/', $header_value, $match))

{

$_POST[$match[1]] = $boundary_value;

}

}

break;

}

}

}

}

定义及参考资料

https://www.cnblogs.com/guguli/p/4758937.html

http://caibaojian.com/http-protocol.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值