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

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

新建 Base.php 所有的类都继承 Base.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', 更改指定错误类名

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

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

 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 , 用于空操作提示信息

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

新建Base.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 异常类

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');
    }
}

猜你喜欢

转载自blog.csdn.net/lows_H/article/details/107937996