La colonne tutorielle suivante de laravel vous présentera une solution à l'exception laravel en retour. J'espère qu'elle sera utile aux amis dans le besoin !
Nous supposons un scénario dans lequel l'enregistrement des utilisateurs nécessite des paramètres
参数名 | 解释 | 类型 | 是否必填 |
---|---|---|---|
mobile | 用户手机号码 | 字符串 | 必填 |
sms_code | 短信验证码 | 整数 | 必填 |
password | 用户密码 | 字符串 | 用户密码 |
re_password | 重复用户密码 | 整数 | 重复用户密码 |
以下列举会出现的问题情况
现在已知会复用的场景有 会在别的业务内有相同错误的类型 (具体业务不做赘述,业务不同,理解不同)
这里假定大家都不是大佬 业务有藕合 处理方案如下 (以下代码仅在checkSms下进行)
//第一次写文档 不会用markdown 你也可以用 response出去 这样浅显易懂exit(json_encode(['code'=>-1,'msg'=>'短信验证码错误']));
if (false === checkSms($mobile,$code,$type)){ exit(json_encode(['code'=>-1,'msg'=>'短信验证码错误']));}
已知你有三套业务 且每套业务包含N个子模块 (别杠微服务/跨语言等,杠就是你赢 /狗头)
Fatal error: Allowed memory size of 1073741824 bytes exhausted (tried to allocate 9216 bytes) in your problem
与其到处去找不如直接告诉我是怎么回事,但是你又很难保证大家写的错误信息内容都是一样的
首先我们明白一个道理 你写代码最害怕的是什么 是bug吗? 不是
是这个
你问我错哪了? 我怎么知道!!!!! 我就知道肯定报错了 抛出异常了 ,程序停了啊!!!
ok 那么我们知道了一个道理,当程序抛出异常的时候,项目就会停掉.
同时我们也明白了一件事 叫做:
假定我们有一个业务模块叫做 User 里面包含了一个控制器叫做 AuthController
内部需要完成一个login的行为
<?php namespace App\Http\Controllers\Application\Auth; use App\Http\Controllers\Controller; use App\Http\Requests\Application\Auth\LoginRequest; use Illuminate\Http\JsonResponse; class AuthController extends Controller { // public function index(LoginRequest $loginRequest): JsonResponse { $data = $loginRequest->all(); //todo 验证是否登录成功 //todo 登录成功之后需要从返回里面获取token 和 userInfo //todo 记录日志等行为 //todo 返回前端 return $this->success('登陆成功', compact('token', 'user')); } }
if (!empty(login($username,$password))){ //todo 登录成功 //tonext}
if(1){ if(1){ if(1){ if(1){ //建议这里直接用来测光速到底是多少 ,因为需求是无限长的 //并且你知道到底是什么问题,什么业务返回来的,到底的意思是什么嘛? (突然成为派大星 ) } } } }
我们上面已知程序抛出异常就会停掉,除非你继续catch 然后抛什么出来??????怕不是万能交税
1.我们设计让我们的程序听话,怎么听话,让他犯错自己会停,还会告诉你怎么回事
2.怎么实现,这么做的意义是什么
3.如何实现,这样做有什么别的意义没
4.性能损耗问题
回答问题
1.你是开发,程序是你的 你必须说什么让他听什么
2.此处仅做流程展示,最后会直接贴代码加注释,如果没耐心可以直接翻最后 创建异常应该都ok吧,不ok 就去看文档 你可以停在这了
<?php namespace App\Exceptions; use Exception; class XxxException extends Exception { /** * @Message('短信验证码错误') */ const SMS_CODE_IS_ERROR = '300000000'; /** * @Message('短信验证码类型错误') */ const SMS_CODE_TYPE_IS_ERROR = '300000001'; /** * @Message('短信验证码不存在') */ const SMS_CODE_IS_NOT_EXISTS = '300000002'; } ?>
伪代码
//todo 验证码类型错误throw new XxxException(XxxException::SMS_CODE_IS_ERROR);
程序现在是不是应该停下来了,因为当你exception的时候 下面代码不会执行了
但是新的问题出现了,如果这样抛出异常,前端怎么办???????????
此处小声bb 前端处理不了跟我什么关系啊,我是后台啊,你有问题找前端啊.
那么我们假设一下 如果我们告诉前端的是
{code:'300000000','message:'短信验证码错误'}
是不是就很舒服了,前后端是一家 怎么能闹脾气呢
那么如果 Code统一,请问出问题你在发愁什么? 是你的phpstorm不存在属性追踪吗?
怎么实现???????????????
你问我,我也不到啊 我只能给你这个啊
<?php namespace App\Exceptions;use App\Factory\ParseException; //解释异常的工厂 嫌弃名字长就没加Factory use App\Traits\ResponseTrait; //这个是我自己写的一个简单的trait 也会一并贴上去use Illuminate\Database\Eloquent\ModelNotFoundException;use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;use Illuminate\Http\JsonResponse;use Illuminate\Http\Response;use Illuminate\Support\Str;use Illuminate\Validation\ValidationException;use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;use Throwable;class Handler extends ExceptionHandler{ use ResponseTrait; /** * A list of the exception types that are not reported. * * @var array */ protected $dontReport = [ // ]; /** * A list of the inputs that are never flashed for validation exceptions. * * @var array */ protected $dontFlash = [ 'current_password', 'password', 'password_confirmation', ]; /** * Register the exception handling callbacks for the application. * * @return void */ public function register() { $this->reportable(function (Throwable $e) { // }); } public function render($request, $e) { //数据库没查到数据或者数据是softdelete if ($e instanceof ModelNotFoundException) { return $this->error('500', '数据不存在或已删除'); } //非允许请求方式 if ($e instanceof MethodNotAllowedHttpException) { return $this->error('422', '请求方式错误'); } //验证失败 if ($e instanceof ValidationException) { return $this->error(412, current(current($e->errors()))); } //这里是为了兼容其他的一些错误 if (Str::length($e->getMessage()) > 1 && Str::length($e->getCode()) > 1) { return $this->error($e->getCode(), $e->getMessage()); } //处理我们自己的错误 $result = ParseException::parseException($e); //这里判断的原因很简单 因为可能这个code没有按照规范声明 if (is_array($result)) { return $this->error($result['code'], $result['message']); } // Object Not Found 你懂我意思吧? if ($e instanceof NotFoundHttpException) { return $this->error('404', '页面路径不存在'); } //这里可以根据自己是否需要做兜底而决定是否兜底 }}
<?php namespace App\Factory;use Illuminate\Support\Facades\Log;class ParseException{ public static function parseException(\Throwable $exception) { //注解 不懂得话建议直接看文档->反射 ,我讲不明白这个东西 $annotation = new \ReflectionClass($exception); //翻转 成code->constant $values = array_flip($annotation->getConstants()); if (empty($values)) { return false; } //拿到对应的constant $constant = $values[$exception->getMessage()]; //constant反射 $annotation_text = new \ReflectionClassConstant($exception, $constant); //获取属性注释内容 $comment = $annotation_text->getDocComment(); try { //正则大法好 建议留意此处 preg_match("/Message\(\'(.*?)\'\)(\\r\\n|\\r|\\n)/U", $comment, $result); } catch (\Throwable $e) { return false; } if (false === isset($result[1])) { return false; } return [ 'code' => $exception->getMessage(), 'message' => $result[1] ]; }}
不要问我要 ResponseTrait 我相信一个简单的 响应实现你是ok的
这样实现的意义就是为了不管谁接手项目前端后端 看到错误信息一目了然,就算某天领导说不要需要告诉用户短信什么错了,就告诉他你短信错了,你只需要去改constant而已!
并且可读性高,ide支持 ,如果你觉得不合适,那我没辙了 ,我尽力了
Perte de performances
Aucune perte de performances évidente n'a été trouvée jusqu'à présent. Le plan de réglage donné est que si possible, la liste d'attributs de la classe annotée (quelque chose à laquelle vous devez prêter attention) peut être mise en cache (car je n'en ai pas besoin). y aller pour le moment) Considérez ceci, laravels est une excellente méthode)
Si rien d'autre, vous pouvez simplement coller mon code et l'utiliser directement, mais je ne vous recommande pas de faire cela, car manger une fois ne veut pas dire que vous serez rassasié tout le temps. J'espère que vous comprendrez que vous devriez au moins l'aimer et ne pas le donner
C'est la première fois que j'écris du démarque. S'il y a quelque chose de mal écrit, vous pouvez partir. un message à temps et je ferai de mon mieux pour le corriger lorsque je le verrai. S'il y a des erreurs de code évidentes, veuillez me le rappeler afin que je puisse supprimer votre message
N'essayez pas de faire semblant de travailler dur, car le résultat. je ne ferai pas semblant avec toi~! (Comment changer la couleur de ce mot ?)
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!