我們在library\Https目錄下新建Request、Response,開始編寫請求和輸出的程式碼。
Request
我們實現幾個常用的方法,get、post、method等,這裡主要用$_SERVER實現,為了複用我們定義了三個私有屬性儲存get引數、post引數和method。
<?php
/**
* 處理請求
*/
namespace Library\Https;
use Library\Components\Base;
class Request extends Base
{
/**
* 獲取請求方法
* @return string
*/
public function getMethod()
{
if (isset($_SERVER['REQUEST_METHOD'])) {
return strtoupper($_SERVER['REQUEST_METHOD']);
}
return 'GET';
}
/**
* 請求頭
* @param $name
* @param null $defaultValue
* @return mixed|null
*/
public function getHeader($name, $defaultValue = null)
{
$name = ucfirst($name);
if (function_exists('apache_request_headers')) {
$headers = apache_request_headers();
return $headers[$name]?? $defaultValue;
}
$name = strtoupper($name);
return $_SERVER[$name]?? $defaultValue;
}
/**
* 獲取get引數
* @param null $name
* @param null $defaultValue
* @return |null
*/
public function get($name = null, $defaultValue = null)
{
if ($name === null) {
return $this->getQueryParams();
}
return $this->getQueryParam($name, $defaultValue);
}
public function getQueryParam($name, $defaultValue = null)
{
$params = $this->getQueryParams();
return isset($params[$name]) ? $params[$name] : $defaultValue;
}
public function getQueryParams()
{
if (empty($this->queryParams)) {
return $this->queryParams = $_GET;
}
return $this->queryParams;
}
/**
* 獲取post引數
* @param null $name
* @param null $defaultValue
* @return array|mixed|null
*/
public function post($name = null, $defaultValue = null)
{
if ($name === null) {
return $this->getBodyParams();
}
return $this->getBodyParam($name, $defaultValue);
}
public function getBodyParam($name, $defaultValue = null)
{
$params = $this->getBodyParams();
if (is_object($params)) {
try {
return $params->{$name};
} catch (\Exception $e) {
return $defaultValue;
}
}
return isset($params[$name]) ? $params[$name] : $defaultValue;
}
public function getBodyParams()
{
$contentType = strtolower($this->getHeader('Content-Type'));
if ($contentType == 'multipart/form-data') {
$this->bodyParams = $_POST;
} else {
$this->bodyParams = \json_decode(file_get_contents("php://input"), true);
}
return $this->bodyParams?? [];
}
/**
* get引數陣列
*/
private $queryParams = [];
/**
* post引數陣列
*/
private $bodyParams = [];
private $method;
}
知識點:
- 獲取請求頭部資訊的方式nginx和apache不同
- apache可以使用apache_request_headers
- nginx使用$_SERVER,並且需要注意的是的是自定義資訊等引數會在前面自動加上http_,並且會轉換為大寫
- post引數獲取的方式
- 當Content-Type是
application/x-www-data-urlencoded
或multipart/form-data
時,資料會放進$_POST中; - 除了Coentent-Type為multipart/form-data的情況,資料都可以通過file_get_contents(“php://input”)取到;
- 不建議使用$GLOBALS[‘HTTP_RAW_POST_DATA’]
Response
Response預設以使用廣泛的json輸出,暫時也只考慮json格式輸出的情況。
<?php
/**
* 資料輸出
*/
namespace Library\Https;
use Library\Components\Base;
class Response extends Base
{
public $code = 0;
public $result = [];
public $msg = "success";
public function send()
{
header('Content-Type:application/json; charset=utf-8');
echo \json_encode([
'data' => $this->result,
'msg' => $this->msg,
'code' => $this->code,
'timestamp' => time()
]);
}
public function json($data = [])
{
$this->result = array_merge($this->result, $data);
return $this;
}
}
知識點:
- header() 用於傳送原生的 HTTP 頭。
- json_encode ( mixed $value [, int $options = 0 [, int $depth = 512 ]] ) : string — 對變數進行 JSON 編碼,options可以預定義常量,如 JSON_UNESCAPED_UNICODE,JSON_UNESCAPED_SLASHES。
Controller
結合輸出物件,我們在建立一個基類控制器,也放在相同的Https目錄,我們控制建立一個建構函式,例項化一個Response,並實現一個通用的json:
<?php
/**
* 基類控制器
* 預定義json方法,便於其他控制器使用
* 返回格式
{
"data": [],
"msg": "success",
"code": 0,
"timestamp": 1572231957
}
*/
namespace Library\Https;
class Controller
{
protected $response;
protected $code = 200;
public function __construct()
{
$this->response = new Response();
}
public function json($data = [])
{
return $this->response->json($data);
}
public function index($params)
{
return $this->response->json(['hello' => 'saif']);
}
}
app應用裡的控制器都必須繼承這個基類控制器。
本作品採用《CC 協議》,轉載必須註明作者和本文連結