数据返回都需要这样的封装,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;
}
}