Files
youlegames/codes/agent/game/api/lib/phprs/Request.php
2026-03-15 01:27:05 +08:00

155 lines
4.8 KiB
PHP

<?php
/**
* $Id: Request.php 63900 2015-05-19 07:09:58Z caoyangmin $
* @author caoyangmin(caoyangmin@baidu.com)
* @brief Request
*/
namespace phprs;
use phprs\util\Verify;
use Peekmo\JsonPath\JsonStore;
use phprs\util\exceptions\BadRequest;
/**
* @author caoym
* http请求包装
* 允许使用jsonpath表达式获取http请求信息
* 如
* req['$._GET.param1']
*
* TODO: 使用更友好的变量名替代直接用php的全局变量, 如$.uri.query 替代$._GET, $.body 替代$._POST
*/
class Request implements \ArrayAccess
{
//TODO: 在API实现中直接使用$_GET等全局变量是不推荐的, 应该给予警告提醒
/**
*
* @param array $data
*/
function __construct($data=null,$url_begin=0){
if($data === null){
$data = $GLOBALS;
$data['header'] = $this->getAllHeaders();
}
$this->url_begin = $url_begin;
//支持json请求(Content-Type: application/json)
$contentType = null;
if(isset($data['header']['Content-Type'])){
$contentType = $data['header']['Content-Type'];
list($contentType, ) = explode(';', $contentType)+array(null,null);
if($contentType == 'application/json'){
$post = file_get_contents('php://input');
if($post != ''){
$post = json_decode($post, true);
Verify::isTrue(is_array($post), new BadRequest('post unjson data with application/json type'));
$data['_POST'] = $post;
if(!isset($data['_REQUEST'])){
$data['_REQUEST'] = [];
}
$data['_REQUEST'] = array_merge($data['_POST'], $data['_REQUEST'] );
}
}
elseif($contentType == 'text/plain'){
$data['_POST'] = file_get_contents('php://input');
}
}
//TODO: 支持put请求
if(isset($data['_SERVER']['REQUEST_METHOD']) && 'PUT' == $data['_SERVER']['REQUEST_METHOD']){
if($contentType == 'application/x-www-form-urlencoded'){
$queryString = file_get_contents('php://input');
$query = array();
parse_str($queryString, $query);
$data['_POST'] = $query;
}
}
$full_path = $data['_SERVER']['REQUEST_URI'];
Verify::isTrue($full_path, '$._SERVER.REQUEST_URI not found' );
list($full_path,) = explode('?', $full_path);
$paths = explode('/', $full_path);
$paths = array_filter($paths,function ($i){return $i !== '';});
$paths = array_slice($paths, $this->url_begin);
$data['path'] = $paths;
$this->data = new JsonStore($data);
}
/**
* 获取http请求的所有header信息
* @return array
*/
function getAllHeaders() {
$headers = array();
foreach ($_SERVER as $name => $value)
{
if (substr($name, 0, 5) == 'HTTP_')
{
$name = str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))));
$headers[$name] = $value;
} else if ($name == "CONTENT_TYPE") {
$headers["Content-Type"] = $value;
} else if ($name == "CONTENT_LENGTH") {
$headers["Content-Length"] = $value;
}
}
return $headers;
}
/**
* (non-PHPdoc)
* @see ArrayAccess::offsetExists()
*/
public function offsetExists($offset){
return count($this->data->get($offset)) !==0;
}
/**
* (non-PHPdoc)
* @see ArrayAccess::offsetGet()
*/
public function offsetGet($offset)
{
$res = $this->data->get($offset);
if(!isset($res[0])){
trigger_error("$offset not exist");
}
return $res[0];
}
/**
* @param string $expr jsonpath 表达式
* @param $create 是否找不到就创建
* @return [found, is succeed]
*/
public function find($expr, $create=false){
$res= $this->data->get($expr, false, $create);
if(count($res) ===0 ){
return array(null,false);
}else if(count($res) ===1){
return array(&$res[0], true);
}else{
return array(&$res, true);
}
}
/**
* (non-PHPdoc)
* @see ArrayAccess::offsetSet()
*/
public function offsetSet($offset, $value)
{
Verify::isTrue($this->data->set($offset, $value));
}
/**
* (non-PHPdoc)
* @see ArrayAccess::offsetUnset()
*/
public function offsetUnset($offset)
{
Verify::isTrue(false, 'NOT IMPL');
}
/**
* 取数包含所有请求信息的数组
* @return multitype:
*/
public function toArray(){
return $this->data->toArray();
}
private $data;
private $url_begin;
}