瀏覽代碼

Fixed:controller middleware bugs

朱金辉 2 年之前
父節點
當前提交
db4d8a6659

+ 2 - 2
demo/public/index.php

@@ -21,8 +21,8 @@ $app->setDB('configure/db.ini');
 Route::prefix("/admin")->setMiddleware(['\middleware\admin'])->group(function($route){
     $route->get("/user/login", function(){return "admin";});
     $route->get('/book/info', function(){return 'book/info';});
-    $route->get('/chapter/edit', ['admin\chapter\edit', 'index']);
-    $route->put('/chapter/add', 'admin\chapter\add');
+    $route->get('/profile/edit', ['admin\profile\edit', 'index']);
+    $route->put('/user/add', 'admin\user\add');
 });
 
 Route::prefix("/user")->setMiddleware(['\middleware\auth'])->group(function($route) {

+ 1 - 0
src/Application.php

@@ -523,6 +523,7 @@ class Application
         if ($next === false) {
             return $this;
         }
+
         //如果app.ini中设置了host的话,看host对应的controller路径
         $hosts = $this->appConfigure('hosts');
         if (!empty($hosts) && is_array($hosts) && count($hosts) > 0) {

+ 0 - 1
src/Autoloader/Import.php

@@ -51,7 +51,6 @@ class Import
             self::setIncludeFiles($file, $configure);
             return $configure;
         }else{
-            //print_r(debug_backtrace());
             throw new FileNotFound($file, 404);
         }
         return false;

+ 11 - 9
src/Base/Controller.php

@@ -7,6 +7,7 @@ namespace Qii\Base;
 
 use Qii\Autoloader\Factory;
 use \Qii\Autoloader\Psr4;
+use \Qii\View\Intf as viewIntf;
 
 /**
  * Qii_Controller_Abstract class
@@ -43,7 +44,7 @@ abstract class Controller
      */
     public $request;
     /**
-     * @var \Qii\Base\Response $response
+     * @var Response $response
      */
     public $response;
     /**
@@ -77,7 +78,7 @@ abstract class Controller
         $this->controllerId = $this->request->controller;
         $this->actionId = $this->request->action;
         $this->language = Factory::getInstance('\Qii\Language\Loader');
-        $this->response = Factory::getInstance('\Qii\Base\Response');
+        $this->response = Factory::getInstance('\Qii\Response\Http');
         $this->cache = new \stdClass();
         //载入model
         if ($this->enableDB) {
@@ -149,7 +150,7 @@ abstract class Controller
      */
     public function assign($key, $val = null)
     {
-        if(!$this->view && !($this->view instanceof \Qii\View\Intf)) {
+        if(!$this->view && !($this->view instanceof viewIntf)) {
             throw new \Exception(_i(6001), __LINE__);
         }
 
@@ -167,7 +168,7 @@ abstract class Controller
      */
     public function render($tpl, $arr = [])
     {
-        if(!$this->view && !($this->view instanceof \Qii\View\Intf)) {
+        if(!$this->view && !($this->view instanceof viewIntf)) {
             throw new \Exception(_i(6001), __LINE__);
         }
 
@@ -179,7 +180,7 @@ abstract class Controller
      * 设置 response
      * @param $request
      */
-    public function setResponse(\Qii\Base\Response $response)
+    public function setResponse(Response $response)
     {
         return $this->response = $response;
     }
@@ -188,7 +189,7 @@ abstract class Controller
      * 设置request
      * @param $request
      */
-    public function setRequest(\Qii\Base\Request $request)
+    public function setRequest(Request $request)
     {
         return $this->request = $request;
     }
@@ -214,11 +215,12 @@ abstract class Controller
      */
     protected function afterRun()
     {
+        print_r($this->response);
         if (!$this->response || !is_object($this->response)) {
             return;
         }
-        if ($this->response instanceof \Qii\Base\Response) {
-            if ($this->response->needRender() && $this->view && $this->view instanceof \Qii\View\Intf) {
+        if ($this->response instanceof Response) {
+            if ($this->response->needRender() && $this->view && $this->view instanceof viewIntf) {
                 $this->response->setRender($this->view);
             }
             $this->response->response();
@@ -287,7 +289,7 @@ abstract class Controller
      */
     public function __destruct()
     {
-        $this->afterRun($this->controllerId, $this->actionId);
+        $this->afterRun();
         if ($this->request && $this->request->isForward()) {
             $this->request->setForward(false);
             \Qii::getInstance()->dispatcher->setRequest($this->request);

+ 55 - 48
src/Base/Dispatcher.php

@@ -1,6 +1,8 @@
 <?php
 namespace Qii\Base;
 
+use Qii\Autoloader\Factory;
+use Qii\Autoloader\Psr4;
 use \Qii\Config\Register;
 use \Qii\Config\Consts;
 use Qii\Exceptions\MethodNotFound;
@@ -93,63 +95,68 @@ class Dispatcher
             $funcArgs = array_slice($args, 2);
         }
         array_unshift($funcArgs, $controllerName);
-        $psr4 = \Qii\Autoloader\Psr4::getInstance();
+        $psr4 = Psr4::getInstance();
         $controllerCls = call_user_func_array(array($psr4, 'loadClass'), $funcArgs);
 
         /**middleWare**/
         $this->getMiddleWare($controllerCls)->gatherMiddleware();
-        $pipeline = array_reduce($this->requestMiddleWare,function ($carry, $item){
+
+        $next = array_reduce($this->requestMiddleWare,function ($carry, $item){
             return function () use ($carry, $item){
                 return _loadClass($item)->handle(\Qii::getInstance()->request, $carry);
             };
-        }, function($funcArgs, $controllerCls, $psr4, $controller, $action){$method = new \ReflectionMethod($this, 'dispatch');
-            foreach($method->getParameters() as $property)
-            {
-                $param = $property->getName();
-                $this->request->setParam($param, $$param);
-            }
-            $this->controllerCls = $controllerCls;
-            $this->controllerCls->setRequest($this->request);
-            $this->controllerCls->controller = $controllerCls;
-            $this->controllerCls->controllerId = $controller;
-            $this->controllerCls->actionId = $action;
-
-            //查看是否设置了当前action的对应关系,如果设置了就走对应关系里边的,否则走当前类中的
-            if ($this->controllerCls->actions
-                && isset($this->controllerCls->actions[$action])
-                && $this->controllerCls->actions[$action]) {
-                $actionArgs = array();
-                $actionArgs[] = $this->controllerCls->actions[$action];
-                $actionCls = call_user_func_array(array($psr4, 'loadClass'), $actionArgs);
-                $this->actionCls = $actionCls;
-                $this->actionCls->setRequest($this->request);
-                $this->actionCls->controller = $this->controllerCls;
-                $this->actionCls->actionId = $action;
-                $this->actionCls->controllerId = $this->controllerCls->controllerId;
-                //支持多个action对应到同一个文件,如果对应的文件中存在指定的方法就直接调用
-                if (method_exists($this->actionCls, $action . Register::get(Consts::APP_DEFAULT_ACTION_SUFFIX))) {
-                    $this->actionCls->response = $response = call_user_func_array(array($this->actionCls, $action. Register::get(Consts::APP_DEFAULT_ACTION_SUFFIX)), $funcArgs);
-                }
-                if(method_exists($this->actionCls, 'initialization')) {
-                    call_user_func_array(array($this->actionCls, 'initialization'), array($this->actionCls));
-                }
-                if (!method_exists($this->actionCls, 'run')) {
-                    throw new MethodNotFound(\Qii::i(1101, $this->controllerCls->actions[$action] . '->run'), __LINE__);
-                }
-                return call_user_func_array(array($this->actionCls, 'run'), array_slice($funcArgs, 1));
-            }
+        }, function(){
+            return true;
+        })();
+
+        if ($next === false) {
+            return false;
+        }
 
-            if(method_exists($this->controllerCls, 'initialization')) {
-                call_user_func_array(array($this->controllerCls, 'initialization'), array($this->controllerCls));
+        $method = new \ReflectionMethod($this, 'dispatch');
+        foreach($method->getParameters() as $property)
+        {
+            $param = $property->getName();
+            $this->request->setParam($param, $$param);
+        }
+        $this->controllerCls = $controllerCls;
+        $this->controllerCls->setRequest($this->request);
+        $this->controllerCls->controller = $controllerCls;
+        $this->controllerCls->controllerId = $controller;
+        $this->controllerCls->actionId = $action;
+
+        //查看是否设置了当前action的对应关系,如果设置了就走对应关系里边的,否则走当前类中的
+        if ($this->controllerCls->actions
+            && isset($this->controllerCls->actions[$action])
+            && $this->controllerCls->actions[$action]) {
+            $actionArgs = array();
+            $actionArgs[] = $this->controllerCls->actions[$action];
+            $actionCls = call_user_func_array(array($psr4, 'loadClass'), $actionArgs);
+            $this->actionCls = $actionCls;
+            $this->actionCls->setRequest($this->request);
+            $this->actionCls->controller = $this->controllerCls;
+            $this->actionCls->actionId = $action;
+            $this->actionCls->controllerId = $this->controllerCls->controllerId;
+            //支持多个action对应到同一个文件,如果对应的文件中存在指定的方法就直接调用
+            if (method_exists($this->actionCls, $action . Register::get(Consts::APP_DEFAULT_ACTION_SUFFIX))) {
+                $this->actionCls->response = call_user_func_array(array($this->actionCls, $action. Register::get(Consts::APP_DEFAULT_ACTION_SUFFIX)), $funcArgs);
+            }
+            if(method_exists($this->actionCls, 'initialization')) {
+                call_user_func_array(array($this->actionCls, 'initialization'), array($this->actionCls));
             }
-            array_shift($funcArgs);
-            $actionName = $action . Register::get(Consts::APP_DEFAULT_ACTION_SUFFIX);
-            if (!method_exists($this->controllerCls, $actionName) && !method_exists($this->controllerCls, '__call')) {
-                throw new MethodNotFound(\Qii::i(1101, $controller . '->' . $actionName), __LINE__);
+            if (!method_exists($this->actionCls, 'run')) {
+                throw new MethodNotFound(\Qii::i(1101, $this->controllerCls->actions[$action] . '->run'), __LINE__);
             }
-            $this->controllerCls->response = $response = call_user_func_array(array($this->controllerCls, $actionName), $funcArgs);
-            return $response;
-        });
-        return call_user_func($pipeline, $funcArgs, $controllerCls, $psr4, $controller, $action);
+            return call_user_func_array(array($this->actionCls, 'run'), array_slice($funcArgs, 1));
+        }
+        if(method_exists($this->controllerCls, 'initialization')) {
+            call_user_func_array(array($this->controllerCls, 'initialization'), array($this->controllerCls));
+        }
+        array_shift($funcArgs);
+        $actionName = $action . Register::get(Consts::APP_DEFAULT_ACTION_SUFFIX);
+        if (!method_exists($this->controllerCls, $actionName) && !method_exists($this->controllerCls, '__call')) {
+            throw new MethodNotFound(\Qii::i(1101, $controller . '->' . $actionName), __LINE__);
+        }
+        return call_user_func_array(array($this->controllerCls, $actionName), $funcArgs);
     }
 }

+ 0 - 22
src/Base/Middleware.php

@@ -1,22 +0,0 @@
-<?php
-namespace Qii\Base;
-
-use Closure;
-
-/**
- * middleware 中间件
- */
-class Middleware {
-    /**
-     * @var array $middleware 全局middleware
-     */
-    public $middleware = [];
-    /**
-     * @var array $middlewareGroup 中间件
-     */
-    public $middlewareGroup = [];
-    /**
-     * @var array route route中间件
-     */
-    public $routeMiddleware = [];
-}

+ 22 - 12
src/Base/Response.php

@@ -2,7 +2,7 @@
 
 namespace Qii\Base;
 
-use controller\base;
+use Qii\Response\Cli;
 
 class Response
 {
@@ -36,7 +36,7 @@ class Response
      * Determine to send the headers or not
      * @var bool $_sendHeader 是否发送头信息
      */
-    protected $_sendHeader = false;
+    protected $_sendHeader = true;
     /**
      * @var bool|string 返回数据格式
      */
@@ -55,7 +55,15 @@ class Response
      */
     public function setRender(\Qii\View\Intf $render)
     {
-        \Qii\Base\Response::$render = $render;
+        Response::$render = $render;
+    }
+
+    /**
+     * @param bool $isSend 是否发送头信息
+     * @return void
+     */
+    public function setSendHeader($isSend = true) {
+        $this->_sendHeader = $isSend;
     }
     
     /**
@@ -180,16 +188,17 @@ class Response
                     if (is_array($this->data['body'])) {
                         $body = '';
                         if (isset($this->data['body']['render']) && $this->data['body']['render'] instanceof \Qii\View\Intf) {
-                            \Qii\Base\Response::$render = $this->data['body']['render'];
+                            Response::$render = $this->data['body']['render'];
                         }
                         
-                        if (\Qii\Base\Response::$render != null && \Qii\Base\Response::$render instanceof \Qii\View\Intf) {
+                        if (Response::$render != null && Response::$render instanceof \Qii\View\Intf) {
                             $tplData = isset($this->data['body']['tplData']) ? $this->data['body']['tplData'] : [];
-                            \Qii\Base\Response::$render->assign($tplData);
-                            $body = \Qii\Base\Response::$render->fetch($this->data['body']['tpl']);
+                            Response::$render->assign($tplData);
+                            $body = Response::$render->fetch($this->data['body']['tpl']);
                         }
                     }
-                    echo(IS_CLI ? (new \Qii\Response\Cli())->stdout($body) : $body);
+                    $this->setBody($body);
+                    echo(IS_CLI ? (new Cli())->stdout($body) : $body);
                     break;
             }
             return;
@@ -197,8 +206,8 @@ class Response
         if ($this->_sendHeader) {
             $this->sendHeaders();
         }
-        foreach ($this->body as $key => $body) {
-            echo IS_CLI ? new \Qii\Response\Cli($body) : $body;
+        foreach ($this->body as $body) {
+            echo IS_CLI ? new Cli($body) : $body;
         }
     }
 
@@ -246,7 +255,7 @@ class Response
      * @param boolean $replace 如果存在是否替换
      * @return $this
      */
-    public function setHeader($name, $value, $replace = false)
+    public function setHeader($name, $value, $replace = true)
     {
         $name = $this->_normalizeHeader($name);
         $value = (string)$value;
@@ -323,12 +332,13 @@ class Response
      */
     protected function sendHeaders()
     {
-        foreach ($this->headers as $header) {
+        foreach ($this->headers as $key => $header) {
             header(
                 $header['name'] . ': ' . $header['value'],
                 $header['replace']
             );
         }
+        $this->clearHeaders();
         return $this;
     }
 }

+ 11 - 8
src/Base/Route.php

@@ -143,7 +143,7 @@ class Route
      * @param $request
      * @return bool
      */
-    public function match(Http $request) {
+    public function match(Http $request, $next) {
         $route = $this->getStoredRoute();
         $method = strtoupper($request->getMethod());
         $uri = $request->getRequestUri();
@@ -169,19 +169,22 @@ class Route
             }
         }
         if (!$callable || count($middleware) == 0) {
-            return true;
+            return $next($request);
         }
+        //命中后,执行相应程序后就不网下周
         $middleware = array_reverse(array_unique($middleware));
-        $pipe = array_reduce($middleware, function ($carry, $item){
+        $result = array_reduce($middleware, function ($carry, $item){
             return function () use ($carry, $item){
                 return _loadClass($item)->handle(\Qii::getInstance()->request, $carry);
             };
         }, function(){
             return true;
-        });
-        $result = call_user_func($pipe);
+        })();
         if (!$result) return false;
-        return $this->make($callable);
+        if (!$this->make($callable)){
+            return $next($request);
+        }
+        return false;
     }
 
     /**
@@ -203,9 +206,9 @@ class Route
                 break;
         }
         if ($callable) {
-            return false;
+            return true;
         }
-        return true;
+        return false;
     }
 
     /**

+ 116 - 0
src/Base/Rules.php

@@ -1,5 +1,35 @@
 <?php
 namespace Qii\Base;
+
+use Qii\Execptions;
+
+/**
+ * @method bool addRequiredFields(array $data = [string, string, bool|string|int], array $data=[...])  [string $field string $msg string $extparam],...
+ * @method bool addEmailFields(array $data = [string, string, bool|string|int], array $data=[...])  [string $field string $msg string $extparam],...
+ * @method bool addIdCodeFields(array $data = [string, string, bool|string|int], array $data=[...])  [string $field string $msg string $extparam],...
+ * @method bool addHttpFields(array $data = [string, string, bool|string|int], array $data=[...])  [string $field string $msg string $extparam],...
+ * @method bool addQQFields(array $data = [string, string, bool|string|int], array $data=[...])  [string $field string $msg string $extparam],...
+ * @method bool addPostCodeFields(array $data = [string, string, bool|string|int], array $data=[...])  [string $field string $msg string $extparam],...
+ * @method bool addIpFields(array $data = [string, string, bool|string|int], array $data=[...])  [string $field string $msg string $extparam],...
+ * @method bool addPhoneFields(array $data = [string, string, bool|string|int], array $data=[...])  [string $field string $msg string $extparam],...
+ * @method bool addTelephoneFields(array $data = [string, string, bool|string|int], array $data=[...])  [string $field string $msg string $extparam],...
+ * @method bool addMobileFields(array $data = [string, string, bool|string|int], array $data=[...])  [string $field string $msg string $extparam],...
+ * @method bool addEnFields(array $data = [string, string, bool|string|int], array $data=[...])  [string $field string $msg string $extparam],...
+ * @method bool addCnFields(array $data = [string, string, bool|string|int], array $data=[...])  [string $field string $msg string $extparam],...
+ * @method bool addAccoundFields(array $data = [string, string, bool|string|int], array $data=[...])  [string $field string $msg string $extparam],...
+ * @method bool addNumberFields(array $data = [string, string, bool|string|int], array $data=[...])  [string $field string $msg string $extparam],...
+ * @method bool addDateFields(array $data = [string, string, bool|string|int], array $data=[...])  [string $field string $msg string $extparam],...
+ * @method bool addSafeFields(array $data = [string, string, bool|string|int], array $data=[...])  [string $field string $msg string $extparam],...
+ * @method bool addPasswordFields(array $data = [string, string, bool|string|int], array $data=[...])  [string $field string $msg string $extparam],...
+ * @method bool addMaxLengthFields(array $data = [string, string, bool|string|int], array $data=[...])  [string $field string $msg string $extparam],...
+ * @method bool addMinLengthFields(array $data = [string, string, bool|string|int], array $data=[...])  [string $field string $msg string $extparam],...
+ * @method bool addLengthFields(array $data = [string, string, bool|string|int], array $data=[...])  [string $field string $msg string $extparam],...
+ * @method bool addRangeofFields(array $data = [string, string, bool|string|int], array $data=[...])  [string $field string $msg string $extparam],...
+ * @method bool addStringFields(array $data = [string, string, bool|string|int], array $data=[...])  [string $field string $msg string $extparam],...
+ * @method bool addSets(array $data = [string, string, bool|string|int], array $data=[...])  [string $field string $msg string $extparam],...
+ * @method bool addSetsArray(array $data = [string, string, bool|string|int], array $data=[...])  [string $field string $msg string $extparam],...
+ *
+ */
 class Rules 
 {
     /**
@@ -153,6 +183,49 @@ class Rules
             $this->addRules($field, $key, $valid, $message);
         }
     }
+
+    /**
+     * 添加必须验证的字段
+     *
+     * @param array $fields ['field', 'xx不能为空']
+     * @return void
+     */
+    /*
+    public function addRequiredFields($fields = array()) {
+        if (!is_array($fields)) {
+            return false;
+        }
+        foreach ($fields as $value) {
+            if(count($value) == 1) {
+                $value[1] = $value[0] . "字段不能为空";
+            }
+            $this->rules[$value[0]]['required'] =  true;
+            $this->message[$value[0]]['required'] = $value[1];
+        }
+        return true;
+    }*/
+
+    /**
+     * 批量添加safe验证字段
+     *
+     * @param array $fields [['fields', 'xx不能包含怪字符'], ...]
+     * @return false|void
+     */
+    /*
+    public function addSafeFields($fields = array()) {
+        if (!is_array($fields)) {
+            return false;
+        }
+
+        foreach ($fields as $value) {
+            if(count($value) == 1) {
+                $value[1] = $value[0] . "字段不能包含怪字符";
+            }
+            $this->rules[$value[0]]['safe'] =  true;
+            $this->message[$value[0]]['safe'] = $value[1];
+        }
+    }*/
+
     /**
      * 添加规则
      * @param string $field 验证字段
@@ -386,4 +459,47 @@ class Rules
         );
         return in_array($key, $allow);
     }
+
+    /**
+     * 添加验证
+     *
+     * @param string $validKey valid
+     * @param array $args [['field', 'msg', validExtParam],...], make(length, [['field', 'msg', 10], ...])
+     * @return false|void
+     */
+    public function make($validKey, $args) {
+        if(!is_array($args)) {
+            return false;
+        }
+        foreach ($args as $value) {
+            if(count($value) == 0) {
+                continue;
+            }
+            if(count($value) == 1) {
+                $value[1] = $value[0] .'格式不正确';
+                $value[2] = true;
+            }else if(count($value) == 2) {
+                $value[2] = true;
+            }
+            $this->addRules($value[0], $validKey, $value[2], $value[1]);
+        }
+    }
+
+    /**
+     * 快捷添加验证
+     * @param string $method 验证方法
+     * @param array $args 参数
+     * @return mixed
+     */
+    public function __call($method, $args) {
+        preg_match("/add(.*)Fields/", $method, $matches);
+        if(!$matches || count($matches) < 2) {
+            throw new MethodNotFound($method ." does not found");
+        }
+        $validKey = strtolower($matches[1]);
+        if (!$this->isAllow($validKey)) {
+            throw new MethodNotFound($method ." does not found");
+        }
+        return call_user_func_array(array($this, 'make'), array($validKey, $args));
+    }
 }

+ 0 - 53
src/Conf/namespace.php

@@ -1,53 +0,0 @@
-<?php
-/**
- * Qii 名称空间配置
- * @author zjh
- * @version 1.3
- */
-return array(
-    //设置是否使用名称空间
-    'setUseNamespace' => array(
-        array('Qii\\', true),
-        array('Qii\Action', true),
-        array('Qii\Autoloader', true),
-        array('Qii\Bootstrap', true),
-        array('Qii\Config', true),
-        array('Qii\Consts', true),
-        array('Qii\Controller', true),
-        array('Qii\Exceptions', true),
-        array('Qii\Language', true),
-        array('Qii\Library', true),
-        array('Qii\Logger', true),
-        array('Qii\Plugin', true),
-        array('Qii\Request', false),
-        array('Qii\Router', true),
-        array('Qii\View', true),
-        array('WhichBrowser', true),
-        array('BigPipe', true),
-        array('Smarty\\', false),
-        array('Smarty\\Internal', false),
-    ),
-    //设置指定名称空间的文件路径,如按照namespace的不用指定
-    'addNamespace' => array(
-        array('Qii\\', Qii_DIR . DS),
-        array('Qii\Action', Qii_DIR . DS . 'Action'),
-        array('Qii\Autoloader', Qii_DIR . DS . 'Autoloader'),
-        array('Qii\Controller', Qii_DIR . DS . 'Controller'),
-        array('Qii\Bootstrap', Qii_DIR . DS . 'Bootstrap'),
-        array('Qii\Config', Qii_DIR . DS . 'Config'),
-        array('Qii\Consts', Qii_DIR . DS . 'Consts'),
-        array('Qii\Exceptions', Qii_DIR . DS . 'Exceptions'),
-        array('Qii\Language', Qii_DIR . DS . 'Language'),
-        array('Qii\Library', Qii_DIR . DS . 'Library'),
-        array('Qii\Logger', Qii_DIR . DS . 'Logger'),
-        array('Qii\Plugin', Qii_DIR . DS . 'Plugin'),
-        array('Qii\Request', Qii_DIR . DS . 'Request'),
-        array('Qii\Response', Qii_DIR . DS . 'Response'),
-        array('Qii\Router', Qii_DIR . DS . 'Router'),
-        array('Qii\View', Qii_DIR . DS . 'View'),
-        array('Smarty', Qii_DIR . DS . 'View' . DS . 'smarty'),
-        array('Smarty', Qii_DIR . DS . 'View' . DS . 'smarty' . DS . 'sysplugins'),
-        array('WhichBrowser', Qii_DIR . DS . 'Library'. DS . 'Third'. DS . 'WhichBrowser'),
-        array('BigPipe', Qii_DIR . DS . 'Library'. DS .'BigPipe'. DS .'BigPipe')
-    )
-);

+ 0 - 10
src/Config/Consts.php

@@ -9,27 +9,17 @@ namespace Qii\Config;
 class Consts
 {
 	const VERSION = '1.2';
-	const APP_SYS = 'Qii';//框架名,用户保存框架实例化对象
 	const APP_ENVIRONS = 'QII_ENVIRONS';//配置文件使用环境
 	const APP_ENVIRON = 'QII_ENVIRON';//当前系统使用的环境
 	const APP_DEFAULT_ENVIRON = 'product';//默认系统环境
 	const APP_DB = 'QII_APP_DB';//数据库配置
-	const APP_CONFIGURE = 'AppConfigure';//系统配置,不能修改为其他值,默认会调用此方法
 	const APP_LOADED_FILE = 'QII_APP_LOADED_FILE';//加载的文件列表
 	const APP_INI_FILE = 'QII_APP_INI_FILE';//网站配置文件列表
-	const APP_INCLUDES_FILE = 'QII_APP_INCLUDES_FILE';//保存includes过的文件列表
 	const APP_SITE_METHOD = 'rewriteMethod';//网站路由
 	const APP_SITE_ROUTER = 'QII_APP_SITE_ROUTER';//网站路由
-	const APP_DISPATCHER = 'Qii_Dispatcher';
-	const APP_SYS_DISPATCHER = 'QII_APP_SYS_DISPATCHER';
-	const APP_LOAD_PREFIX = 'Qii_Load_';//不能随意修改
-	const APP_LOAD_SYS_PREFIX = 'Qii_Load_Qii_';//不能随意修改
 	const APP_CACHE_PATH = 'QII_CACHE_PATH';//App缓存目录
-	const APP_CACHE_SYSTEM_PATH = 'QII_CACHE_SYSTEM_PATH';//框架缓存目录
 	const APP_INI = 'app.ini';//网站配置文件
 	const APP_LANGUAGE_CONFIG = 'QII_LANGUAGE_CONFIG';//语言包
-	const APP_OUTPUT_CHARSET = 'utf-8';
-	const APP_VIEW = 'QII_VIEW';//controller->_view
 	const APP_DEFAULT_CONTROLLER = 'APP_DEFAULT_CONTROLLER';//默认controller
 	const APP_DEFAULT_CONTROLLER_PREFIX = 'APP_DEFAULT_CONTROLLER_PREFIX';//默认controller
 	const APP_DEFAULT_ACTION = 'APP_DEFAULT_ACTION';//默认Action

+ 1 - 1
src/Config/Register.php

@@ -329,7 +329,7 @@ class Register
 	/**
 	 * 获取网站的配置信息
 	 *
-	 * @return Array
+	 * @return Array|mixed
 	 */
 	public static function getAppConfigure($iniFile = Consts::APP_INI, $key = NULL)
 	{

+ 8 - 7
src/Driver/Base.php

@@ -3,6 +3,7 @@
 namespace Qii\Driver;
 use Qii\Autoloader\Psr4;
 use Qii\Exceptions\InvalidParams;
+use Qii\Exceptions\MethodNotFound;
 
 /**
  * Class Base
@@ -1167,18 +1168,18 @@ class Base
     /**
      * 如果不存在指定的方法则调用提示错误
      *
-     * @param String $name
-     * @param Mix $args
-     * @return Mix
+     * @param string $method
+     * @param mixd $args
+     * @return mixed
      */
-    public function __call($method, $argvs)
+    public function __call($method, $args)
     {
         if (isset($this->_modelAlias[$method])) {
             if (method_exists($this, $this->_modelAlias[$method])) {
-                return call_user_func_array(array($this, $this->_modelAlias[$method]), $argvs);
+                return call_user_func_array(array($this, $this->_modelAlias[$method]), $args);
             }
-            \Qii::setError(false, __LINE__, 1506, 'Alias ' . get_called_class() . '->' . $method . '()');
+            return \Qii::setError(false, __LINE__, 1506, 'Alias ' . get_called_class() . '->' . $method . '() not found');
         }
-        \Qii::setError(false, __LINE__, 1506, get_called_class() . '->' . $method . '()');
+        return \Qii::setError(false, __LINE__, 1506, get_called_class() . '->' . $method . '() not found');
     }
 }

+ 17 - 12
src/Exceptions/Error.php

@@ -1,6 +1,10 @@
 <?php
 namespace Qii\Exceptions;
 
+use Qii\Autoloader\Import;
+use Qii\Autoloader\Psr4;
+use Qii\Config\Register;
+
 if (class_exists('\Qii\Exceptions\Error', false)) {
     return;
 }
@@ -87,10 +91,14 @@ class Error
         if ($condition) {
             return false;
         }
+        if ($msg === null && $args !== null) {
+            $msg = is_array($args) ? ("\t Error occurred:". join("\n\t", $args)) : "Error occurred: ". $args;
+        }
         $appConfigure = \Qii::appConfigure();
         //如果是调试模式就直接抛出异常
         $isDebug = $appConfigure['debug'];
         $message = array();
+        $message[] = $msg;
         $message[] = explode("\n", self::getTraceAsString());
         if (\Qii::getInstance()->loggerWriter != null) {
             $message[] = 'Referer:' . (isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : \Qii::getInstance()->request->url->getCurrentURL());
@@ -101,28 +109,25 @@ class Error
             throw new \Exception(call_user_func_array(array('\Qii', 'i'), $args), $line);
         }
         $errorPage = $appConfigure['errorPage'];
-        $env = \Qii\Config\Register::get(\Qii\Config\Consts::APP_ENVIRON, 'dev');
+        $env = Register::get(\Qii\Config\Consts::APP_ENVIRON, 'dev');
         if ($env != 'product' && $errorPage != null) {
             list($controller, $action) = explode(':', $appConfigure['errorPage']);
             $controllerCls = $controller;
             if(substr($controller, 0, 1) != '\\') {
-                $controllerCls = \Qii\Config\Register::get(\Qii\Config\Consts::APP_DEFAULT_CONTROLLER_PREFIX) . '\\' . $controller;
+                $controllerCls = Register::get(\Qii\Config\Consts::APP_DEFAULT_CONTROLLER_PREFIX) . '\\' . $controller;
             }
             $action = preg_replace('/(Action)$/i', "", $action);
-            $filePath = \Qii\Autoloader\Psr4::getInstance()->searchMappedFile($controllerCls);
+            $filePath = Psr4::getInstance()->searchMappedFile($controllerCls);
             if (!is_file($filePath)) {
                 if ($env == 'product') return '';
-                \Qii\Autoloader\Import::requires(Qii_DIR . DS . 'Exceptions' . DS . 'Error.php');
+                Import::requires(Qii_DIR . DS . 'Exceptions' . DS . 'Error.php');
                 call_user_func_array(array('\Qii\Exceptions\Error', 'index'), array($controller, $action));
-                die();
-            } else {
-                \Qii::getInstance()->request->setControllerName($controller);
-                \Qii::getInstance()->request->setActionName($action);
-                \Qii::getInstance()->dispatcher->setRequest(\Qii::getInstance()->request);
-                \Qii::getInstance()->dispatcher->dispatch($controller, $action, new \Exception($msg ? $msg : self::getTraceAsString(), $code));
-                die();
+                exit();
             }
-            return;
+            \Qii::getInstance()->request->setControllerName($controller);
+            \Qii::getInstance()->request->setActionName($action);
+            \Qii::getInstance()->dispatcher->setRequest(\Qii::getInstance()->request);
+            \Qii::getInstance()->dispatcher->dispatch($controller, $action, new \Exception($msg ."\n". self::getTraceAsString(), $code));
         }
         return true;
     }

+ 44 - 0
src/Functions/Funcs.php

@@ -175,4 +175,48 @@ function toUTF8($str)
 function toGBK($str)
 {
 	return convertCode($str, 'GBK');
+}
+
+/**
+ * 字符串是否包含
+ *
+ * @param string $haystack
+ * @param string $needle
+ * @return bool
+ */
+function str_contains(string $haystack, string $needle)
+{
+    return '' === $needle || false !== strpos($haystack, $needle);
+}
+
+/**
+ * 以xxx开头
+ * @param string $haystack
+ * @param string $needle
+ * @return bool
+ */
+function str_starts_with($haystack, $needle)
+{
+    return 0 === strncmp($haystack, $needle, \strlen($needle));
+}
+
+/**
+ * 以xx结尾
+ * @param string $haystack
+ * @param string $needle
+ * @return bool
+ */
+function str_ends_with($haystack, $needle)
+{
+    if ('' === $needle || $needle === $haystack) {
+        return true;
+    }
+
+    if ('' === $haystack) {
+        return false;
+    }
+
+    $needleLength = \strlen($needle);
+
+    return $needleLength <= \strlen($haystack) && 0 === substr_compare($haystack, $needle, -$needleLength);
 }

+ 2 - 2
src/Qii.php

@@ -138,7 +138,7 @@ class Qii extends Application
     /**
      * 返回当前app的配置
      * @param string $key 如果需要返回单独的某一个key就指定一下这个值
-     * @return Mix
+     * @return mixed
      */
     public static function appConfigure($key = null)
     {
@@ -200,7 +200,7 @@ if (!function_exists('catch_fatal_error')) {
 }
 
 //注册名称空间
-$namespace = _include(Qii_DIR . DS . 'Conf' . DS . 'namespace.php');
+$namespace = _include(Qii_DIR . DS . 'Config' . DS . 'Namespace.php');
 Psr4::getInstance()
     ->register()
     ->setUseNamespaces($namespace['setUseNamespace'] ?? [])

+ 3 - 1
src/Response/Cli.php

@@ -1,7 +1,9 @@
 <?php
 namespace Qii\Response;
 
-class Cli extends \Qii\Base\Response
+use Qii\Base\Response;
+
+class Cli extends Response
 {
     public function __construct($body = null)
     {

+ 7 - 5
src/Response/Http.php

@@ -1,9 +1,11 @@
 <?php
 namespace Qii\Response;
 
+use Qii\Exceptions\Response;
+
 class Http extends \Qii\Base\Response
 {
-    protected $_sendheader = true;
+    protected $_sendHeader = true;
     protected $_responseCode = 200;
 
     /**
@@ -15,7 +17,7 @@ class Http extends \Qii\Base\Response
     public function setResponseCode($code)
     {
         if (!is_int($code) || (100 > $code) || (599 < $code)) {
-            throw new \Qii\Exceptions\Response('Invalid HTTP response code');
+            throw new Response('Invalid HTTP response code');
         }
 
         $this->_responseCode = $code;
@@ -39,15 +41,15 @@ class Http extends \Qii\Base\Response
      * If an {@link setResponseCode() HTTP response code}
      * has been specified, it is sent with the first header.
      *
-     * @return Qii_Response_Http
+     * @return Qii\Response\Http
      */
     protected function sendHeaders()
     {
         $httpCodeSent = false;
-        if (!$this->_sendheader) {
+        if (!$this->_sendHeader || !is_array($this->headers)) {
             return $this;
         }
-        foreach ($this->_headers as $header) {
+        foreach ($this->headers as $header) {
             if (!$httpCodeSent && $this->_responseCode) {
                 header(
                     $header['name'] . ': ' . $header['value'],