首页 » PHP教程 » phpjson响应技巧_另辟途径若安在 Laravel 更优雅的响应 JSON 数据

phpjson响应技巧_另辟途径若安在 Laravel 更优雅的响应 JSON 数据

访客 2024-11-29 0

扫一扫用手机浏览

文章目录 [+]

class TestController extends Controller{public function index() {return json(['code' => 10000, 'message' => '', 'data' => 1]) }}

再简便点,便是把这个 json 输出封装到基类,或者 trait 中供给用者自己调用。
我也是这么利用,但在利用过程中,我在想能不能更加大略点,由于有时候仅仅是想返回数据而已。
可不可以像下面的示例这样

class TestController extends Controller{public function index() {return 1; }}

只须要业务方法调用返回就可以了,不须要每次都利用类似下面的代码

phpjson响应技巧_另辟途径若安在 Laravel 更优雅的响应 JSON 数据

class TestController extends Controller{public function index() {// 基类方法return $this->json(1) }}更优雅的相应办法

在研究 Laravel 的源码时,我创造了一个有趣的事宜 RequestHandled,这个事宜在要求处理完成后被触发。
通过监听这个事宜,我们可以在数据相应阶段进行处理,从而实现更优雅的 JSON 数据相应办法。
看下面这段代码,目前这段代码在 Laravel11 中的 Illuminate\Foundation\Http 类中

phpjson响应技巧_另辟途径若安在 Laravel 更优雅的响应 JSON 数据
(图片来自网络侵删)

public function handle($request){$this->requestStartedAt = Carbon::now();try {$request->enableHttpMethodParameterOverride();$response = $this->sendRequestThroughRouter($request);} catch (Throwable $e) {$this->reportException($e);$response = $this->renderException($request, $e); }// 在这里可以对相应做些什么$this->app['events']->dispatch(new RequestHandled($request, $response) );return $response;}

首先创建一个 Listener,利用 php artisan make:listener RequestHandledListener ,创建完成之后,Laravel 框架会自动帮注册,不须要手动去注册。

下面只是大略的示例,由于只须要 Json 相应,以是这里过滤掉所有非 JsonRespons 相应

class RequestHandledListener{public function handle(RequestHandled $event): void{$response = $event->response;if ($response instanceof JsonResponse) {$exception = $response->exception;if ($response->getStatusCode() == SymfonyResponse::HTTP_OK && !$exception) {$response->setData($this->formatData($response->getData()));}}}// 拦截数据,然后格式化数据// 详细内容跟规则可以根据实际业务设置protected function formatData(mixed $data): array{$responseData = ['code' => 10000, // 业务成功 code'message' => 'success', // 成功信息];$responseData['data'] = $data;return $responseData;}}

回到掌握器的时候,再利用下面的代码进行输出

class TestController extends Controller{public function index(){return 1;}}

创造根本没有任何浸染。
根本不是 Json 相应啊。
想一想为啥? 为什么掌握要输出 Json Response 工具呢?上面的代码到浏览器只会输出个 1,便是一个普通的相应,而不是 Json Response。
以是须要想相应始终设置为 Json Reponse 工具。
来写一个中间件办理这个问题。
利用 php artisan make:middleware JsonResponseMiddleware 创建中间件

namespace App\Http\Middleware;use Illuminate\Http\JsonResponse;use Illuminate\Http\Request;use Illuminate\Http\Response;use Symfony\Component\HttpFoundation\BinaryFileResponse;class JsonResponseMiddleware{public function handle(Request $request, \Closure $next){$response = $next($request);// responseif ($response instanceof Response) {return new JsonResponse($response->getContent());}return $response;}}

切换到路由 web.php 文件,加上路由

Route::get('/', [\App\Http\Controllers\IndexController::class, 'index'])->middleware(\App\Http\Middleware\JsonResponseMiddleware::class);

回到浏览器,刷新下,你将会看到下面的输出

{"code": 10000,"message": "success","data": "1"}处理不同要求来源

有时,我们可能须要根据要求的来源不同来处理相应数据的格式。
例如,后台管理系统和客户真个要求可能须要不同的数据格式。
这时,我们可以通过设置要求头信息来区分不同的要求来源。
下面只是一个示例。
现在前端要求一样平常都用 axios, 以是只要在全局 axios 工具设置一个头信息。
如下

axios.defaults.headers['Request-from'] = 'WhereFrom'

后端可以根据头信息来判断是否须要利用该返回,可以这么做,回到 RequestHandledListener 中

public function handle(RequestHandled $event): void{// 只有后台要求才处理if (Request::hasHeader('Request-from')&& Str::of(Request::header('Request-from'))->exactly('WhereFrom')) {$response = $event->response;if ($response instanceof JsonResponse) {$exception = $response->exception;if ($response->getStatusCode() == SymfonyResponse::HTTP_OK && !$exception) {$response->setData($this->formatData($response->getData())); } } }}如何相应缺点码

不对啊,这里写去世的 success,那么失落败要求该怎么做?全体项目失落败都是用非常处理就行,以是只须要在全局非常这里处理下。
首先确定下我们数据格式是这样的

{"code": 10000,"message": "success","data": "1"}

当到掌握器中 Index 方法抛出一个非常

public function index(){throw new \Exception('test');}

会输出这样的内容

{code: 10000,message: "success",data: '<!DOCTYPE html><html lang="en" class="auto"><!--' // 非常一大段的文本,html 输出}

这里有三个问题

Code 码没有利用非常的还是固定的message 信息不是非常抛出来的data 不须要有数据,可以不用返回

为理解决这三个问题,可以这么做,首先我们创建一个基类 abstract class Exception, php artisan make:exception BaseException, 内容如下

use Symfony\Component\HttpKernel\Exception\HttpException;abstract class BaseException extends HttpException{protected $code = 0;public function __construct(string $message = '', int $code = 0) {parent::__construct($this->statusCode(), $message ?: $this->message, null, [], $code); }public function statusCode(): int {// 对付非常统一返回 500,须要变动可以通过子类修正对应的 codereturn 500; }public function render(): array {return ['code' => $this->code,'message' => $this->message, ]; }}

基类创建好之后呢,再来创建子类,由于业务中的缺点类型各种各样,以是非常子类也是很多的,但是记住都须要继续 BaseException,还是用上面的 artisan 创建一个失落败非常,代码如下

namespace App\Exceptions;use Exception;class FailException extends BaseException{//protected $code = 10001;protected $message = 'fail';}

再回到掌握中

public function index(){ throw new FailException();}

刷新浏览器之后,浏览器会输出精确的缺点返回了。
很不错,办理了上面的三个问题

{"code": 10001,"message": "fail"}总结

这个办法多多少少有点黑盒了。
对付刚接手的人,如果不去翻代码或者有人来讲解的话,可能多多少有点懵的 。
但是如果理解了,我认为将 response json 这样输出从业务代码中解构出来还是蛮好的。
如果运用的相应数据险些不变动,个人更喜好这样的办法去返回,不然掌握器大量的 response()->json() 这样的代码看着挺烦人的。
如有更好的方法,欢迎谈论。

[原文链接: 另辟路子!
如何在 Laravel 更优雅的相应 JSON 数据

](https://catchadmin.com/post/2024-03/laravel-unified-response)

相关文章

乔楚php技巧_分享下MySQL的备份筹划

分享下MySQL的备份方案1. 两个条件:1. 备份任务集中管理,基于WEB平台定备份任务2. 备份结果要有Report及每天的随...

PHP教程 2024-12-09 阅读0 评论0