資料返回都需要這樣的封裝,return $this->success($result);
class IndexController extends AbstractController
{
public function index()
{
$user = $this->request->input('user', '399001');
$method = $this->request->getMethod();
$result = [
'method' => $method,
'message' => "Hello {$user}.",
];
return $this->success($result);
}
}
一般的實現方式是在基類中實現success方法,但會讓基類愈加龐大,於是改良使用trait,基類中引入trait,這樣也挺好。
突然無聊想到的方法,感覺挺好的:定義返回服務類,使用 __call
在基類中呼叫服務類的方法。感覺能更方便的解耦耶,貼程式碼
ResponseService
<?php
namespace App\Service\Utils;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Contract\ResponseInterface;
/**
* API請求返回服務類
*
* Class ResponseService
*
* @package App\Service\Utils
*/
class ResponseService
{
/**
* @var int
*/
private $http_code = 200;
/**
* http頭部資訊
*
* @var string[]
*/
private $http_headers = [
'Author' => 'Colorado',
];
/**
* 業務返回碼
* 組成結構:xx(業務模組) xx(業務子模組) xx(細化編碼)
* 舉例:110101 11(APP模組)01(鑑權模組)01(登入失敗)
*
* @var int
*/
private $business_code = 100000;
/**
* 業務返回訊息
*
* @var string
*/
private $business_msg = 'ok';
/**
* @Inject
* @var ResponseInterface
*/
private $response;
/**
* 設定http狀態碼
*
* @param int $code
*
* @return $this
*/
public function setHttpCode(int $code = 200): self
{
$this->http_code = $code;
return $this;
}
/**
* 設定http頭部資訊
*
* @param string $name
* @param mixed $value
*
* @return $this
*/
public function setHttpHeader(string $name, $value): self
{
$this->http_headers[$name] = (string)$value;
return $this;
}
/**
* 成功資料返回
*
* @param mixed $data 返回資料
* @param int $business_code 業務返回碼
*
* @return ResponseInterface|\Psr\Http\Message\ResponseInterface
*/
public function success($data, int $business_code = 100000)
{
$this->business_code = $business_code;
return $this->response($data);
}
/**
* 失敗返回
*
* @param string $error_msg 錯誤資訊
* @param mixed $data 返回資料
* @param int $business_code 錯誤業務碼
*
* @return ResponseInterface|\Psr\Http\Message\ResponseInterface
*/
public function fail(string $error_msg = 'fail', $data = null, int $business_code = 999999)
{
$this->business_code = $business_code;
$this->business_msg = $error_msg;
return $this->response($data);
}
/**
* 返回資料
*
* @param $data
*
* @return ResponseInterface|\Psr\Http\Message\ResponseInterface
*/
private function response($data)
{
$this->response = $this->response->json($this->normalizeData($data))->withStatus($this->http_code);
if (! empty($this->http_headers)) {
foreach ($this->http_headers as $name => $value) {
$this->response = $this->response->withHeader($name, $value);
}
}
return $this->response;
}
/**
* 標準化返回資料格式
*
* @param mixed $data 業務返回資料
*
* @return array
*/
private function normalizeData($data): array
{
return [
'code' => $this->business_code,
'data' => $data,
'message' => $this->business_msg,
'timestamp' => time(),
];
}
}
基類AbstractController
<?php
declare(strict_types=1);
/**
* This file is part of Hyperf.
*
* @link https://www.hyperf.io
* @document https://hyperf.wiki
* @contact group@hyperf.io
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
*/
namespace App\Controller;
use App\Service\Utils\ResponseService;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\HttpServer\Contract\ResponseInterface;
use Psr\Container\ContainerInterface;
/**
* Class AbstractController
* @method ResponseService setHttpCode(int $code = 200)
* @method ResponseService setHttpHeader(string $name, $value)
* @method success(mixed $data, int $business_code = 100000)
* @method fail(string $error_msg = 'fail', mixed $data = null, int $business_code = 999999)
* @package App\Controller
*/
abstract class AbstractController
{
/**
* @Inject
* @var ContainerInterface
*/
protected $container;
/**
* @Inject
* @var RequestInterface
*/
protected $request;
/**
* @Inject
* @var ResponseInterface
*/
protected $response;
/**
* @param $name
* @param $arguments
*
* @return mixed
*/
public function __call($name, $arguments)
{
if (method_exists(ResponseService::class, $name)) {
return make(ResponseService::class)->{$name}(...$arguments);
}
}
}
使用demo
控制器中
class IndexController extends AbstractController
{
public function index()
{
$user = $this->request->input('user', '399001');
$method = $this->request->getMethod();
$result = [
'method' => $method,
'message' => "Hello {$user}.",
];
// 成功返回
return $this->success($result);
// 失敗返回
return $this->fail('失敗啦');
// 設定http狀態碼
return $this->setHttpCode(201)->success($result);
return $this->setHttpCode(500)->fail('伺服器掛了');
// 設定http頭部資訊
return $this->setHttpHeader('server', 'hyperf-server')->success($result);
}
}
其他地方,如ExceptionHandler
使用make該類即可呼叫類的方法
class ValidationExceptionHandler extends ExceptionHandler
{
public function handle(Throwable $throwable, ResponseInterface $response)
{
$this->stopPropagation();
$body = $throwable->validator->errors()->first();
return make(ResponseService::class)->fail($body);
}
public function isValid(Throwable $throwable): bool
{
return $throwable instanceof ValidationException;
}
}
本作品採用《CC 協議》,轉載必須註明作者和本文連結