TP5.0、TP5.1 判断请求的模块、控制器、方法是否存在,不存在则友好输出提示信息

TP5.0 API接口时,对于前端人员错误请求时,我们应该判断请求的模块、控制器、方法是否存在,不存在则友好输出

新建 Base.php 所有的类都继承 Base.php 类 ,用于友好输出不存在的方法

<?php
	namespace app\index\controller;
	use think\Controller;
	class Base extends Controller
	{
	    public function _empty($name)
	    {
	        return show('404','请求的方法不存在',[],'404');
	    }
	}

新建Error.php 类,用于友好输出不存在的控制器
可修改config.php 下的 'empty_controller' => 'Error', 更改指定错误类名

<?php
	namespace app\index\controller;
	class Error
	{
	    public function _empty($name){
	        return show('404','请求的控制器不存在',[],'404');
	    }
	}

修改thinkphp/library/think/App.php 下的 module 方法 @GPS

<?php

 public static function module($result, $config, $convert = null)
    {
        if (is_string($result)) {
            $result = explode('/', $result);
        }

        $request = Request::instance();

        if ($config['app_multi_module']) {
            // 多模块部署
            $module    = strip_tags(strtolower($result[0] ?: $config['default_module']));
            $bind      = Route::getBind('module');
            $available = false;

            if ($bind) {
                // 绑定模块
                list($bindModule) = explode('/', $bind);

                if (empty($result[0])) {
                    $module    = $bindModule;
                    $available = true;
                } elseif ($module == $bindModule) {
                    $available = true;
                }
            } elseif (!in_array($module, $config['deny_module_list']) && is_dir(APP_PATH . $module)) {
                $available = true;
            }

            // 模块初始化
            if ($module && $available) {
                // 初始化模块
                $request->module($module);
                $config = self::init($module);

                // 模块请求缓存检查
                $request->cache(
                    $config['request_cache'],
                    $config['request_cache_expire'],
                    $config['request_cache_except']
                );
            } else {
                return show('404','请求的模块不存在',[],'404'); // @GPS
                throw new HttpException(404, 'module not exists:' . $module);
            }
        } else {
            // 单一模块部署
            $module = '';
            $request->module($module);
        }

        // 设置默认过滤机制
        $request->filter($config['default_filter']);

        // 当前模块路径
        App::$modulePath = APP_PATH . ($module ? $module . DS : '');

        // 是否自动转换控制器和操作名
        $convert = is_bool($convert) ? $convert : $config['url_convert'];

        // 获取控制器名
        $controller = strip_tags($result[1] ?: $config['default_controller']);

        if (!preg_match('/^[A-Za-z](\w|\.)*$/', $controller)) {
            return show('404','请求的控制器不存在',[],'404'); // @GPS
            throw new HttpException(404, 'controller not exists:' . $controller);
        }

        $controller = $convert ? strtolower($controller) : $controller;

        // 获取操作名
        $actionName = strip_tags($result[2] ?: $config['default_action']);
        if (!empty($config['action_convert'])) {
            $actionName = Loader::parseName($actionName, 1);
        } else {
            $actionName = $convert ? strtolower($actionName) : $actionName;
        }

        // 设置当前请求的控制器、操作
        $request->controller(Loader::parseName($controller, 1))->action($actionName);

        // 监听module_init
        Hook::listen('module_init', $request);

        try {
            $instance = Loader::controller(
                $controller,
                $config['url_controller_layer'],
                $config['controller_suffix'],
                $config['empty_controller']
            );
        } catch (ClassNotFoundException $e) {
            throw new HttpException(404, 'controller not exists:' . $e->getClass());
        }


        // 获取当前操作名
        $action = $actionName . $config['action_suffix'];
        $vars = [];
        // 判断类是否存在
        if (is_callable([$instance, $action])) {
            // 执行操作方法
            $call = [$instance, $action];

            $reflect = '';
            // 判断方法是否存在  @GPS
            try {
                // 严格获取当前操作方法名
                $reflect    = new \ReflectionMethod($instance, $action);
                //dump($reflect);
                // 判断方法是否为公开方法
                if(!$reflect->isPublic()){
                    if (is_callable([$instance, '_empty'])) {
                        // 空操作
                        $call = [$instance, '_empty'];
                        $vars = [$actionName];
                    }
                }
                $methodName = $reflect->getName();
                $suffix     = $config['action_suffix'];
                $actionName = $suffix ? substr($methodName, 0, -strlen($suffix)) : $methodName;
                $request->action($actionName);
            }catch (\ReflectionException $e){
                if (is_callable([$instance, '_empty'])) {
                    // 空操作
                    $call = [$instance, '_empty'];
                    $vars = [$actionName];
                }
            }




        } elseif (is_callable([$instance, '_empty'])) {
            // 空操作
            $call = [$instance, '_empty'];
            $vars = [$actionName];
        } else {
            // 操作不存在
            throw new HttpException(404, 'method not exists:' . get_class($instance) . '->' . $action . '()');
        }

        Hook::listen('action_begin', $call);

        return self::invokeMethod($call, $vars);
    }

TP5.1 判断请求的模块、控制器、方法是否存在,不存在则友好输出提示信息

新建控制器 Error.php , 用于空操作提示信息

<?php

	namespace app\index\controller;
	class Error 
	{
	    public function index($name){
	        return show(404,'请求的内容不存在',[],404);
	    }
	
	    public function _empty($name){
	        return $this->index($name);
	    }
	}

新建Base.php 基类,其他控制器继承基类

<?php

	namespace app\index\controller;	
	use think\Controller;	
	class Base extends Controller
	{
	    public function _empty($name){
	        return show(404,'请求的内容不存在',[],404);
	    }
	}

修改config.php

// 默认的空模块名
'empty_module'           => 'index',

// 默认的空控制器名
 'empty_controller'       => 'Error',

'exception_handle'       => '\app\lib\exception\ExceptionHandler',

新建ExceptionHandler 异常类

<?php

namespace app\lib\exception;

use Exception;
use think\exception\Handle;
use Log;
use think\Request;

class ExceptionHandler extends Handle
{
    private $code;
    private $msg;
    private $errorCode;

    public function render(Exception $e)
    {

        if ($e instanceof BaseException)
        {
            //如果是自定义异常,则控制http状态码,不需要记录日志
            //因为这些通常是因为客户端传递参数错误或者是用户请求造成的异常
            //不应当记录日志

            $this->code = $e->code;
            $this->msg = $e->msg;
            $this->errorCode = $e->errorCode;
        }
        else{
            // 如果是服务器未处理的异常,将http状态码设置为500,并记录日志
            if(config('app_debug')){
                // 调试状态下需要显示TP默认的异常页面,因为TP的默认页面
                // 很容易看出问题
                return parent::render($e);
            }

            $this->code = 500;
            $this->msg = '内部错误';
            $this->errorCode = 999;
            $this->recordErrorLog($e);
        }

        $request = new Request();

        $result = [
            'msg'  => $this->msg,
            'error_code' => $this->errorCode,
            'request_url' => $request = $request->url()
        ];

        return json($result, $this->code);
    }

    /*
     * 将异常写入日志
     */
    private function recordErrorLog(Exception $e)
    {
        Log::record($e->getMessage(),'error');
    }
}

本资源由随笔博客发布。发布者:五维国度,转载请注明出处:http://blog.suibi.site/archives/4299


本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

(0)
上一篇 2022年 12月 2日 上午11:13
下一篇 2022年 12月 2日 上午11:30

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

联系我们

在线咨询: QQ交谈

邮件:jctestxcx@163.com

关注微信