CakePHP中try catch捕获异常后后续代码仍执行如何解决
问题产生原因
你封装的私有authorize方法中返回的重定向响应,仅会退出authorize方法本身的执行,不会中断调用它的delete等上层控制器方法的流程。
当无权限用户触发删除逻辑时,authorize方法内虽然生成了重定向响应、写入了无权限提示,但这个响应没有被delete方法接收和返回,代码会继续向下执行删除逻辑、写入删除成功的Flash提示,最终走到方法末尾的重定向逻辑,就会出现同时显示两条提示、无权限也能删除数据的问题。
修复方法
你可以选择以下任意一种方案修复,推荐第二种,维护成本更低:
- 方案1:判断授权方法返回值,手动终止上层方法执行
保留现有authorize方法结构,在所有调用该方法的CRUD接口中接收返回值,如果拿到重定向响应就直接return终止后续流程,以delete方法为例:public function delete($id = null) { $this->request->allowMethod(['post', 'delete']); // 建议将请求方法校验挪到最前,提前拦截非法请求 $school = $this->Schools->get($id); // 校验授权结果,失败则直接返回重定向响应终止执行 $authResponse = $this->authorize($school); if ($authResponse) { return $authResponse; } if ($this->Schools->delete($school)) { $this->Flash->success(__("School has been successfully removed.")); } else { $this->Flash->error(__("The school could not be deleted. Please try again.")); } return $this->redirect(['action' => 'index']); } - 方案2:授权失败时抛出重定向异常,全局中断流程
这种方式不需要在每个调用授权的方法里写判断,只要授权失败就会直接终止整个请求流程,是更稳妥的写法。
首先在控制器头部引入重定向异常类:
然后修改use Cake\Http\Exception\RedirectException;authorize方法,捕获到权限异常后直接抛出重定向异常:
调整后你现有的delete方法不需要做额外修改,授权失败时会直接跳转,不会执行后续删除逻辑。private function authorize(School $s){ try{ $this->Authorization->authorize($s); } catch(ForbiddenException $e){ $this->Flash->error("You don't have permission."); // 抛出重定向异常,框架会直接处理跳转,不再执行后续业务代码 throw new RedirectException( $this->redirect(['controller' => 'Schools', 'action' => 'index'])->getHeaderLine('Location') ); } }
内容的提问来源于stack exchange,提问作者Alves Gustavo
相关产品推荐
相关产品推荐

