Zhu Jinhui před 7 roky
rodič
revize
b981596ea2

+ 10 - 0
Qii/Action/Base.php

@@ -0,0 +1,10 @@
+<?php
+namespace Qii\Action;
+
+class Base 
+{
+    public function __construct()
+    {
+
+    }
+}

+ 298 - 24
Qii/Application.php

@@ -16,11 +16,23 @@ class Application
     /**
      * @var string $workspace 工作目录
      */
-    private static $workspace = './';
+    private static $workspace = './';/**
+     * @var string $env 环境变量
+     */
+    public static $env = 'product';
+    /**
+     * @var array $paths 网站使用的路径
+     */
+    public static $paths = array('configure', 'controller', 'model', 'view', 'plugins', 'tmp');
+
+    /**
+     * Qii\Request\Url
+     */
+    public $request;
 
 	public function __construct()
 	{
-		
+        $this->helper = \Qii\Autoloader\Psr4::getInstance()->loadClass('\Qii\Autoloader\Helper');
 	}
 
     /**
@@ -33,6 +45,38 @@ class Application
 	    return \Qii\Autoloader\Factory::getInstance('\Qii\Application');
 	}
 
+    /**
+     * 设置网站运行环境
+     *
+     * @param string $env 网站环境
+     * @return $this
+     */
+    public function setEnv($env)
+    {
+        self::$env = $env;
+        return $this;
+    }
+    /**
+     * 设置缓存文件路径
+     * @param string $path 缓存路径
+     */
+    public function setCachePath($path)
+    {
+        \Qii\Config\Register::set(\Qii\Consts\Config::APP_CACHE_PATH, $this->getCachePath($path));
+        return $this;
+    }
+
+    /**
+     * 保存网站的配置文件
+     *
+     * @param $iniFile
+     */
+    public function setAppIniFile($iniFile)
+    {
+        \Qii\Config\Register::set(\Qii\Consts\Config::APP_INI_FILE, $iniFile);
+        return $this;
+    }
+
     /**
      * 设置网站的工作目录,可以通过此方法将网站的重要文件指向到其他目录
      *
@@ -56,49 +100,279 @@ class Application
 
         return $this;
     }
-
+    /**
+     * 获取指定路径的缓存绝对路径
+     * @param string $path 路径
+     * @return string 绝对路径
+     */
+    public function getCachePath($path)
+    {
+        if (self::$workspace != '') return self::$workspace . DS . $path;
+        $dir = '';
+        $workspace = \Qii\Autoloader\Psr4::getInstance()->getNamespace('workspace');
+        foreach ($workspace AS $dir) {
+            if (is_dir($dir)) $dir = $dir;
+        }
+        return $dir . DS . $path;
+    }
+    /**
+     * 获取网站运行环境
+     *
+     * @return string
+     */
+    public function getEnv()
+    {
+        return self::$env;
+    }
+    /**
+     * 获取当前工作目录
+     */
     public function getWorkspace()
     {
         return self::$workspace;
     }
+    /**
+     * 获取网站的配置文件
+     * @return Mix
+     */
+    public function getAppIniFile()
+    {
+        return \Qii\Config\Register::get(\Qii\Consts\Config::APP_INI_FILE);
+        return $this;
+    }
+
     /**
      * 设置网站配置文件
+     * @param string $ini 配置文件路径
+     * @param string $env 环境
      *
-     * @param array $config 配置文件
      */
-	public function setConfig($key, $config = [])
-	{
-        \Qii\Autoloader\Factory::getInstance('\Qii\Config\Arrays')
-            ->set(\Qii\Consts\Config::APP_CONFIGURE . '['. $key.']', $config);
-	}
+    public function setAppConfigure($ini, $env = '')
+    {
+        if ($env == '') $env = $this->getEnv();
+        $ini = \Qii\Autoloader\Psr4::getInstance()->getFileByPrefix($ini);
+        $this->setAppIniFile($ini);
+        if (!\Qii\Config\Register::setAppConfigure(
+            $ini,
+            $env
+        )
+        ) throw new \Qii\Exceptions\FileNotFound(\Qii::i(1405, $ini), __LINE__);
+        //载入request方法
+        $this->request = \Qii\Autoloader\Psr4::getInstance()->loadClass('\Qii\Request\Http');
+        \Qii\Config\Setting::getInstance()->setDefaultTimeZone();
+        \Qii\Config\Setting::getInstance()->setDefaultControllerAction();
+        \Qii\Config\Setting::getInstance()->setDefaultNamespace();
+        \Qii\Config\Setting::getInstance()->setDefaultLanguage();
+        return $this;
+    }
 
     /**
-     * 获取指定配置内容key的值
+     * 合并ini文件生成的数组
+     * @param String $iniFile ini文件名
+     * @param Array $array
+     */
+    public function mergeAppConfigure($iniFile, $array)
+    {
+        if (!is_array($array)) return;
+        \Qii\Config\Register::mergeAppConfigure($iniFile, $array);
+        return $this;
+    }
+
+    /**
+     * 覆盖/添加ini文件的key对应的值
+     * @param String $iniFile ini文件名
+     * @param String $key
+     * @param String $val
+     */
+    public function rewriteAppConfigure($iniFile, $key, $val)
+    {
+        \Qii\Config\Register::rewriteConfig($iniFile, $key, $val);
+        return $this;
+    }
+    
+    /**
+     * 设置指定的前缀是否使用命名空间
+     * @param string $prefix 前缀
+     * @param bool $useNamespace 是否使用
+     * @return $this
+     */
+    public function setUseNamespace($prefix, $useNamespace = true)
+    {
+        \Qii\Autoloader\Psr4::getInstance()->setUseNamespace($prefix, $useNamespace);
+        return $this;
+    }
+
+    /**
+     * 添加命名空间对应的网站目录
+     * @param string $prefix 前缀
+     * @param string $baseDir 对应的路径
+     * @param bool $prepend 是否追加
+     * @return $this
+     */
+    public function addNamespace($prefix, $baseDir, $prepend = false)
+    {
+        if (!is_dir($baseDir)) {
+            throw new \Qii\Exceptions\FolderDoesNotExist(\Qii::i(1009, $baseDir), __LINE__);
+        }
+        $baseDir = \Qii\Autoloader\Psr4::getInstance()->realpath($baseDir);
+        \Qii\Autoloader\Psr4::getInstance()->addNamespace($prefix, $baseDir, $prepend);
+        return $this;
+    }
+
+    /**
+     * 设置启动前执行的方法
      *
-     * @param string $key 配置内容key
-     * @return mixed|null
+     * @return $this
+     * @throws Exception
      */
-	public function getConfig($key = null)
+    public function setBootstrap()
     {
-        if(!$key) {
-            return \Qii\Autoloader\Factory::getInstance('\Qii\Config\Arrays')
-                ->get(\Qii\Consts\Config::APP_CONFIGURE);
+        \Qii\Autoloader\Psr4::getInstance()->loadFileByClass('Bootstrap');
+        if (!class_exists('Bootstrap', false)) throw new \Qii\Exceptions\ClassNotFound(\Qii::i(1405, 'Bootstrap'), __LINE__);;
+        $bootstrap = \Qii\Autoloader\Psr4::getInstance()->instance('Bootstrap');
+        if (!$bootstrap instanceof \Qii\Bootstrap\Base) {
+            throw new \Qii\Exceptions\ClassInstanceof(Qii::i(1107, 'Bootstrap', 'Qii\Bootstrap'), __LINE__);;
         }
-        return \Qii\Autoloader\Factory::getInstance('\Qii\Config\Arrays')
-            ->get(\Qii\Consts\Config::APP_CONFIGURE . '['.$key.']');
+        $refectionClass = new \ReflectionClass('Bootstrap');
+        $methods = $refectionClass->getMethods();
+        //自动执行以init开头的公共方法
+        foreach ($methods as $method) {
+            $name = $method->getName();
+            if (substr($name, 0, 4) == 'init' && $method->isPublic()) $bootstrap->$name();
+        }
+        return $this;
     }
+
     /**
-     * 设置Route配置
-     * @param array $route
+     * 设置写loger的类
+     *
+     * @param LogerWriter $logerCls 日志记录类
      */
-	public function setRoute($route = [])
+    public function setLoger($logerCls)
     {
-        \Qii\Autoloader\Factory::getInstance('\Qii\Config\Arrays')
-            ->set(\Qii\Consts\Config::APP_SITE_ROUTER, $config);
+        /*
+        if (!class_exists($logerCls, false)) {
+            throw new \Qii_Exceptions_ClassNotFound(Qii::i(1405, $logerCls), __LINE__);
+        }*/
+
+        $this->logerWriter = \Qii\Autoloader\Instance::instance(
+            '\Qii\Loger\Instance',
+            \Qii\Autoloader\Instance::instance($logerCls)
+        );
+        return $this;
+    }
+
+    /**
+     * 设置数据库使用的文件
+     *
+     * @param $iniFile
+     * @throws \Qii_Exceptions_Overwrite
+     */
+    public function setDBIniFile($iniFile)
+    {
+        \Qii\Config\Register::set(\Qii\Consts\Config::APP_DB, $iniFile);
+    }
+
+    /**
+     * 获取当前数据库文件
+     *
+     * @return \Qii_Mix
+     * @throws \Qii_Exceptions_Variable
+     */
+    public function getDBIniFile()
+    {
+        return \Qii\Config\Register::get(\Qii\Consts\Config::APP_DB);
+    }
+
+    /**
+     * 设置数据库配置文件
+     * @param string $ini 配置文件路径
+     * @param string $env 环境
+     */
+    public function setDB($ini, $env = '')
+    {
+        if ($env == '') $env = $this->getEnv();
+        $this->setDBIniFile($ini);
+        if (!\Qii\Config\Register::setAppConfigure(
+            \Qii\Autoloader\Psr4::getInstance()->getFileByPrefix($ini),
+            $env
+        )
+        ) {
+            throw new \Qii\Exceptions\FileNotFound(\Qii::i(1405, $ini), __LINE__);
+        }
+        return $this;
+    }
+
+    /**
+     * 设置路由规则
+     *
+     * @param string $router 路由配置文件位置
+     * @return $this
+     */
+    public function setRouter($router)
+    {
+        \Qii\Config\Register::set(
+            \Qii\Consts\Config::APP_SITE_ROUTER,
+            \Qii\Autoloader\Import::includes(
+                \Qii\Autoloader\Psr4::realpath(\Qii\Autoloader\Psr4::getInstance()->getFileByPrefix($router)
+                )
+            )
+        );
+        //载入rewrite规则后重写request
+        $rewrite = \Qii\Autoloader\Psr4::loadStatic(
+            '\Qii\Route\Parse',
+            'get',
+            $this->request->controller,
+            $this->request->action,
+            $this->request->url->get(2)
+        );
+        $rewrite['controller'] = $rewrite['controller'] ? $rewrite['controller'] : $this->request->defaultController();
+        $rewrite['action'] = $rewrite['action'] ? $rewrite['action'] : $this->request->defaultAction();
+        //是否已经rewrite,如果和url中的不一样就是已经rewrite
+        if ($this->request->controller != $rewrite['controller'] || $this->request->action != $rewrite['action']) {
+            $this->request->setRouted(true);
+        }
+        $this->request->controllerName($rewrite['controller']);
+        $this->request->setActionName($rewrite['action']);
+        return $this;
+    }
+    /**
+     * sprintf 格式化语言错误信息内容
+     *
+     * Qii::e($message, $argv1, $argv2, ..., $line);
+     * $message = sprintf($message, $argv1, $argv2, ...);
+     * throw new \Qii\Exceptions\Error($message, $line);
+     */
+    public function showError()
+    {
+        return call_user_func_array(array('\Qii\Exceptions\Errors', 'e'), func_get_args());
     }
 	
 	public function run()
 	{
-		print_r($this->getConfig());
+        $this->helper->load(self::$workspace);
+        $this->dispatcher = \Qii\Autoloader\Psr4::getInstance()->loadClass('\Qii\Controller\Dispatcher');
+        if (!$this->dispatcher instanceof \Qii\Controller\Dispatcher) {
+            throw new \Exception('Dispatcher must instance of Qii\Controller\Dispatcher', __LINE__);
+        }
+        //如果设置了host的话,看host对应的controller路径
+        $hosts = $this->appConfigure('hosts');
+        if (count($hosts) > 0) {
+            foreach ($hosts AS $host) {
+                if ($host['domain'] == $this->request->host) {
+                    \Qii\Config\Register::set(
+                        \Qii\Consts\Config::APP_DEFAULT_CONTROLLER_PREFIX,
+                        ($host['path'] ? $host['path'] : $host['domain'])
+                    );
+                    break;
+                }
+            }
+        }
+        $this->request->setDispatcher($this->dispatcher);
+        //rewrite规则
+        $this->dispatcher->setRequest($this->request);
+        $this->dispatcher->dispatch();
+        $this->request->setDispatched(true);
+        return $this;
 	}
 }

+ 6 - 4
Qii/Autoloader/Factory.php

@@ -26,14 +26,16 @@ class Factory
         {
             return \Qii::e('CLASS_NAME_IS_NULL', $className);
         }
-        $className = Psr4::getInstance()->getClassName($className);
         if(isset(Factory::$instance[$className]) &&
             Factory::$instance[$className] != null
         ){
             return Factory::$instance[$className];
         }
-        Factory::$instance[$className] = new $className;
-
-        return Factory::$instance[$className];
+        if(class_exists($className, false))
+        {
+            return Factory::$instance[$className] = new $className;
+        }
+        $className = Psr4::getInstance()->getClassName($className);
+        return Factory::$instance[$className] = new $className;
     }
 }

+ 68 - 0
Qii/Autoloader/Helper.php

@@ -0,0 +1,68 @@
+<?php
+namespace Qii\Autoloader;
+
+/**
+ * Helper 将自动注册到系统 Helper中,直接调用即可
+ *
+ * @author Jinhui Zhu<jinhui.zhu@live.cn>2015-10-24 23:18
+ * @version 1.2
+ */
+class Helper
+{
+    const VERSION = '1.2';
+    /**
+     * @var $helpers helper类
+     */
+    public static $helpers = array();
+
+    public function __construct()
+    {
+        self::$helpers = array();
+    }
+
+    /**
+     * 使用属性返回helper类
+     * @param string $name 不带helper\的类名
+     * @return object
+     */
+    public function __get($name)
+    {
+        if (substr($name, 0, 7) == 'Helper\\') return $this->get($name);
+        return $this->get('Helper\\' . $name);
+    }
+
+    /**
+     * 获取helper类,如果没有实例化就抛出异常
+     * @param string $helper
+     * @return object
+     */
+    public function get($helper)
+    {
+        if (isset(self::$helpers[$helper])) return self::$helpers[$helper];
+        throw new \Qii\Exceptions\CallUndefinedClass(\Qii::i('1105', $helper), __LINE__);
+    }
+
+    /*
+     * 自动加载Helper目录中文件,支持自动实例化对象
+     * @param string $appPath 自动加载指定目录中文件
+     */
+    public function load($appPath = '')
+    {
+        if ($appPath == '') {
+            return;
+        }
+        if (!is_dir($appPath . DS . 'helper')) {
+            return;
+        }
+        foreach (glob(str_replace("//", DS, $appPath . DS . 'helper' . DS . '*.php'), GLOB_BRACE) AS $file) {
+            if(\Qii\Autoloader\Import::requires($file)){
+                //如果里边包含class的话就将class注册到Qii::instance('class');
+                $className = \Qii\Autoloader\Psr4::getInstance()->getClassName('helper\\' . str_replace(array('.php', '.'), array('', '_'), basename($file)));
+
+                if (class_exists($className, false)) {
+                    self::$helpers[$className] = \Qii\Autoloader\Psr4::getInstance()->instance($className);
+                }
+            }
+        }
+    }
+}

+ 71 - 0
Qii/Autoloader/Instance.php

@@ -0,0 +1,71 @@
+<?php
+namespace Qii\Autoloader;
+/**
+ * Instance类
+ * @author Jinhui Zhu<jinhui.zhu@live.cn>2015-10-22 19:45
+ * @version 1.3
+ *
+ * 使用方法:
+ *
+ * $class = Qii\Instance::init('className');
+ * 再次使用就可以直接通过Qii\Instance::getInstance('className');
+ */
+class Instance
+{
+    const VERSION = '1.2';
+    /**
+     * @var APP_LOAD_PREFIX 保存类到以APP_LOAD_PREFIX开头的key中
+     */
+    const APP_LOAD_PREFIX = '__qii_instance';
+    /**
+     * @var $loadedClass 保存加载过的类
+     */
+    protected static $loadedClass = array();
+
+    /**
+     * 获取初始化的类
+     * @param string $className 类名
+     * @reutrn object
+     */
+    public static function getInstance($className)
+    {
+        if (isset(self::$loadedClass[self::APP_LOAD_PREFIX . $className])) return self::$loadedClass[self::APP_LOAD_PREFIX . $className];
+        throw new \Qii\Exceptions\CallUndefinedClass(\Qii::i('1105', $className), __LINE__);
+    }
+
+    /**
+     * 初始化类保存到_loadedClass中并返回
+     */
+    public static function initialize()
+    {
+        $args = func_get_args();
+        $className = array_shift($args);
+        if (!class_exists($className, false)) throw new \Qii\Exceptions\CallUndefinedClass(\Qii::i('1105', $className), __LINE__);
+        if (isset(self::$loadedClass[self::APP_LOAD_PREFIX . $className])
+            && self::$loadedClass[self::APP_LOAD_PREFIX . $className]
+        ) return self::$loadedClass[self::APP_LOAD_PREFIX . $className];
+        $loader = new \ReflectionClass($className);
+        try {
+            $instance = $loader->newInstanceArgs($args);
+            self::$loadedClass[self::APP_LOAD_PREFIX . $className] = $instance;
+            //如果有_initialize方法就自动调用_initialize方法,并将参数传递给_initialize方法
+            if ($loader->hasMethod('_initialize')) {
+                call_user_func_array(array($instance, '_initialize'), $args);
+            }
+            return self::$loadedClass[self::APP_LOAD_PREFIX . $className];
+        } catch (\Exception $e) {
+            throw new \Exception($e->getMessage(), __LINE__);
+        }
+    }
+
+    /**
+     * 加载文件后再初始化
+     */
+    public static function instance()
+    {
+        $args = func_get_args();
+        $className = array_shift($args);
+        \Qii\Autoloader\Psr4::getInstance()->loadFileByClass($className);
+        return call_user_func_array(array('\Qii\Autoloader\Instance', 'initialize'), array_merge(array($className), $args));
+    }
+}

+ 67 - 0
Qii/Autoloader/Loader.php

@@ -0,0 +1,67 @@
+<?php
+namespace Qii\Autoloader;
+
+/**
+ * Loader类
+ */
+class Loader
+{
+
+    const VERSION = '1.2';
+    /**
+     * @var $loaded 保存已经加载过的类实例
+     */
+    private $loaded;
+    /**
+     * @var $lastCall 最后一次访问的方法
+     */
+    private $lastCall;
+
+    public function __construct()
+    {
+        $this->lastCall = null;
+        return $this;
+    }
+
+    public function __clone()
+    {
+        $this->lastCall = null;
+    }
+
+    public function __get($name)
+    {
+        $this->lastCall = $name;
+        return $this;
+    }
+
+    /**
+     * 返回load对象
+     *
+     * @return mixed
+     */
+    public static function Instance()
+    {
+        return \Qii\Autoloader\Instance::instance('\Qii\Autoloader\Loader');
+    }
+
+    /**
+     * 实现自动加载
+     *
+     * @param $method
+     * @param $argvs
+     * @return object
+     */
+    public function __call($method, $args)
+    {
+        $class = array_shift($args);
+        if ($this->lastCall) {
+            $className = $this->lastCall . '\\' . $method;
+            \Qii\Autoloader\Import::requireByClass($className);
+        } else {
+            $className = $method . '\\' . $class;
+        }
+        $this->lastCall = null;
+        if (isset($this->loaded[$className])) return $this->loaded[$className];
+        return $this->loaded[$className] = call_user_func_array(array('\Qii\Autoloader\Instance', 'Instance'), array_merge(array($className), $args));
+    }
+}

+ 21 - 42
Qii/Autoloader/Psr4.php

@@ -200,17 +200,11 @@ class Psr4
         }
         return $folder;
     }
-
     /**
-     * 通过类名加载文件
-     * @param string $class 类名
-     * @return string 文件路径
+     * 从Map中获取文件
      */
-    public function loadFileByClass($class)
+    protected function searchMappedFile($class)
     {
-        // the current namespace prefix
-        //replace "_" to "\" use common method to load class
-        $class = str_replace("_", "\\", $class);
         $prefix = $class;
         // work backwards through the namespace names of the fully-qualified
         // class name to find a mapped file name
@@ -226,9 +220,6 @@ class Psr4
             if ($mappedFile) {
                 return $mappedFile;
             }
-
-            // remove the trailing namespace separator for the next iteration
-            // of strrpos()
             $prefix = rtrim($prefix, '\\');
         };
         //如果没有找到就在workspace中去找对应的文件 额外添加的方法
@@ -236,8 +227,23 @@ class Psr4
         if ($mappedFile) {
             return $mappedFile;
         }
-        $notLoaded = isset(self::$lastErrorLoadedFile[$class]) ? self::$lastErrorLoadedFile[$class] : self::getClassName($class);
-        throw new \Qii\Exceptions\FileNotFound(\Qii::i(1405, $notLoaded), __LINE__);
+        return false;
+    }
+    /**
+     * 通过类名加载文件
+     * @param string $class 类名
+     * @return string 文件路径
+     */
+    public function loadFileByClass($class)
+    {
+        // the current namespace prefix
+        //replace "_" to "\" use common method to load class
+        $class = str_replace("_", "\\", $class);
+        if(!$this->searchMappedFile($class))
+        {
+            $notLoaded = isset(self::$lastErrorLoadedFile[$class]) ? self::$lastErrorLoadedFile[$class] : self::getClassName($class);
+            throw new \Qii\Exceptions\FileNotFound(\Qii::i(1405, $notLoaded), __LINE__);
+        }
     }
 
     /**
@@ -250,34 +256,11 @@ class Psr4
         // the current namespace prefix
         //replace "_" to "\" use common method to load class
         $class = str_replace("_", "\\", $class);
-        $prefix = $class;
-        // work backwards through the namespace names of the fully-qualified
-        // class name to find a mapped file name
-        while (false !== $pos = strrpos($prefix, '\\')) {
-            // retain the trailing namespace separator in the prefix
-            $prefix = substr($class, 0, $pos + 1);
-
-            // the rest is the relative class name
-            $relativeClass = substr($class, $pos + 1);
-
-            // try to load a mapped file for the prefix and relative class
-            $mappedFile = $this->loadMappedFile($prefix, $relativeClass);
-            if ($mappedFile) {
-                return $class;
-            }
-
-            // remove the trailing namespace separator for the next iteration
-            // of strrpos()
-            $prefix = rtrim($prefix, '\\');
-        };
-        //如果没有找到就在workspace中去找对应的文件 额外添加的方法
-        $mappedFile = $this->loadMappedFile('workspace\\', $class);
-
-        if ($mappedFile) 
+        if($this->searchMappedFile($class))
         {
             return $class;
         }
-        return str_replace('\\', '_', $class);
+        return  str_replace('\\', '_', $class);
     }
 
     /**
@@ -420,15 +403,11 @@ class Psr4
             throw new \Qii\Exceptions\CallUndefinedClass(\Qii::i('1105', $className), __LINE__);
         }
         $loader = new \ReflectionClass($className);
-        //try {
         self::$_loadedClass[$className] = $instance = $loader->newInstanceArgs($args);
         //如果有_initialize方法就自动调用_initialize方法,并将参数传递给_initialize方法
         if ($loader->hasMethod('_initialize')) {
             call_user_func_array(array($instance, '_initialize'), $args);
         }
         return $instance;
-        /*} catch (Exception $e) {
-            throw new \Exception($e->getMessage(), __LINE__);
-        }*/
     }
 }

+ 7 - 0
Qii/Bootstrap/Base.php

@@ -0,0 +1,7 @@
+<?php
+namespace Qii\Bootstrap;
+
+interface Base 
+{
+	public function _initialize();
+}

+ 10 - 10
Qii/Config/Setting.php

@@ -1,12 +1,12 @@
 <?php
-namespace \Qii\Config;
+namespace Qii\Config;
 /**
  * 系统设置
  *
  */
 class Setting
 {
-    protected static $_instance;
+    protected static $instance;
     public $language;
 
     private function __construct()
@@ -19,10 +19,10 @@ class Setting
      */
     public static function getInstance()
     {
-        if (self::$_instance == null) {
-            self::$_instance = new self();
+        if (self::$instance == null) {
+            self::$instance = new self();
         }
-        return self::$_instance;
+        return self::$instance;
     }
 
     /**
@@ -33,7 +33,7 @@ class Setting
      */
     public function setDefaultLanguage()
     {
-        $this->language = \Qii_Autoloader_Psr4::getInstance()->loadClass('Qii_Language_Loader');
+        $this->language = \Qii\Autoloader\Psr4::getInstance()->loadClass('\Qii\Language\Loader');
         //加载语言包
         $this->language->load('error', Qii_DIR);
         $this->language->load('exception', Qii_DIR);
@@ -59,12 +59,12 @@ class Setting
     public function setDefaultControllerAction()
     {
         //设置默认controller及controller方法前缀
-        \Qii_Config_Register::set(\Qii_Const_Config::APP_DEFAULT_CONTROLLER, \Qii::getInstance()->appConfigure('controller')['default']);
-        \Qii_Config_Register::set(\Qii_Const_Config::APP_DEFAULT_CONTROLLER_PREFIX, \Qii::getInstance()->appConfigure('controller')['prefix']);
+        \Qii\Config\Register::set(\Qii\Consts\Config::APP_DEFAULT_CONTROLLER, \Qii::getInstance()->appConfigure('controller')['default']);
+        \Qii\Config\Register::set(\Qii\Consts\Config::APP_DEFAULT_CONTROLLER_PREFIX, \Qii::getInstance()->appConfigure('controller')['prefix']);
 
         //设置默认action及方法名后缀
-        \Qii_Config_Register::set(\Qii_Const_Config::APP_DEFAULT_ACTION, \Qii::getInstance()->appConfigure('action')['default']);
-        \Qii_Config_Register::set(\Qii_Const_Config::APP_DEFAULT_ACTION_SUFFIX, \Qii::getInstance()->appConfigure('action')['suffix']);
+        \Qii\Config\Register::set(\Qii\Consts\Config::APP_DEFAULT_ACTION, \Qii::getInstance()->appConfigure('action')['default']);
+        \Qii\Config\Register::set(\Qii\Consts\Config::APP_DEFAULT_ACTION_SUFFIX, \Qii::getInstance()->appConfigure('action')['suffix']);
         return $this;
     }
 

+ 267 - 0
Qii/Controller/Base.php

@@ -0,0 +1,267 @@
+<?php
+namespace Qii\Controller;
+
+/**
+ * Qii_Controller_Abstract class
+ * @author Zhu Jinhui
+ */
+abstract class Base
+{
+    /**
+     * @var array $actions action对应的方法列表,设置了的就转发
+     */
+    public $actions = array();
+    /**
+     * @var \Qii\Autoloader\Psr4::getInstance() $load
+     */
+    public $load;
+    /**
+     * @var \Qii\Language\Loader $language
+     */
+    public $language;
+    /**
+     * @var Qii\Controller\Base $controller
+     */
+    public $controller;
+    /**
+     * @var string $controllerId controller名
+     */
+    public $controllerId = 'index';
+    /**
+     * @var string $actionId action名
+     */
+    public $actionId = 'index';
+    /**
+     * @var Qii\Request\Base $request
+     */
+    public $request;
+    /**
+     * @var Qii_Response_Abstract $response
+     */
+    public $response;
+    /**
+     * @var Qii_Driver_xxx_Connection
+     */
+    public $db;
+    /**
+     * @var mixed
+     */
+    public $view;
+    /**
+     * @var Qii_Cache_Abslute $cache
+     */
+    public $cache;
+    /**
+     * 是否启用view模块
+     * @var bool
+     */
+    public $enableView = false;
+
+    /**
+     * 是否启用Model
+     * @var bool
+     */
+    public $enableModel = false;
+
+    public function __construct()
+    {
+        $this->load = \Qii\Autoloader\Psr4::getInstance()->loadClass('\Qii\Autoloader\Loader');
+        $this->request = \Qii\Autoloader\Psr4::getInstance()->loadClass('\Qii\Request\Http');
+        $this->controllerId = $this->request->controller;
+        $this->actionId = $this->request->action;
+        //载入model
+        if ($this->enableModel) {
+            $this->enableModel();
+        }
+        //载入view
+        if ($this->enableView) {
+            $this->view = $this->setView();
+        }
+
+        if (!$this->beforeRun()) {
+            exit();
+        }
+    }
+
+    /**
+     * 启用view后调用初始化View方法
+     */
+    protected function initView()
+    {
+    }
+
+    /**
+     * 设置view
+     *
+     * @param string $engine
+     * @param array $policy
+     * @return mixed
+     */
+    public function setView($engine = 'smarty', $policy = array())
+    {
+        $viewConfigure = \Qii::appConfigure('view');
+        //如果之前实例化过相同的就不再实例化
+        if (!$engine) $engine = $viewConfigure['engine'];
+        $policy = (array)$policy;
+        if (!$policy) {
+            $policy = array_merge($policy, $viewConfigure[$engine]);
+        }
+        $viewEngine = \Qii\Autoloader\Psr4::getInstance()->loadClass('\Qii\View\Loader');
+        $viewEngine->setView($engine, $policy);
+        $this->view = $viewEngine->getView();
+        if(method_exists($this, 'initView'))
+        {
+            $this->initView();
+        }
+        return $this->view ;
+    }
+
+    /**
+     * 设置缓存
+     *
+     * @param string $engine 缓存方法
+     * @param array $policy 缓存策略
+     */
+    public function setCache($engine = '', $policy = array())
+    {
+        $engine = $engine == '' ? \Qii::appConfigure('cache') : $engine;
+        $basicPolicy = array(
+            'servers' => $this->getCachePolicy($engine),
+        );
+        if ($basicPolicy['servers']) {
+            $policy = array_merge($basicPolicy, $policy);
+        }
+        $loader = new \Qii\Cache\Loader($engine);
+        return $this->cache = $loader->initialization($policy);
+    }
+
+    /**
+     * 获取缓存的策略
+     * @param String $cache 缓存的内容
+     * @return multitype:multitype:Ambigous <>
+     */
+    final public function getCachePolicy($cache)
+    {
+        $data = array();
+        if (!$cache) return $data;
+        $cacheInfo = \Qi\Config\Register::getAppConfigure(\Qi\Config\Register::get(\Qii\Consts\Config::APP_INI_FILE), $cache);
+        if (!$cacheInfo) return $data;
+
+        $servers = explode(";", $cacheInfo['servers']);
+        $ports = explode(";", $cacheInfo['ports']);
+        for ($i = 0; $i < count($servers); $i++) {
+            $data[] = array('host' => $servers[$i], 'port' => $ports[$i]);
+        }
+        return $data;
+    }
+
+    final public function enableModel()
+    {
+        return $this->db = \Qii\Autoloader\Psr4::getInstance()->loadClass('\Qii\Driver\Model');
+    }
+
+    /**
+     * 获取view
+     *
+     * @return mixed
+     */
+    public function getView()
+    {
+        return $this->view;
+    }
+
+    /**
+     * 设置request
+     * @param $request
+     */
+    public function setRequest(\Qii\Request\Base $request)
+    {
+        $this->request = $request;
+    }
+
+
+    /**
+     * 只要继承的方法调用parent::__construct()就开始执行
+     * 此方法如果返回false,将不再往下继续执行
+     */
+    protected function beforeRun()
+    {
+        return true;
+    }
+
+    /**
+     * 执行完dispatch后调用
+     */
+    protected function afterRun()
+    {
+
+    }
+
+    /**
+     * 转发
+     * @param String $controller
+     * @param String $action
+     * @return mixed
+     */
+    final public function dispatch($controller, $action)
+    {
+        $this->request->setControllerName($controller);
+        $this->request->setActionName($action);
+        \Qii::getInstance()->dispatcher->setRequest($this->request);
+        return call_user_func_array(array(\Qii::getInstance()->dispatcher, 'dispatch'), func_get_args());
+    }
+
+    /**
+     * 获取当前使用的controller
+     *
+     * @return string
+     */
+    final public function getCurrentController()
+    {
+        return get_called_class();
+    }
+
+    /**
+     * 获取 request 方法
+     * @return Qii_Request_Http
+     */
+    final public function getRequest()
+    {
+        return $this->request;
+    }
+
+    /**
+     * 获取response类
+     * @return mixed
+     */
+    final public function getResponse()
+    {
+        return $this->response;
+    }
+
+    /**
+     * 设置forward
+     * @param string $controller controller名
+     * @param string $action action名
+     */
+    public function setForward($controller, $action)
+    {
+        $this->request->setControllerName($controller);
+        $this->request->setActionName($action);
+        $this->request->setForward(true);
+    }
+
+    /**
+     * afterRun 和 forward 执行
+     */
+    public function __destruct()
+    {
+        $this->afterRun($this->controller, $this->actionId);
+        if ($this->request && $this->request->isForward()) {
+            $this->request->setForward(false);
+            \Qii::getInstance()->dispatcher->setRequest($this->request);
+            \Qii::getInstance()->dispatcher->dispatch();
+            $this->request->setDispatched(true);
+        }
+    }
+}

+ 71 - 0
Qii/Controller/Dispatcher.php

@@ -0,0 +1,71 @@
+<?php
+namespace Qii\Controller;
+
+class Dispatcher
+{
+    public $request;
+
+    public function __construct()
+    {
+
+    }
+
+    public function setRequest(\Qii\Request\Http $request)
+    {
+        $this->request = $request;
+        return $this;
+    }
+
+    /**
+     * 转发
+     * @param string $controller
+     * @param string $action
+     * @return mixed
+     */
+    public function dispatch($controller = '', $action = '')
+    {
+        $args = func_get_args();
+        $controller = $controller != '' ? $controller : $this->request->getControllerName();
+        $action = $action != '' ? $action : $this->request->getActionName();
+
+        $controllerName = \Qii\Config\Register::get(\Qii\Consts\Config::APP_DEFAULT_CONTROLLER_PREFIX) . '_' . $controller;
+        $funcArgs = array();
+        if (count($args) > 2) {
+            $funcArgs = array_slice($args, 2);
+        }
+        array_unshift($funcArgs, $controllerName);
+        $psr4 = \Qii\Autoloader\Psr4::getInstance();
+        $controllerCls = call_user_func_array(array($psr4, 'loadClass'), $funcArgs);
+        $controllerCls->setRequest($this->request);
+        $controllerCls->controller = $controllerCls;
+        $controllerCls->controllerId = $controller;
+        $controllerCls->actionId = $action;
+        //查看是否设置了当前action的对应关系,如果设置了就走对应关系里边的,否则走当前类中的
+        if ($controllerCls->actions && isset($controllerCls->actions[$action]) && $controllerCls->actions[$action]) {
+            $actionArgs = array();
+            $actionArgs[] = $controllerCls->actions[$action];
+            //$actionArgs[] = $controllerCls;
+            //$actionArgs[] = $action;
+            $actionCls = call_user_func_array(array($psr4, 'loadClass'), $actionArgs);
+            $actionCls->setRequest($this->request);
+            $actionCls->controller = $controllerCls;
+            $actionCls->actionId = $action;
+            $actionCls->controllerId = $controllerCls->controllerId;
+            //支持多个action对应到同一个文件,如果对应的文件中存在指定的方法就直接调用
+            if (method_exists($actionCls, $action . \Qii\Config\Register::get(\Qii\Consts\Config::APP_DEFAULT_ACTION_SUFFIX))) {
+                return call_user_func_array(array($actionCls, $action. \Qii\Config\Register::get(\Qii\Consts\Config::APP_DEFAULT_ACTION_SUFFIX)), $funcArgs);
+            }
+            if (!method_exists($actionCls, 'run')) {
+                throw new \Qii\Exceptions\MethodNotFound(\Qii::i(1101, $controllerCls->actions[$action] . '->run'), __LINE__);
+            }
+            return call_user_func_array(array($actionCls, 'run'), $funcArgs);
+        } else {
+            array_shift($funcArgs);
+            $actionName = $action . \Qii\Config\Register::get(\Qii\Consts\Config::APP_DEFAULT_ACTION_SUFFIX);
+            if (!method_exists($controllerCls, $actionName) && !method_exists($controllerCls, '__call')) {
+                throw new \Qii\Exceptions\MethodNotFound(\Qii::i(1101, $controller . '->' . $actionName), __LINE__);
+            }
+            return call_user_func_array(array($controllerCls, $actionName), $funcArgs);
+        }
+    }
+}

+ 3 - 3
Qii/Exceptions/Errors.php

@@ -51,7 +51,7 @@ class Errors extends \Exception
 		$message[] = \Qii::i('Error code', $e->getCode());
 		$message[] = \Qii::i('Error description', $e->getMessage());
 		$message[] = \Qii::i('Error line', $e->getLine() . ' on ' . self::getLineMessage($e->getFile(), $e->getLine()));
-		$traceString = Qii::i('Trace as below') . '<br />';
+		$traceString = \Qii::i('Trace as below') . '<br />';
 		$traces = explode("\n", $e->getTraceAsString());
 		foreach ($traces AS $trance) {
 			$traceString .= "&nbsp;&nbsp;&nbsp;&nbsp;" . $trance . '<br />';
@@ -62,9 +62,9 @@ class Errors extends \Exception
 			$message[] = 'Referer URL:' . (isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : \Qii::getInstance()->request->url->getCurrentURL());
 			\Qii::getInstance()->logerWriter->writeLog($message);
 		}
-		$appConfigure = Qii\Config\Register::getConfig();
+		$appConfigure = \Qii\Config\Register::getConfig();
 
-		$env = Qii\Config\Register::get(\Qii\Consts\Config::APP_ENVIRON, 'dev');
+		$env = \Qii\Config\Register::get(\Qii\Consts\Config::APP_ENVIRON, 'dev');
 		if ($env == 'product' || ($appConfigure['errorPage'] && (isset($appConfigure['debug']) && $appConfigure['debug'] == 0))) {
 			list($controller, $action) = explode(':', $appConfigure['errorPage']);
 			$controllerCls = \Qii\Config\Register::get(\Qii\Consts\Config::APP_DEFAULT_CONTROLLER_PREFIX) . '_' . $controller;

+ 104 - 1
Qii/Qii.php

@@ -34,7 +34,41 @@ use \Qii\Application;
 
 class Qii extends Application
 {
+    public function __construct()
+    {
+        parent::__construct();
+    }
+    public static function getInstance()
+    {
+	    return \Qii\Autoloader\Factory::getInstance('\Qii');
+    }
+    /**
+     * 设置private 属性
+     *
+     * @param String $name
+     * @param Mix $value
+     */
+    public static function setPrivate($name, $value)
+    {
+        \Qii\Autoloader\Psr4::getInstance()->loadClass('\Qii\Config\Arrays')->setPrivate($name, $value);
+    }
 
+    /**
+     * 获取private属性
+     *
+     * @param String $name
+     * @param String $key
+     * @return Mix
+     */
+    public static function getPrivate($name, $key = '')
+    {
+        $private = \Qii\Autoloader\Psr4::getInstance()->loadClass('\Qii\Config\Arrays')->getPrivate($name);
+        if (preg_match('/^\s*$/', $key)) {
+            return $private;
+        }
+        if (isset($private[$key])) return $private[$key];
+    }
+    
 	public static function i()
     {
         return call_user_func_array(array(
@@ -42,6 +76,20 @@ class Qii extends Application
             func_get_args()
         );
     }
+    /**
+     * 错误设置,如果满足给定的条件就直接返回false,否则在设置了错误页面的情况下返回true
+     * 如果出错后要终止的话,需要自行处理,此方法不错停止不执行
+     *
+     * @param Bool $condition
+     * @param int $line 出错的行数,这样以便轻松定位错误
+     * @param String $msg
+     * @param Int|String $code
+     * @return Bool
+     */
+    public static function setError($condition, $line = 0, $code, $args = null)
+    {
+        return call_user_func_array(array('\Qii\Exceptions\Error', 'setError'), func_get_args());
+    }
     /**
      * 抛出异常
      *
@@ -51,8 +99,57 @@ class Qii extends Application
     {
         return call_user_func_array(array('\Qii\Exceptions\Errors', 'e'), func_get_args());
     }
+    /**
+     * 返回当前app的配置
+     * @param string $key 如果需要返回单独的某一个key就指定一下这个值
+     * @return Mix
+     */
+    public static function appConfigure($key = null)
+    {
+        return \Qii\Config\Register::getAppConfigure(\Qii::getInstance()->getAppIniFile(), $key);
+    }
     
+    /**
+     * 当调用Qii不存在的方法的时候,试图通过Autoload去加载对应的类
+     * 示例:
+     * \Qii::getInstance()->Qii_Autoloader_Psr4('instance', 'Model\User');
+     *    此方法将调用:Qii_Autoloader_Psr4->instance('Model\User');
+     */
+    public function __call($className, $args)
+    {
+        return call_user_func_array(array(\Qii\Autoloader\Psr4::getInstance(), 'loadClass'), $args);
+    }
+    /**
+     * 当调用不存在的静态方法的时候会试图执行对应的类和静态方法
+     * 示例:
+     * \Qii::Qii_Autoloader_Psr4('getInstance')
+     *    此方法将调用:\Qii\Autoloader\Psr4::getInstance静态方法
+     */
+    public static function __callStatic($className, $args)
+    {
+        $method = array_shift($args);
+        $className = \Qii\Autoloader\Psr4::getInstance()->getClassName($className);
+        return call_user_func_array($className . '::' . $method, $args);
+    }
 }
+
+if (!function_exists('catch_fatal_error')) {
+    function catch_fatal_error()
+    {
+        // Getting Last Error
+        $error = error_get_last();
+        // Check if Last error is of type FATAL
+        if (isset($error['type']) && $error['type'] == E_ERROR) {
+            // Fatal Error Occurs
+            $message = array();
+            $message[] = 'Error file : ' . ltrim($error['file'], \Qii\Autoloader\Psr4::realpath($_SERVER['DOCUMENT_ROOT']));
+            $message[] = 'Error line : ' . $error['line'] . ' on ' . \Qii\Exceptions\Errors::getLineMessage($error['file'], $error['line']);
+            $message[] = 'Error description : ' . $error['message'];
+            \Qii\Exceptions\Error::showError($message);
+        }
+    }
+}
+
 \Qii\Autoloader\Psr4::getInstance()
     ->register()
     ->setUseNamespace('Qii\\', true)
@@ -99,4 +196,10 @@ class Qii extends Application
 \Qii\Autoloader\Factory::getInstance('\Qii\Language\Loader')->load('error', Qii_DIR . DS . 'Language');
 \Qii\Autoloader\Factory::getInstance('\Qii\Language\Loader')->load('error', Qii_DIR . DS . 'Language');
 \Qii\Autoloader\Factory::getInstance('\Qii\Language\Loader')->load('exception', Qii_DIR . DS . 'Language');
-\Qii\Autoloader\Factory::getInstance('\Qii\Language\Loader')->load('resource', Qii_DIR . DS . 'Language');
+\Qii\Autoloader\Factory::getInstance('\Qii\Language\Loader')->load('resource', Qii_DIR . DS . 'Language');
+
+
+//捕获FATAL错误,用户可以选择记录到日志,还是直接显示或者不显示错误
+register_shutdown_function('catch_fatal_error');
+set_exception_handler(array('\Qii\Exceptions\Errors', 'getError'));
+set_error_handler(array('\Qii\Exceptions\Errors', 'getError'), E_USER_ERROR);

+ 614 - 0
Qii/Request/Base.php

@@ -0,0 +1,614 @@
+<?php
+namespace Qii\Request;
+
+abstract class Base
+{
+    const SCHEME_HTTP = 'http';
+    const SCHEME_HTTPS = 'https';
+    public $host = '';
+    public $module;
+    public $controller;
+    public $action;
+    public $method;
+
+    public $dispatcher;
+
+
+    protected $params;
+
+    protected $language;
+
+    protected $_exception;
+
+    protected $_baseUri = '';
+
+    protected $uri = '';
+
+    protected $dispatched = false;
+
+    protected $routed = false;
+
+    protected $forward = false;
+    /**
+     * @var Qii_Request_Url url
+     */
+    public $url;
+    /**
+     * 初始化参数,获取链接中对应的参数并存放到$this->params中
+     *
+     */
+    public function __construct()
+    {
+        foreach ($_GET AS $key => $val) {
+            $this->setParam($key, $val);
+        }
+        $rewriteRule = \Qii::getInstance()->appConfigure(\Qii\Consts\Config::APP_SITE_METHOD);
+        $this->url = new \Qii\Request\Url($rewriteRule);
+        $this->host = $_SERVER['HTTP_HOST'];
+        $params = (array)$this->url->getParams();
+        if(count($params) > 0) $this->params = array_merge($this->params, $params);
+        //处理url中的数据
+        if(ucwords($rewriteRule) == 'Short'){
+            $this->setControllerName(
+                    isset($this->params[0]) && $this->params[0] != '' ?
+                        $this->params[0] :
+                        $this->defaultController());
+            $this->setActionName(
+                    isset($this->params[1]) && $this->params[1] != '' ?
+                        $this->params[1] :
+                        $this->defaultAction());
+        }
+        return $this;
+    }
+    /**
+     * 获取POST数据
+     */
+    public function post($name, $default = null)
+    {
+        return isset($_POST[$name]) ? $_POST[$name] : $default;
+    }
+    /**
+     * 默认controller
+     */
+    public function defaultController()
+    {
+        return \Qii\Config\Register::get(\Qii\Consts\Config::APP_DEFAULT_CONTROLLER, 'index');
+    }
+    /**
+     * 默认action
+     */
+    public function defaultAction()
+    {
+        return \Qii\Config\Register::get(\Qii\Consts\Config::APP_DEFAULT_ACTION, 'index');
+    }
+
+    /**
+     * 获取当前数据处理
+     */
+    public function uri()
+    {
+        return $this->uri;
+    }
+
+    /**
+     * isGet
+     *
+     * @param void
+     * @return boolean
+     */
+    public function isGet()
+    {
+        return (strtoupper($this->method) == 'GET');
+    }
+
+    /**
+     * isPost
+     *
+     * @param void
+     * @return boolean
+     */
+    public function isPost()
+    {
+        return (strtoupper($this->method) == 'POST');
+    }
+
+    /**
+     * isPut
+     *
+     * @param void
+     * @return boolean
+     */
+    public function isPut()
+    {
+        return (strtoupper($this->method) == 'PUT');
+    }
+
+    /**
+     * isHead
+     *
+     * @param void
+     * @return boolean
+     */
+    public function isHead()
+    {
+        return (strtoupper($this->method) == 'HEAD');
+    }
+
+    /**
+     * isOptions
+     *
+     * @param void
+     * @return boolean
+     */
+    public function isOptions()
+    {
+        return (strtoupper($this->method) == 'OPTIONS');
+    }
+
+    /**
+     * isCli
+     *
+     * @param void
+     * @return boolean
+     */
+    public function isCli()
+    {
+        return (strtoupper($this->method) == 'CLI');
+    }
+
+    /**
+     * isXmlHttpRequest
+     *
+     * @param void
+     * @return boolean
+     */
+    public function isXmlHttpRequest()
+    {
+        return false;
+    }
+
+    /**
+     * getServer
+     *
+     * @param string $name
+     * @param mixed $default
+     * @return mixed
+     */
+    public function getServer($name = null, $default = null)
+    {
+        if (is_null($name)) {
+            return $_SERVER;
+        } elseif (isset($_SERVER[$name])) {
+            return $_SERVER[$name];
+        }
+        return $default;
+    }
+
+    /**
+     * getEnv
+     *
+     * @param string $name
+     * @param mixed $default
+     * @return mixed
+     */
+    public function getEnv($name = null, $default = null)
+    {
+        if (is_null($name)) {
+            return $_ENV;
+        } elseif (isset($_ENV[$name])) {
+            return $_ENV[$name];
+        }
+        return $default;
+    }
+
+    /**
+     * setParam
+     *
+     * @param mixed $name
+     * @param mixed $value
+     * @return boolean | Qii_Request_Abstract
+     */
+    public function setParam($name, $value = null)
+    {
+        if (is_null($value)) {
+            if (is_array($name)) {
+                $this->params = array_merge($this->params, $name);
+                return $this;
+            }
+        } elseif (is_string($name)) {
+            $this->params[$name] = $value;
+            return $this;
+        }
+        return false;
+    }
+
+    /**
+     * getParam
+     *
+     * @param string $name
+     * @param mixed $default
+     * @return mixed
+     */
+    public function getParam($name, $dafault = null)
+    {
+        if (isset($this->params[$name])) {
+            return $this->params[$name];
+        }
+        return $dafault;
+    }
+
+    /**
+     * setParams
+     *
+     * @param array
+     * @return boolean | Qii_Request_Abstract
+     */
+    public function setParams($params)
+    {
+        if (is_array($params)) {
+            $this->params = $params;
+            return $this;
+        }
+        return false;
+    }
+
+    /**
+     * getParams
+     *
+     * @param void
+     * @return array
+     */
+    public function getParams()
+    {
+        return $this->params;
+    }
+
+    /**
+     * setException
+     *
+     * @param Exception $exception
+     * @return boolean | Qii_Request_Abstract
+     */
+    public function setException($exception)
+    {
+        if (is_object($exception)
+            && ($exception instanceof Exception)
+        ) {
+            $this->_exception = $exception;
+            return $this;
+        }
+        return false;
+    }
+
+    /**
+     * getException
+     *
+     * @param void
+     * @return Exception
+     */
+    public function getException()
+    {
+        if (is_object($this->_exception)
+            && ($this->_exception instanceof Exception)
+        ) {
+            return $this->_exception;
+        }
+        return null;
+    }
+
+
+    /**
+     * getModuleName
+     *
+     * @param void
+     * @return string
+     */
+    public function getModuleName()
+    {
+        return $this->module;
+    }
+
+    /**
+     * getControllerName
+     *
+     * @param void
+     * @return string
+     */
+    public function getControllerName()
+    {
+        return $this->controller;
+    }
+
+    /**
+     * getActionName
+     *
+     * @param void
+     * @return string
+     */
+    public function getActionName()
+    {
+        return $this->action;
+    }
+
+    /**
+     * setModuleName
+     *
+     * @param string $name
+     * @return boolean | Qii_Request_Abstract
+     */
+    public function setModuleName($name)
+    {
+        if (!is_string($name)) {
+            trigger_error('Expect a string module name', E_USER_WARNING);
+            return false;
+        }
+        $this->module = $name;
+        return $this;
+    }
+
+    /**
+     * setControllerName
+     *
+     * @param string $name
+     * @return boolean | Qii_Request_Abstract
+     */
+    public function setControllerName($name)
+    {
+        if (!is_string($name)) {
+            trigger_error('Expect a string controller name', E_USER_WARNING);
+            return $this;
+        }
+        $this->controller = $name;
+        return $this;
+    }
+
+    /**
+     * setActionName
+     *
+     * @param string $name
+     * @return boolean | Qii_Request_Abstract
+     */
+    public function setActionName($name)
+    {
+        if (!is_string($name)) {
+            trigger_error('Expect a string action name', E_USER_WARNING);
+            return false;
+        }
+        $this->action = $name;
+        return $this;
+    }
+
+    /**
+     * getMethod
+     *
+     * @param void
+     * @return string
+     */
+    public function getMethod()
+    {
+        return $this->method;
+    }
+
+    /**
+     * getLanguage
+     *
+     * @param void
+     * @return string
+     */
+    public function getLanguage()
+    {
+        return $this->language;
+    }
+
+    /**
+     * setBaseUri
+     *
+     * @param string $baseUri
+     * @return boolean | Qii_Request_Abstract
+     */
+    public function setBaseUri($baseUri)
+    {
+        if ($baseUri && is_string($baseUri)) {
+            $this->_baseUri = $baseUri;
+            return $this;
+        }
+        return false;
+    }
+
+    /**
+     * getBaseUri
+     *
+     * @param void
+     * @return string
+     */
+    public function getBaseUri()
+    {
+        return $this->_baseUri;
+    }
+
+    /**
+     * setRequestUri
+     *
+     * @param string $uri
+     * @return boolean | Qii_Request_Abstract
+     */
+    public function setRequestUri($uri)
+    {
+        if (is_string($uri)) {
+            $this->uri = $uri;
+            return $this;
+        }
+        return false;
+    }
+
+    /**
+     * getRequestUri
+     *
+     * @param void
+     * @return string
+     */
+    public function getRequestUri()
+    {
+        return $this->uri;
+    }
+
+    /**
+     * isDispatched
+     *
+     * @param void
+     * @return boolean
+     */
+    public function isDispatched()
+    {
+        return (boolean)$this->dispatched;
+    }
+
+    /**
+     * setDispatched
+     *
+     * @param boolean $flag
+     * @return boolean | Qii_Request_Abstract
+     */
+    public function setDispatched($flag = true)
+    {
+        if (is_bool($flag)) {
+            $this->dispatched = $flag;
+            return $this;
+        }
+        return false;
+    }
+
+    /**
+     * 设置dispatcher
+     *
+     * @param Qii_Controller_Dispatcher $dispatcher
+     */
+    public function setDispatcher(\Qii\Controller\Dispatcher $dispatcher)
+    {
+        $this->dispatcher = $dispatcher;
+    }
+
+    /**
+     * isRouted
+     *
+     * @param void
+     * @return boolean
+     */
+    public function isRouted()
+    {
+        return $this->routed;
+    }
+
+    /**
+     * setRouted
+     *
+     * @param boolean $flag
+     * @return boolean | Qii_Request_Abstract
+     */
+    public function setRouted($flag = true)
+    {
+        if (is_bool($flag)) {
+            $this->routed = $flag;
+            return $this;
+        }
+        return false;
+    }
+    /**
+     * 是否需要转发
+     */
+    public function isForward()
+    {
+        return $this->forward;
+    }
+    /**
+     * 设置是否需要转发
+     * @param bool $flag
+     * @return $this
+     */
+    public function setForward($flag = true)
+    {
+        if (is_bool($flag)) {
+            $this->forward = $flag;
+            return $this;
+        }
+        return $this;
+    }
+
+    /**
+     * __setbaseUri
+     *
+     * @param string $baseUri
+     * @param string $request_uri
+     * @return boolean
+     */
+    protected function _setbaseUri($baseUri, $request_uri = null)
+    {
+        if ($baseUri && is_string($baseUri)) {
+            $this->_baseUri = $baseUri;
+
+            return true;
+        } elseif ($request_uri && is_string($request_uri)) {
+            $scriptFileName = $this->getServer('SCRIPT_FILENAME');
+
+            do {
+                if ($scriptFileName && is_string($scriptFileName)) {
+                    $fileName = basename($scriptFileName, \Qii::getInstance()->appConfigure('ext', '.php'));
+                    $fileNameLen = strlen($fileName);
+
+                    $script_name = $this->getServer('SCRIPT_NAME');
+                    if ($script_name && is_string($script_name)) {
+                        $script = basename($script_name);
+
+                        if (strncmp($fileName, $script, $fileNameLen) == 0) {
+                            $basename = $script_name;
+                            break;
+                        }
+                    }
+
+                    $phpself_name = $this->getServer('PHP_SELF');
+                    if ($phpself_name && is_string($phpself_name)) {
+                        $phpself = basename($phpself_name);
+                        if (strncmp($fileName, $phpself, $fileNameLen) == 0) {
+                            $basename = $phpself_name;
+                            break;
+                        }
+                    }
+
+                    $orig_name = $this->getServer('ORIG_SCRIPT_NAME');
+                    if ($orig_name && is_string($orig_name)) {
+                        $orig = basename($orig_name);
+                        if (strncmp($fileName, $orig, $fileNameLen) == 0) {
+                            $basename = $orig_name;
+                            break;
+                        }
+                    }
+                }
+            } while (0);
+
+            if ($basename && strstr($request_uri, $basename) == $request_uri) {
+                $this->_baseUri = rtrim($basename, '/');
+
+                return true;
+            } elseif ($basename) {
+                $dirname = rtrim(dirname($basename), '/');
+                if ($dirname) {
+                    if (strstr($request_uri, $dirname) == $request_uri) {
+                        $this->_baseUri = $dirname;
+
+                        return true;
+                    }
+                }
+            }
+
+            $this->_baseUri = '';
+
+            return true;
+        }
+
+        return false;
+    }
+    public function __call($method, $args)
+    {
+        return call_user_func_array(array($this->url, $method), $args);
+    }
+}

+ 217 - 0
Qii/Request/Http.php

@@ -0,0 +1,217 @@
+<?php
+namespace Qii\Request;
+
+final class Http extends Base
+{
+
+    /**
+     * __construct
+     *
+     * @param string $request_uri
+     * @param string $base_uri
+     */
+    public function __construct($request_uri = null, $base_uri = null)
+    {
+        if (isset($_SERVER['REQUEST_METHOD'])) {
+            $this->method = $_SERVER['REQUEST_METHOD'];
+        } else {
+            if (!strncasecmp(PHP_SAPI, 'cli', 3)) {
+                $this->method = 'Cli';
+            } else {
+                $this->method = 'Unknown';
+            }
+        }
+        if (empty($request_uri)) {
+            do {
+                // #ifdef PHP_WIN32
+                if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
+                    /* check this first so IIS will catch */
+                    if ($request_uri = $this->getServer('HTTP_X_REWRITE_URL')) {
+                        break;
+                    }
+
+                    /* IIS7 with URL Rewrite: make sure we get the unencoded url (double slash problem) */
+                    if ($rewrited = (boolean)$this->getServer('IIS_WasUrlRewritten')) {
+                        $unencode = $this->getServer('UNENCODED_URL');
+                        if ($unencode && is_string($unencode)) {
+                            $request_uri = $unencode;
+                        }
+                        break;
+                    }
+                    // #endif
+                }
+                if ($request_uri = $this->getServer('PATH_INFO')) {
+                    break;
+                }
+
+                if ($request_uri = $this->getServer('REQUEST_URI')) {
+                    /* Http proxy reqs setup request uri with scheme and host [and port] + the url path, only use url path */
+                    if (strstr($request_uri, 'http') == $request_uri) {
+                        $url_info = parse_url($request_uri);
+                        if ($url_info && isset($url_info['path'])) {
+                            $request_uri = $url_info['path'];
+                        }
+                    } else {
+                        if ($pos = strstr($request_uri, '?')) {
+                            $request_uri = substr($request_uri, 0, $pos - 1);
+                        }
+                    }
+                    break;
+                }
+
+                if ($request_uri = $this->getServer('ORIG_PATH_INFO')) {
+                    /* intended do nothing */
+                    /*
+                    if ($query = $this->getServer('QUERY_STRING')) {
+                    }
+                    */
+                    break;
+                }
+
+            } while (0);
+        }
+        if ($request_uri && is_string($request_uri)) {
+            $request_uri = str_replace('//', '/', $request_uri);
+            $this->uri = $request_uri;
+
+            // request_set_base_uri
+            $this->_setbaseUri($base_uri, $request_uri);
+        }
+        $this->params = array();
+        parent::__construct();
+    }
+
+    /**
+     * getQuery
+     *
+     * @param string $name
+     * @param mixed $default
+     * @return mixed
+     */
+    public function getQuery($name = null, $default = null)
+    {
+        if (is_null($name)) {
+            return $_GET;
+        } elseif (isset($_GET[$name])) {
+            return $_GET[$name];
+        }
+        return $default;
+    }
+
+    /**
+     * getRequest
+     *
+     * @param string $name
+     * @param mixed $default
+     * @return mixed
+     */
+    public function getRequest($name = null, $default = null)
+    {
+        if (is_null($name)) {
+            return $_REQUEST;
+        } elseif (isset($_REQUEST[$name])) {
+            return $_REQUEST[$name];
+        }
+        return $default;
+    }
+
+    /**
+     * getPost
+     *
+     * @param string $name
+     * @param mixed $default
+     * @return mixed
+     */
+    public function getPost($name = null, $default = null)
+    {
+        if (is_null($name)) {
+            return $_POST;
+        } elseif (isset($_POST[$name])) {
+            return $_POST[$name];
+        }
+        return $default;
+    }
+
+    /**
+     * getCookie
+     *
+     * @param string $name
+     * @param mixed $default
+     * @return mixed
+     */
+    public function getCookie($name = null, $default = null)
+    {
+        if (is_null($name)) {
+            return $_COOKIE;
+        } elseif (isset($_COOKIE[$name])) {
+            return $_COOKIE[$name];
+        }
+        return $default;
+    }
+
+    /**
+     * getFiles
+     *
+     * @param string $name
+     * @param mixed $default
+     * @return mixed
+     */
+    public function getFiles($name = null, $default = null)
+    {
+        if (is_null($name)) {
+            return $_FILES;
+        } elseif (isset($_FILES[$name])) {
+            return $_FILES[$name];
+        }
+        return $default;
+    }
+
+    /**
+     * get [params -> post -> get -> cookie -> server]
+     *
+     * @param string $name
+     * @param mixed $default
+     * @return mixed
+     */
+    public function get($name, $default = null)
+    {
+        if (isset($this->params[$name])) {
+            return $this->params[$name];
+        } elseif (isset($_POST[$name])) {
+            return $_POST[$name];
+        } elseif (isset($_GET[$name])) {
+            return $_GET[$name];
+        } elseif (isset($_COOKIE[$name])) {
+            return $_COOKIE[$name];
+        } elseif (isset($_SERVER[$name])) {
+            return $_SERVER[$name];
+        }
+        return $default;
+    }
+
+    /**
+     * isXmlHttpRequest
+     *
+     * @param void
+     * @return boolean
+     */
+    public function isXmlHttpRequest()
+    {
+        $header = isset($_SERVER['HTTP_X_REQUESTED_WITH']) ? $_SERVER['HTTP_X_REQUESTED_WITH'] : '';
+        if (is_string($header) && strncasecmp('XMLHttpRequest', $header, 14) == 0) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * __clone
+     *
+     * @param void
+     */
+    private function __clone()
+    {
+
+    }
+
+}

+ 219 - 0
Qii/Request/Sample.php

@@ -0,0 +1,219 @@
+<?php
+namespace Qii\Request;
+
+final class Simple extends Base
+{
+	/**
+	 * __construct
+	 *
+	 * @param string $module
+	 * @param string $controller
+	 * @param string $action
+	 * @param string $method
+	 * @param array $params
+	 */
+	public function __construct ($module, $controller, $action, $method, $params = null)
+	{
+		if ($params && !is_array($params)) {
+			unset($this);
+			trigger_error('Expects the params is an array', E_USER_ERROR);
+			return false;
+		}
+
+		if (is_string($method)) {
+			$this->method = $method;
+		} else {
+			if (isset($_SERVER['REQUEST_METHOD'])) {
+				$this->method = $_SERVER['REQUEST_METHOD'];
+			} else {
+				if (!strncasecmp(PHP_SAPI, 'cli', 3)) {
+					$this->method = 'CLI';
+				} else {
+					$this->method = 'Unknown';
+				}
+			}
+		}
+
+		if ($module || $controller || $action) {
+			if ($module && is_string($module)) {
+				$this->module = $module;
+			} else {
+				$this->module = YAF_G('default_module');
+			}
+
+			if ($controller && is_string($controller)) {
+				$this->controller = $controller;
+			} else {
+				$this->controller = YAF_G('default_controller');
+			}
+
+			if ($action && is_string($action)) {
+				$this->action = $action;
+			} else {
+				$this->controller = YAF_G('default_action');
+			}
+
+			$this->routed = true;
+		} else {
+			$argv = $this->getServer('argv');
+			if (is_array($argv)) {
+				foreach($argv as $value) {
+					if (is_string($value)) {
+						if (strncasecmp($value, 'request_uri=', 12)) {
+							continue;
+						}
+						$query = substr($value, 12);
+						break;
+					}
+				}
+			}
+
+			if (empty($query)) {
+				$this->uri = '';
+			} else {
+				$this->uri = $query;
+			}
+		}
+
+		if ($params && is_array($params)) {
+			$this->params = $params;
+		} else {
+			$this->params = array();
+		}
+        parent::__construct();
+	}
+	
+	/**
+	 * getQuery
+	 *
+	 * @param string $name
+	 * @param mixed $default
+	 * @return mixed
+	 */
+	public function getQuery($name = null, $default = null)
+	{
+		if (is_null($name)) {
+			return $_GET;
+		} elseif (isset($_GET[$name])) {
+			return $_GET[$name];
+		}
+		return $default;
+	}
+
+	/**
+	 * getRequest
+	 *
+	 * @param string $name
+	 * @param mixed $default
+	 * @return mixed
+	 */
+	public function getRequest($name = null, $default = null)
+	{
+		if (is_null($name)) {
+			return $_REQUEST;
+		} elseif (isset($_REQUEST[$name])) {
+			return $_REQUEST[$name];
+		}
+		return $default;
+	}
+
+	/**
+	 * getPost
+	 *
+	 * @param string $name
+	 * @param mixed $default
+	 * @return mixed
+	 */
+	public function getPost($name = null, $default = null)
+	{
+		if (is_null($name)) {
+			return $_POST;
+		} elseif (isset($_POST[$name])) {
+			return $_POST[$name];
+		}
+		return $default;
+	}
+
+	/**
+	 * getCookie
+	 *
+	 * @param string $name
+	 * @param mixed $default
+	 * @return mixed
+	 */
+	public function getCookie($name = null, $default = null)
+	{
+		if (is_null($name)) {
+			return $_COOKIE;
+		} elseif (isset($_COOKIE[$name])) {
+			return $_COOKIE[$name];
+		}
+		return $default;
+	}
+
+	/**
+	 * getFiles
+	 *
+	 * @param string $name
+	 * @param mixed $default
+	 * @return mixed
+	 */
+	public function getFiles($name = null, $default = null)
+	{
+		if (is_null($name)) {
+			return $_FILES;
+		} elseif (isset($_FILES[$name])) {
+			return $_FILES[$name];
+		}
+		return $default;
+	}
+
+	/**
+	 * get [params -> post -> get -> cookie -> server]
+	 *
+	 * @param string $name
+	 * @param mixed $default
+	 * @return mixed
+	 */	
+	public function get($name, $default = null)
+	{
+		if (isset($this->params[$name])) {
+			return $this->params[$name];
+		} elseif (isset($_POST[$name])) {
+			return $_POST[$name];
+		} elseif (isset($_GET[$name])) {
+			return $_GET[$name];
+		} elseif (isset($_COOKIE[$name])) {
+			return $_COOKIE[$name];
+		} elseif (isset($_SERVER[$name])) {
+			return $_SERVER[$name];
+		}
+		return $default;
+	}
+
+	/**
+	 * isXmlHttpRequest
+	 *
+	 * @param void
+	 * @return boolean
+	 */	
+	public function isXmlHttpRequest()
+	{
+		$header = isset($_SERVER['HTTP_X_REQUESTED_WITH']) ? $_SERVER['X-Requested-With'] : '';
+		if (is_string($header) && strncasecmp('XMLHttpRequest', $header, 14) == 0) {
+			return true;
+		}
+		return false;
+	}
+
+	/**
+	 * __clone
+	 *
+	 * @param void
+	 */
+	private function __clone()
+	{
+		
+	}
+
+}

+ 148 - 0
Qii/Request/Url.php

@@ -0,0 +1,148 @@
+<?php
+namespace Qii\Request;
+
+/**
+ * 返回URL处理方法
+ */
+class Url
+{
+    /**
+     * self instance
+     */
+    private static $_instance;
+    public $request;
+
+    public function __construct($rewriteRule = 'Normal')
+    {
+        $allow = array('Normal', 'Middle', 'Short');
+        if (!in_array($rewriteRule, $allow)) {
+            throw new \Qii\Exceptions\Unsupport("链接模式错误,链接格式只能为 '<u><font color=\"green\">" . join("', '", $allow) . "</font></u>',当前模式为 '<font color=\"red\">" . $rewriteRule . "</font>'", __LINE__);
+        }
+        $className = 'Qii\Request\Url\\' . $rewriteRule;
+        $this->request = \Qii\Autoloader\Psr4::getInstance()->loadClass($className, $rewriteRule);
+        return $this;
+    }
+
+    public static function getInstance()
+    {
+        $args = func_get_args();
+        $arg = array_shift($args);
+        if (self::$_instance == null) {
+            self::$_instance = new self($arg);
+        }
+        return self::$_instance;
+    }
+
+
+    /**
+     * 获取当前连接地址
+     *
+     */
+    public static function getCurrentURL()
+    {
+        $rewriteRule = \Qii::getInstance()->appConfigure(\Qii\Consts\Config::APP_SITE_METHOD);
+        return \Qii\Request\Url::getInstance($rewriteRule)->request->getCurrentURL();
+    }
+
+    /**
+     * 获取网站路径的URL
+     * @return string
+     */
+    public static function pathUrl()
+    {
+        $rewriteRule = \Qii::getInstance()->appConfigure(\Qii\Consts\Config::APP_SITE_METHOD);
+        return \Qii\Request\Url::getInstance($rewriteRule)->request->getWebHost() . \Qii::getInstance()->request->url->getPath();
+    }
+
+    /**
+     * 获取文件的路径
+     * @param String $file
+     * @return String
+     */
+    public static function getFile($file)
+    {
+        return self::pathUrl() . '/' . ltrim($file, '/');
+    }
+
+    /**
+     * 将绝对地址补成全路径URL
+     * @param String $url
+     * @return string
+     */
+    public static function getFullUrl($url = 'index', $ext = '.html')
+    {
+        if (is_array($url)) {
+            $url = join('/', $url);
+        }
+        $url = str_replace('//', '/', $url);
+        $query = parse_url($url);
+        $url = $query['path'];
+        $params = array();
+        if (isset($query['query'])) {
+            parse_str($query['query'], $params);
+        }
+        if ($url == '/') $url = 'index';
+        if ($ext == null) {
+            $ext = '';
+        }
+        $query = count($params) > 0 ? '?' . http_build_query($params) : '';
+        //去掉url中末尾的扩展名,避免重复
+        $url = preg_replace('/' . $ext . '$/', '', $url);
+        return rtrim(self::pathUrl(), '/') . '/' . ltrim($url, '/') . $ext . (count($params) > 0 ? '?' . http_build_query($params) : '');
+    }
+
+    /**
+     * 返回url的全路径
+     * @param string $url url格式为路径如:publish/edit.json?isAjax=1&ad_uuid=1912-1212-1212-1112-123
+     */
+    public static function getAbsluteUrl($url)
+    {
+        return self::getFullUrl($url, '');
+    }
+
+    /**
+     * 通过path直接返回全路径
+     *
+     * @param $url
+     * @return string
+     */
+    public static function getSourceFullUrl($url)
+    {
+        $ext = pathinfo($url, PATHINFO_EXTENSION);
+        $url = preg_replace('/' . $ext . '$/', '', $url);
+        return self::getFullUrl($url, $ext);
+    }
+    /**
+     * 获取来源地址
+     */
+    public static function getRefererURL()
+    {
+        return isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '';
+    }
+    /**
+     * 来源地址是否是当前网站
+     * @param string $currentURL 需要验证的网址,不传默认当前网址
+     * @return bool
+     */
+    public static function refererFromCurrentSite($currentURL = null)
+    {
+		$referer = self::getRefererURL();
+        if(!$currentURL) $currentURL = self::getCurrentURL();
+		if(parse_url($referer, PHP_URL_HOST) != parse_url($currentURL, PHP_URL_HOST)){
+			return false;
+		}
+        return true;
+    }
+    /**
+     * 先看本方法中有没有静态方法可调用
+     */
+    public function __call($method, $args)
+    {
+        if(method_exists($this, $method))
+        {
+            return call_user_func_array(array(self, $method), $args);
+        }
+        return call_user_func_array(array($this->request, $method), $args);
+    }
+
+}

+ 340 - 0
Qii/Request/Url/Base.php

@@ -0,0 +1,340 @@
+<?php
+namespace Qii\Request\Url;
+
+abstract class Base
+{
+	const VERSION = '1.2';
+	/**
+	 * URL 模式
+	 *
+	 * @var String
+	 */
+	protected $_mode = 'Normal';
+	/**
+	 * 链接字符
+	 *
+	 * @var String
+	 */
+	private $_symbol = '&';
+	/**
+	 * 文件后缀
+	 *
+	 * @var String
+	 */
+	private $_extenstion = '.html';
+	/**
+	 * 允许设置的URL模式
+	 *
+	 * @var Array
+	 */
+	private $_allowMode = array('Normal', 'Middle', 'Short');
+
+	private $_urlRewrite = "";
+
+	/**
+	 * 是否去掉文件名称,如果rewrite不在根目录的时候将此设为true,避免生成URL错误.
+	 *
+	 * @var Bool
+	 */
+	private $_fileNameTrim = false;
+	/**
+	 * URL中匹配到的参数
+	 */
+	private $params = null;
+	/**
+	 * 初始化模式
+	 * @param string $mode 模式
+	 */
+	public function __construct($mode)
+	{
+		$this->checkMode($mode);
+		$this->_mode = $mode;
+		if(in_array($mode, array('Short', 'Middle')))
+		{
+			$this->_symbol = '/';
+		}
+		$this->params = $this->getParams();
+	}
+
+	/**
+	 * 根据给定的参数创建URL
+	 * @param Array $array {controller:controllerName, action : actionName}
+	 * @param string $fileName
+	 * @param string $extenstion
+	 * @param string $trimExtension
+	 * @return string
+	 */
+	public function bulidURI($params, $fileName = '', $extenstion = '', $trimExtension = false)
+	{
+		$this->checkMode($this->_mode);
+		if (empty($fileName)) {
+			$fileName = $_SERVER['SCRIPT_NAME'];
+		}
+		if (sizeof($params) == 0) {
+			return '';
+		}
+		//2012-03-25新增 path,如果path==$fileName就去掉path,从而避免多个rewrite的时候调用此方法生成的URL错误。
+		$path = $this->getPathInfo();
+		//去掉文件名并保留路径 去掉加路径出现的bug
+		if ($this->_fileNameTrim) {
+			$fileName = rtrim(str_replace(basename($fileName), '', $fileName), "/");
+		}
+		$notAllowPath = array($fileName, "\\");
+		if (in_array($path, $notAllowPath)) {
+			$path = "";
+		}
+		$realPath = rtrim(str_replace('//', '/', $path . $fileName), '/');
+		if ($this->_mode == 'normal') {
+			return $fileName . '?' . $this->{$this->_mode}($params);
+		}
+		if (!empty($extenstion)) {
+			return $realPath . $this->_symbol . $this->{$this->_mode}($params) . ($trimExtension ? '' : $extenstion);
+		}
+		return $realPath . $this->_symbol . $this->{$this->_mode}($array) . ($trimExtension ? '' : $this->_extenstion);
+	}
+	/**
+	 * 获取当前网址
+	 */
+	public function getWebHost()
+	{
+		if (IS_CLI) return '';
+		$prefix = 'http://';
+		if ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') || $_SERVER['SERVER_PORT'] == 443) $prefix = 'https://';
+		return $prefix . rtrim(rtrim(str_replace('//', '/', $_SERVER['HTTP_HOST']), '/'), "\\");
+	}
+	/**
+	 * 获取当前域名
+	 */
+	public function getDomain()
+	{
+		return rtrim(rtrim(str_replace('//', '/', $_SERVER['HTTP_HOST']), '/'), "\\");
+	}
+	/**
+	 *
+	 * 获取当前页面URL
+	 */
+	public function getCurrentURL()
+	{
+		if (IS_CLI) return '';
+		return 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
+	}
+	/**
+	 *
+	 * 获取当前页面的路径相关信息
+	 * @param String $path
+	 * @param String $index
+	 */
+	public function getPathInfo($path = '', $index = 'dirname')
+	{
+		if (empty($path)) $path = $_SERVER['SCRIPT_NAME'];
+		//Array ( [dirname] => /Qii [basename] => index.php [extension] => php [filename] => index )
+		$pathInfo = pathinfo($path);
+		$pathInfo['dirname'] = str_replace("\\", "/", $pathInfo['dirname']);
+		if (!empty($index)) {
+			return $pathInfo[$index];
+		}
+		return $pathInfo;
+	}
+	/**
+	 *
+	 * 获取当前路径
+	 * @param String $path
+	 */
+	public function getPath($path = '')
+	{
+		if (empty($path)) {
+			$path = $_SERVER['SCRIPT_NAME'];
+		}
+		return substr($path, 0, (strrpos($path, '/')));
+	}
+	/**
+	 *
+	 * 设置是否去掉文件名字
+	 * @param Bool $trim
+	 */
+	public function setTrim($trim = false)
+	{
+		$this->_fileNameTrim = $trim;
+	}
+
+	/**
+	 * 设置文件后缀名字
+	 *
+	 * @param String $extenstion
+	 */
+	public function setExtenstion($extenstion)
+	{
+		if (!empty($extenstion)) $this->_extenstion = $extenstion;
+	}
+
+	/**
+	 * 设置连接字符串
+	 *
+	 * @param String $symbol
+	 */
+	public function setSymbol($symbol)
+	{
+		if (!empty($symbol)) $this->_symbol = $symbol;
+	}
+
+	/**
+	 * 设置URI模式
+	 *
+	 * @param String $mode
+	 */
+	public function setMode($mode)
+	{
+		$this->checkMode($mode);
+		$this->_mode = $mode;
+		return $this;
+	}
+	/**
+	 * 获取本类中的私有属性
+	 *
+	 * @param String $key
+	 * @return Mix
+	 */
+	public function get($key = null)
+	{
+        if($key === null) return $this->params;
+		return isset($this->params[$key]) ? $this->params[$key] : null;
+	}
+    /**
+     * 获取POST数据
+     */
+    public function post($name = null, $default = null)
+    {
+        if($name === null) return $_POST;
+        return isset($_POST[$name]) ? $_POST[$name] : $default;
+    }
+    
+	/**
+	 * Cli模式下数据的传输
+	 * 
+	 * @param string $key
+	 */
+	protected function CLIParams($key = '')
+	{
+		$argv = array();
+		if (isset($_SERVER['argv'])) $argv = $_SERVER['argv'];
+		//修正部分服务器Rewrite 后再加参数不识别的问题(直接进入命令行的模式)
+		if ($argv && $_SERVER['PHP_SELF'] == $_SERVER['SCRIPT_NAME']) {
+			if (count($argv) == 1) return;
+			array_shift($argv);
+			$args = (array) $this->parseArgs($argv[0]);
+			//处理GET或POST方法 数据结构 key1=value1 key2=value2 键和值中间不能有空格
+			if($_SERVER['argc'] > 2){
+				for($i = 1; $i < $_SERVER['argc'] - 1; $i++)
+				{
+					list($index, $val) = explode('=', $argv[$i], 2);
+					$args[$index] = $val;
+				}
+			}
+			if ($args && $key != '') {
+				return isset($args[$key]) ? $args[$key] : '';
+			}
+			return $args;
+		}
+	}
+	/**
+	 * 获取参数
+	 *
+	 * @param String $fileName
+	 * @param String $url
+	 * @param String $key
+	 * @return Mix
+	 */
+	public function getParams($key = '', $url = '', $fileName = '')
+	{
+	    if($this->params != null) return $this->params;
+		$this->checkMode($this->_mode);
+		//如果是命令行模式
+		if(IS_CLI) return $this->CLIParams($key);
+
+		if ($this->_mode == 'Normal') {
+			if (empty($key)) return $_GET;
+			return $_GET[$key];
+		}
+		if (!isset($_SERVER['PATH_INFO'])) $_SERVER['PATH_INFO'] = '';
+		if (empty($url)) {
+			//修正Rewrite以指定目录开头的bug 将$url = $_SERVER['REQUEST_URI'];替换成以下的
+			$url = (($_SERVER['PATH_INFO'] != '' && $_SERVER['PATH_INFO'] != '/') ? $_SERVER['PATH_INFO'] : $_SERVER['REQUEST_URI']);
+		}
+		if (empty($fileName)) {
+			$fileName = $_SERVER['SCRIPT_NAME'];
+		}
+		//取fileName后边的内容
+		$url = str_replace($fileName, "", $url);
+		$param = parse_url($url);
+		//如果到?号的URL则取query,没有?则取path的basename($path);
+		if (isset($param['path']) && substr($param['path'], 0, 1) == '?') {
+			//拆分字符
+			if (empty($param['query'])) {
+				return '';
+			}
+			$query = $param['query'];
+		} else {
+			$query = isset($param['path']) ? $param['path'] : '';
+		}
+		$query = $this->comparePath($query, $fileName);
+		//添加系统扩展名到返回数组中 2011-10-14 15:26
+		preg_match("/(.*)\.(.*)$/", $query, $extenstion);
+		//去掉文件后缀名称,修改时间2010-09-03 22:33,以便指定任意后缀名。
+		if (!isset($extenstion[2])) $extenstion[2] = '';
+		$extenstion[2] = str_replace('/', '\/', $extenstion[2]);
+		$query = preg_replace("/\.{$extenstion[2]}$/", "", $query);
+		$paramArray = explode($this->_symbol, $query);
+		$v = $this->decodeArgs($paramArray);
+		//添加系统扩展名到返回数组中 2011-10-14 15:26
+		$v['sysfileExtension'] = $extenstion[2];
+		if ($_GET) $v = array_merge($v, $_GET);
+		if ($key != '' || is_int($key)) {
+			return $v[$key];
+		}
+		return $v;
+	}
+	/**
+	 * 对比转发文件的路径
+	 *
+	 * @param String $path
+	 * @param String $scriptName
+	 * @return String
+	 */
+	public function comparePath($path, $f)
+	{
+		//去掉basename($f)再进行比较,比较的时候将字符串转换成小写;
+		$basename = basename($f);
+		$path = str_replace($basename, "", $path);
+		$f = str_replace($basename, "", $f);
+		//对比parseURL后的Path
+		$pathArray = explode('/', ltrim(rtrim($path, '/'), '/'));
+		$fArray = explode('/', ltrim(rtrim($f, '/'), '/'));
+		$fCount = count($fArray);
+		$tmpArray = array();
+		$tmpArray = $pathArray;
+		for ($i = 0; $i < $fCount; $i++) {
+			if (strtolower($pathArray[$i]) != strtolower($fArray[$i])) {
+				break;
+			}
+			array_shift($tmpArray);
+		}
+		return join("/", $tmpArray);
+	}
+	/**
+	 * 检查生成链接模式
+	 *
+	 * @param String $mode
+	 */
+	public function checkMode($mode)
+	{
+		if (!in_array($mode, $this->_allowMode)) 
+		{
+			throw new \Qii\Exceptions\Unsupport("链接模式错误,链接格式只能为 '<u><font color=\"green\">" . join("', '", $this->_allowMode) . "</font></u>',当前模式为 '<font color=\"red\">" . $mode . "</font>'", __LINE__);
+		}
+	}
+
+	public function __call($method, $args)
+	{
+		//防止掉用不存在的方法
+	}
+}

+ 23 - 0
Qii/Request/Url/Intf.php

@@ -0,0 +1,23 @@
+<?php
+namespace Qii\Request\Url;
+
+interface Intf
+{
+	/**
+	 * 根据给定的参数创建URL
+	 * @param Array $array {controller:controllerName, action : actionName}
+	 * @param string $fileName
+	 * @param string $extenstion
+	 * @param string $trimExtension
+	 * @return string
+	 */
+	public function bulidURI($params, $fileName = '', $extenstion = '', $trimExtension = false);
+	/**
+	 * 匹配参数
+	 */
+	public function parseArgs($params);
+	/**
+	 * 获取参数对应的值
+	 */
+	public function decodeArgs($params, $k = '');
+}

+ 49 - 0
Qii/Request/Url/Middle.php

@@ -0,0 +1,49 @@
+<?php
+namespace Qii\Request\Url;
+
+class Middle extends Base implements Intf
+{
+	public function __construct($mode)
+	{
+		parent::__construct($mode);
+	}
+	/**
+	 * 解析uri获取参数 => 值
+	 * @param string $params uri
+	 * @return array
+	 */
+	public function parseArgs($params)
+	{
+		$this->checkMode($this->_mode);
+		if (empty($params)) return;
+		$argvArray = explode("/", $params);
+		$data = array();
+		if (is_array($argvArray)) {
+			foreach ($argvArray AS $arg) {
+				$args = explode("/", $arg);
+				$data[$args[0]] = $args[1];
+			}
+		}
+		foreach ($_GET AS $key => $val) {
+			$data[$key] = $val;
+		}
+		return $data;
+	}
+	/**
+	 * 获取指定参数的值
+	 * @param array $urlArray 参数集合
+	 * @param string $k 指定参数
+	 */
+	public function decodeArgs($urlArray, $k = '')
+	{
+		$this->checkMode($this->_mode);
+		$urlArraySize = sizeof($urlArray);
+		for ($i = 0; $i < $urlArraySize; $i = $i + 2) {
+			if ($urlArray[$i + 1] == 'NULL') {
+				continue;
+			}
+			$url[$urlArray[$i]] = $urlArray[$i + 1];
+		}
+		return $url;
+	}
+}

+ 40 - 0
Qii/Request/Url/Normal.php

@@ -0,0 +1,40 @@
+<?php
+namespace Qii\Request\Url;
+
+class Normal extends Base implements Intf
+{
+	public function __construct($mode)
+	{
+		parent::__construct($mode);
+	}
+	/**
+	 * 解析uri获取参数 => 值
+	 * @param string $params uri
+	 * @return array
+	 */
+	public function parseArgs($params)
+	{
+		$this->checkMode($this->_mode);
+		if (empty($params)) reutrn;
+		$argvArray = explode("/", $params);
+		$data = array();
+		if (is_array($argvArray)) {
+			foreach ($argvArray AS $arg) {
+				$args = explode("=", $arg);
+				$data[$args[0]] = $args[1];
+			}
+		}
+		return $data;
+	}
+	/**
+	 * 获取指定参数的值
+	 * @param array $urlArray 参数集合
+	 * @param string $k 指定参数
+	 */
+	public function decodeArgs($urlArray, $k = '')
+	{
+		$this->checkMode($this->_mode);
+		if (!empty($k)) return $_GET[$k];
+		return $_GET;
+	}
+}

+ 42 - 0
Qii/Request/Url/Short.php

@@ -0,0 +1,42 @@
+<?php
+namespace Qii\Request\Url;
+
+class Short extends Base implements Intf
+{
+	public function __construct($mode)
+	{
+		parent::__construct($mode);
+	}
+	/**
+	 * 解析uri获取参数 => 值
+	 * @param string $params uri
+	 * @return array
+	 */
+	public function parseArgs($params)
+	{
+		$this->checkMode($this->_mode);
+		if ($params == '') return;
+		$argvArray = explode("/", $params);
+		$data = array();
+		if (is_array($argvArray)) {
+			foreach ($argvArray AS $arg) {
+				$data[] = $arg;
+			}
+		}
+		foreach ($_GET AS $key => $val) {
+			$data[$key] = $val;
+		}
+		return $data;
+	}
+	/**
+	 * 获取指定参数的值
+	 * @param array $urlArray 参数集合
+	 * @param string $k 指定参数
+	 */
+	public function decodeArgs($urlArray, $k = '')
+	{
+		$this->checkMode($this->_mode);
+		if (!empty($k)) return $urlArray[$k] == 'NULL' ? '' : $urlArray[$k];
+		return $urlArray;
+	}
+}

+ 15 - 0
Qii/Response/Cli.php

@@ -0,0 +1,15 @@
+<?php
+namespace Qii\Response;
+
+class Cli extends Base
+{
+    /**
+     * Magic __toString functionality
+     *
+     * @return string
+     */
+    public function __toString()
+    {
+        return $this->_body;
+    }
+}

+ 79 - 0
Qii/Response/Http.php

@@ -0,0 +1,79 @@
+<?php
+namespace Qii\Response;
+
+class Http extends Base
+{
+    protected $_sendheader = true;
+    protected $_responseCode = 200;
+
+    /**
+     * Set HTTP response code to use with headers
+     *
+     * @param int $code
+     * @return Yaf_Response_Http
+     */
+    public function setResponseCode($code)
+    {
+        if (!is_int($code) || (100 > $code) || (599 < $code)) {
+            throw new \Qii\Exceptions\Response('Invalid HTTP response code');
+        }
+
+        $this->_responseCode = $code;
+        return $this;
+    }
+
+    /**
+     * Retrieve HTTP response code
+     *
+     * @return int
+     */
+    public function getResponseCode()
+    {
+        return $this->_responseCode;
+    }
+
+    /**
+     * Send all headers
+     *
+     * Sends any headers specified.
+     * If an {@link setResponseCode() HTTP response code}
+     * has been specified, it is sent with the first header.
+     *
+     * @return Yaf_Response_Http
+     */
+    protected function sendHeaders()
+    {
+        $httpCodeSent = false;
+
+        foreach ($this->_headers as $header) {
+            if (!$httpCodeSent && $this->_responseCode) {
+                header(
+                    $header['name'] . ': ' . $header['value'],
+                    $header['replace'], $this->_responseCode
+                );
+                $httpCodeSent = true;
+            } else {
+                header(
+                    $header['name'] . ': ' . $header['value'],
+                    $header['replace']
+                );
+            }
+        }
+        return $this;
+    }
+
+    /**
+     * Set redirect URL
+     *
+     * Sets Location header. Forces replacement of any prior redirects.
+     *
+     * @param string $url
+     * @return Yaf_Response_Abstract
+     */
+    public function setRedirect($url)
+    {
+        $this->setHeader('Location', $url, true)
+            ->setResponseCode(302);
+        return $this;
+    }
+}

+ 261 - 0
Qii/Response/Response.php

@@ -0,0 +1,261 @@
+<?php
+namespace Qii\Response;
+
+class Response
+{
+    /**
+     * Default body name
+     */
+    const DEFAULT_BODY = 'html';
+
+    /**
+     * Body content
+     * @var array
+     */
+    protected $_body = array();
+
+    /**
+     * Array of headers. Each header is an array with keys 'name' and 'value'
+     * @var array
+     */
+    protected $_headers = array();
+
+    /**
+     * Determine to send the headers or not
+     * @var unknown_type
+     */
+    protected $_sendHeader = false;
+	public function __construct()
+	{
+		
+	}
+
+    /**
+     * Append content to the body content
+     *
+     * @param string $content
+     * @param string $key
+     * @return Qii_Response_Abstract
+     */
+    public function appendBody($body, $key = NULL)
+    {
+        if (!strlen($key)) {
+            $key = self::DEFAULT_BODY;
+        }
+        if (!isset($this->_body[$key])) {
+            $this->_body[$key] = '';
+        }
+        $this->_body[$key] .= (string) $body;
+        return $this;
+    }
+
+    /**
+     * Clear the entire body
+     *
+     * @param string $key
+     * @return boolean
+     */
+    public function clearBody($key = NULL)
+    {
+        if (strlen($key)) {
+            if (array_key_exists($key, $this->_body)) {
+                unset($this->_body[$key]);
+            }
+        } else {
+            $this->_body = array();
+        }
+        return true;
+    }
+
+    /**
+     * Clear headers
+     *
+     * @return Qii\Response\Abstract
+     */
+    public function clearHeaders()
+    {
+        $this->_headers = array();
+        return $this;
+    }
+
+    /**
+     * Return the body content
+     *
+     * @param string $key
+     * @return string
+     */
+    public function getBody($key = NULL)
+    {
+        if (!strlen($key)) {
+            $key = self::DEFAULT_BODY;
+        }
+        return array_key_exists($key, $this->_body) ? $this->_body[$key] : null;
+    }
+
+    /**
+     * Return array of headers; see {@link $_headers} for format
+     *
+     * @return array
+     */
+    public function getHeader()
+    {
+        return $this->_headers;
+    }
+
+    /**
+     * Prepend content the body
+     *
+     * @param string $body
+     * @param string $key
+     * @return Qii_Response_Abstract
+     */
+    public function prependBody($body, $key = null)
+    {
+        if (!strlen($key)) {
+            $key = self::DEFAULT_BODY;
+        }
+        if (!isset($this->_body[$key])) {
+            $this->_body[$key] = '';
+        }
+        $this->_body[$key] = $body . $this->_body[$key];
+        return $this;
+    }
+
+    /**
+     * Send the response, including all headers
+     *
+     * @return void
+     */
+    public function response()
+    {
+        if ($this->_sendHeader == true) {
+            $this->sendHeaders();
+        }
+        foreach ($this->_body as $key => $body) {
+            echo $body;
+        }
+    }
+
+    public function setAllHeaders()
+    {
+        return false;
+    }
+    /**
+     * Set body content
+     *
+     * @param string $body
+     * @param string $key
+     * @return Qii_Response_Abstract
+     */
+    public function setBody($body, $key = NULL)
+    {
+        if (!strlen($key)) {
+            $key = self::DEFAULT_BODY;
+        }
+        $this->_body[$key] = (string) $body;
+        return $this;
+    }
+
+    /**
+     * Set a header
+     *
+     * If $replace is true, replaces any headers already defined with that
+     * $name.
+     *
+     * @param string $name
+     * @param string $value
+     * @param boolean $replace
+     * @return Qii_Response_Abstract
+     */
+    public function setHeader($name, $value, $replace = false)
+    {
+        $name  = $this->_normalizeHeader($name);
+        $value = (string) $value;
+
+        if ($replace) {
+            foreach ($this->_headers as $key => $header) {
+                if ($name == $header['name']) {
+                    unset($this->_headers[$key]);
+                }
+            }
+        }
+
+        $this->_headers[] = array(
+            'name'    => $name,
+            'value'   => $value,
+            'replace' => $replace
+        );
+
+        return $this;
+    }
+
+    /**
+     * Set redirect URL
+     *
+     * Sets Location header. Forces replacement of any prior redirects.
+     *
+     * @param string $url
+     * @return Qii_Response_Abstract
+     */
+    public function setRedirect($url)
+    {
+        $this->setHeader('Location', $url, true);
+        return $this;
+    }
+
+    /**
+     * Magic __toString functionality
+     *
+     * Returns response value as string
+     * using output buffering.
+     *
+     * @return string
+     */
+    public function __toString()
+    {
+        ob_start();
+        $this->response();
+        return ob_get_clean();
+    }
+
+    /**
+     * Normalize a header name
+     *
+     * Normalizes a header name to X-Capitalized-Names
+     *
+     * @param  string $name
+     * @return string
+     */
+    protected function _normalizeHeader($name)
+    {
+        $filtered = str_replace(array('-', '_'), ' ', (string) $name);
+        $filtered = ucwords(strtolower($filtered));
+        $filtered = str_replace(' ', '-', $filtered);
+        return $filtered;
+    }
+
+    /**
+     * Send all headers
+     *
+     * Sends any headers specified.
+     * If an {@link setHttpResponseCode() HTTP response code}
+     * has been specified, it is sent with the first header.
+     *
+     * @return Qii_Response_Abstract
+     */
+    protected function sendHeaders()
+    {
+        foreach ($this->_headers as $header) {
+            header(
+                $header['name'] . ': ' . $header['value'],
+                $header['replace']
+            );
+        }
+        return $this;
+    }
+
+    public function render()
+    {
+        
+    }
+}

+ 47 - 0
Qii/Route/Parse.php

@@ -0,0 +1,47 @@
+<?php
+namespace Qii\Route;
+/**
+ * 路由规则类
+ *
+ * @author Jinhui Zhu<jinhui.zhu@live.cn>2015-10-24 23:11
+ */
+
+class Parse
+{
+    const VERSION = 1.3;
+
+    /**
+     * 路由转发, 转发对应的规则中xx不能为*
+     *
+     * @param String $controller
+     * @param String $action
+     * @param Array $router
+     * @return Array ($controller, $action);
+     *
+     * *:* => *:yyy 所有controller和action都转发到 *->yyy
+     * *:* => yy:* 所有转发到xxx->*, 这里的*,前边对应的是什么,后边就对应转发到什么,比如: *:xxx => yy:yyy
+     * xx:* => yy:* xx中对应的方法转发到yy对应的方法
+     * xx:* => yy:yyy xxx Controller转发到 yy->yyy
+     * *:xxx => yy:yyy 所有Controller转发到 yy->yyy
+     */
+    public static function get($controller, $action = '', $thirdParam = '')
+    {
+        if ($controller == 'Qii') {
+            return array('controller' => $controller, 'action' => $action);
+        }
+        //如果第一列的是*号则所有的controller都执行对应的x:
+        $router =\Qii\Config\Register::getAppConfigure(\Qii\Consts\Config::APP_SITE_ROUTER);
+        $rewriteRule = \Qii\Config\Register::getAppConfigure(\Qii\Config\Register::get(\Qii\Consts\Config::APP_INI_FILE), 'rewriteRule');
+        if (!$rewriteRule) $rewriteRule = 'Normal';
+        \Qii\Autoloader\Import::requires(Qii_DIR . DS . 'Route' . DS . 'Parse' .DS. $rewriteRule . '.php');
+        $className = '\Qii\Route\Parse\\' . $rewriteRule;
+        if (!class_exists($className, false)) {
+            throw new \Qii\Exceptions\ClassNotFound(\Qii::i(1103, $className), __LINE__);
+        }
+        $class = new $className();
+        $class->setConfig($router);
+        return $class->parse($controller, $action, $thirdParam);
+    }
+}
+
+;

+ 99 - 0
Qii/Route/Parse/Normal.php

@@ -0,0 +1,99 @@
+<?php
+namespace Qii\Route\Parse;
+
+/**
+ * Route规则文件
+ * 兼容以前版本的匹配规则
+ *
+ * @author Jinhui Zhu<jinhui.zhu@live.cn>2015-10-24 23:11
+ * @version 1.2
+ */
+
+class Normal
+{
+	const VERSION = '1.2';
+	private $config;
+
+	public function __construct()
+	{
+
+	}
+
+	/**
+	 * 设置路由规则
+	 * @param Array $config 路由规则
+	 */
+	public function setConfig($config)
+	{
+		$this->config = $config;
+	}
+
+	/**
+	 * 路由转发, 转发对应的规则中xx不能为*
+	 *
+	 * @param String $controller
+	 * @param String $action
+	 * @return Array ($controller, $action);
+	 *
+	 * *:* => *:yyy 所有controller和action都转发到 *->yyy
+	 * *:* => yy:* 所有转发到xxx->*, 这里的*,前边对应的是什么,后边就对应转发到什么,比如: *:xxx => yy:yyy
+	 * xx:* => yy:* xx中对应的方法转发到yy对应的方法
+	 * xx:* => yy:yyy xxx Controller转发到 yy->yyy
+	 * *:xxx => yy:yyy 所有Controller转发到 yy->yyy
+	 * xxx:*(yy):第三个参数 => {1}:* 转发xxx:yy => yy:第三个参数
+	 */
+	public function parse($controller, $action, $thirdParam = '')
+	{
+		if (!$this->config) {
+			return array('controller' => $controller, 'action' => $action);
+		}
+		$routerArray = array();
+		if (is_array($this->config)) {
+			foreach ($this->config AS $key => $value) {
+				$keyArray = explode(":", $key);
+				$valueArray = explode(":", $value);
+				if (!isset($keyArray[1])) $keyArray[1] = '';
+				if (!isset($valueArray[1])) $valueArray[1] = '';
+				if ('' == $keyArray[1]) {
+					$keyArray[1] = "*";
+				}
+				$routerArray['controller'][$keyArray[0] . ":" . $keyArray[1]] = $valueArray[0];
+				if ($valueArray[1] == '*') $valueArray[1] = $action;
+				if ($keyArray[1] == "*") {
+					$routerArray['action'][$keyArray[0] . ":" . $keyArray[1]] = $valueArray[1];
+				} else {
+					$routerArray['action'][$keyArray[0] . ":" . $keyArray[1]] = $valueArray[1];
+				}
+			}
+		}
+		if (count($routerArray) == 0) {
+			return array('controller' => $controller, 'action' => $action);
+		}
+		if (isset($routerArray["controller"]["*:*"]) && '' != $routerArray["controller"]["*:*"])//*:*=>yyy:* or *:* => *:yyy mode
+		{
+			$controller = ($routerArray['controller']['*:*'] == '*' ? $controller : $routerArray["controller"]["*:*"]);
+			$action = ($routerArray['action']['*:*'] == '*' ? $action : $routerArray['action']['*:*']);
+		} elseif (isset($routerArray["action"][$controller . ":*"]) && '' != $routerArray["action"][$controller . ":*"])//xx:*=>yy:* mode
+		{
+			$action = $routerArray['action'][$controller . ":*"];
+			$controller = $routerArray["controller"][$controller . ":*"];
+			if (stristr($controller, '{1}')) {
+				$controller = str_replace('{1}', $action, $controller);
+				$action = $thirdParam ? $thirdParam : 'index';
+			}
+		} elseif (isset($routerArray["action"]["*:" . $action]) && '' != $routerArray["action"]["*:" . $action])//*:xxx=> yy:yyy mode
+		{
+			$controller = $routerArray["control"]["*:" . $action];
+			$action = $routerArray["action"]["*:" . $action];
+		} elseif (isset($routerArray["controller"][$controller . ":" . $action])) {
+			$tmpAction = $controller . ":" . $action;
+			$action = $routerArray["action"][$controller . ":" . $action];
+			$controller = $routerArray["controller"][$tmpAction];
+			if (stristr($action, '{1}')) {
+				$action = str_replace('{1}', $action, $thirdParam);
+			}
+		}
+		$action = !$action ? 'index' : $action;
+		return array('controller' => $controller, 'action' => $action);
+	}
+}

+ 52 - 0
Qii/Route/Parse/Regx.php

@@ -0,0 +1,52 @@
+<?php
+namespace Qii\Route\Parse;
+
+/**
+ * Route规则 支持正则表达式
+ *
+ * @author Jinhui Zhu<jinhui.zhu@live.cn>2015-10-24 23:11
+ * @version 1.2
+ */
+
+class Regx
+{
+	const VERSION = '1.2';
+	private $config;
+
+	public function __construct()
+	{
+
+	}
+
+	public function setConfig($config)
+	{
+		$this->config = $config;
+	}
+
+	/**
+	 * 匹配路由
+	 * @param String $controller 控制器名称
+	 * @param String $action 动作名称
+	 *
+	 * 支持规则:controller/(:any) controller/(:num) controller/(.*) 等一系列正则规则
+	 */
+	public function parse($controller, $action)
+	{
+		$uri = $controller . '/' . $action;
+		foreach ($this->config AS $key => $val) {
+			$key = str_replace(':any', '.+', str_replace(':num', '[0-9]+', $key));
+			// Does the RegEx match?
+			if (preg_match('#^' . $key . '$#', $uri)) {
+				// Do we have a back-reference?
+				if (strpos($val, '$') !== FALSE AND strpos($key, '(') !== FALSE) {
+					$val = preg_replace('#^' . $key . '$#', $val, $uri);
+				}
+				$router = explode('/', $val);
+				return array('controller' => $router[0], 'action' => $router[1]);
+			}
+		}
+		return array('controller' => $controller, 'action' => $action);
+	}
+}
+
+?>

+ 10 - 0
Qii/View/Vendor.php

@@ -0,0 +1,10 @@
+<?php
+namespace Qii\View;
+
+class Vendor
+{
+    public function __construct($config = [])
+    {
+        
+    }
+}

+ 12 - 0
private/Bootstrap.php

@@ -0,0 +1,12 @@
+<?php
+class Bootstrap implements \Qii\Bootstrap\Base
+{
+	public function __construct()
+	{
+		
+	}
+
+	public function _initialize()
+	{
+	}
+}

+ 10 - 0
private/Controller/Index.php

@@ -0,0 +1,10 @@
+<?php
+namespace Controller;
+
+class index extends \Qii\Controller\Base
+{
+    public function indexAction()
+    {
+        echo __CLASS__;
+    }
+}

+ 38 - 0
private/Plugins/loger.php

@@ -0,0 +1,38 @@
+<?php
+namespace Plugins;
+class loger implements \Qii\Loger\Writer
+{
+	public $logerPath = 'tmp';
+	public $fileName = 'loger.log';
+
+	public function __construct()
+	{
+		$this->logerPath = dirname(dirname(__FILE__)) .DS. $this->logerPath;
+		$this->fileName = $this->logerPath . DS . date('Y-m-d') .'.'. $this->fileName;
+		return $this;
+	}
+
+	public function setFileName($fileName)
+	{
+		$this->fileName = $this->logerPath . DS . date('Y-m-d') .'.'. $fileName . '.log';
+		return $this;
+	}
+	protected function trimSpace($text)
+	{
+	    return  str_replace(array("\r\n", "\r", "\n", "\t", "\s", ' ', chr(32)), "", $text);
+	}
+
+	public function formatLog($log)
+	{
+		if(!is_array($log)) return $log;
+		return json_encode($log);
+		return $this->trimSpace(print_r($log, true));
+	}
+
+	public function writeLog($loger)
+	{
+		if(is_array($loger)) $loger = $this->formatLog($loger);
+
+		file_put_contents($this->fileName, date('Y-m-d H:i:s') ."\n\t". $loger . "\n", FILE_APPEND);
+	}
+}

+ 108 - 0
private/configure/app.ini

@@ -0,0 +1,108 @@
+;通用配置,如果没有指定环境将使用通用配置,指定了环境,指定环境的配置将覆盖默认配置中的配置信息
+[author]
+name = 朱金辉
+email = jinhui.zhu@live.cn
+qq = 119328118
+
+[common]
+;程序是否使用命名空间
+namespace['use'] = true
+namespace[list.Controller] = true
+namespace[list.Model] = true
+namespace[list.Library] = true
+namespace[list.Action] = true
+;rewrite 方法, 此定义不能省略
+rewriteMethod = Short
+;rewrite匹配规则,可选
+rewriteRules = Normal
+;hosts中的属性将会覆盖掉默认的属性,当在不同域名上使用不同配置上很有用处
+;hosts[0.domain] = test.istudy.wang
+;hosts[0.path] = test
+;hosts[0.password] = test
+
+;用于检查系统环境的时候用到的密码,如果不填写就可以直接通过url进入
+admin[user] = admin
+admin[password] = 119328118
+;是否开启调试模式,调试模式下,所有的错误都将抛出来,并终止运行
+debug = 1
+;错误页面
+errorPage = Error:Index
+;时间区域
+timezone = Asia/Shanghai
+;文档类型
+contentType = text/html
+;文档编码
+charset = UTF-8
+;模板引擎
+view[engine] = smarty
+view[path] = view
+;smarty 引擎的相关配置
+view[smarty.view] = view
+view[smarty.path] = view
+view[smarty.ldelimiter] = {#
+view[smarty.rdelimiter] = #}
+view[smarty.compile] = tmp/compile
+view[smarty.cache] = tmp/cache
+view[smarty.lifetime] = 300
+;缓存类型
+cache = memcache
+
+;是否开启安全验证,enable:是否开启安全验证;key:POST数据的时候安全字符串加密用到的key
+security[enable] = true
+security[name] = security_sid
+security[expired] = 3600
+security[key] = 4cd780a986d5c30e03bdcb67d16c8320
+
+;memcache配置,多个服务器IP和端口以;隔开
+memcache[servers] = 127.0.0.1
+memcache[ports] = 11211
+
+
+;搜索文件路径
+xpath[] = controller
+xpath[] = model
+xpath[] = class
+xpath[] = plugin
+
+;map:为参数的顺序,当启用短URI标签的情况下会按照这个顺序去遍历参数;
+query[] = controller
+query[] = action
+query[] = param
+
+;controller、action配置  name:参数名 ext:后缀;default:默认方法 
+controller[name] = controller
+controller[prefix] = Controller
+controller[default] = index
+
+action[name] = action
+action[suffix] = Action
+action[default] = index
+
+;url相关配置,用于生成链接用
+[uri]
+
+;url模式,短链接模式
+mode = short
+controllerName = controller
+actionName = action
+
+normal[mode] = normal
+normal[trim] = 0
+normal[symbol] = "&"
+normal[extenstion] = .html
+
+middle[mode] = middle
+middle[trim] = 1
+middle[symbol] = "/"
+middle[extenstion] = .html
+
+short[mode] = short
+short[trim] = 1
+short[symbol] = "/"
+short[extenstion] = .html
+;以下这种写法将会继承:后边的section,如果是"."开头的话就放在当前key下边
+[dev:common:.uri]
+password = 12345
+[product:common:.uri]
+password = 119328118
+

+ 24 - 0
private/configure/db.ini

@@ -0,0 +1,24 @@
+;数据库配置
+[common]
+;是否读写分离
+readOrWriteSeparation = 0
+driver = pdo
+;使用的数据库类型
+use_db_driver = mysql
+master[db] = istudy
+master[host] = 127.0.0.1
+master[user] = root
+master[password] = 119328118
+
+slave[0.db] = istudy
+slave[0.host] = 127.0.0.1
+slave[0.user] = root
+slave[0.password] = 119328118
+
+
+slave[1.db] = istudy
+slave[1.host] = 127.0.0.1
+slave[1.user] = root
+slave[1.password] = 119328118
+
+[product:common]

+ 5 - 0
private/configure/router.config.php

@@ -0,0 +1,5 @@
+<?php
+return [
+    'home:index' => 'index:index',
+    'manage:*' => 'manage\{1}:*'
+];

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 1 - 0
private/tmp/2017-06-27.loger.log


+ 108 - 0
private/tmp/product.app.ini.php

@@ -0,0 +1,108 @@
+<?php 
+ return array (
+  'namespace' => 
+  array (
+    'use' => '1',
+    'list' => 
+    array (
+      'Controller' => '1',
+      'Model' => '1',
+      'Library' => '1',
+      'Action' => '1',
+    ),
+  ),
+  'rewriteMethod' => 'Short',
+  'rewriteRules' => 'Normal',
+  'admin' => 
+  array (
+    'user' => 'admin',
+    'password' => '119328118',
+  ),
+  'debug' => '1',
+  'errorPage' => 'Error:Index',
+  'timezone' => 'Asia/Shanghai',
+  'contentType' => 'text/html',
+  'charset' => 'UTF-8',
+  'view' => 
+  array (
+    'engine' => 'smarty',
+    'path' => 'view',
+    'smarty' => 
+    array (
+      'view' => 'view',
+      'path' => 'view',
+      'ldelimiter' => '{#',
+      'rdelimiter' => '#}',
+      'compile' => 'tmp/compile',
+      'cache' => 'tmp/cache',
+      'lifetime' => '300',
+    ),
+  ),
+  'cache' => 'memcache',
+  'security' => 
+  array (
+    'enable' => '1',
+    'name' => 'security_sid',
+    'expired' => '3600',
+    'key' => '4cd780a986d5c30e03bdcb67d16c8320',
+  ),
+  'memcache' => 
+  array (
+    'servers' => '127.0.0.1',
+    'ports' => '11211',
+  ),
+  'xpath' => 
+  array (
+    0 => 'controller',
+    1 => 'model',
+    2 => 'class',
+    3 => 'plugin',
+  ),
+  'query' => 
+  array (
+    0 => 'controller',
+    1 => 'action',
+    2 => 'param',
+  ),
+  'controller' => 
+  array (
+    'name' => 'controller',
+    'prefix' => 'Controller',
+    'default' => 'index',
+  ),
+  'action' => 
+  array (
+    'name' => 'action',
+    'suffix' => 'Action',
+    'default' => 'index',
+  ),
+  'password' => '119328118',
+  'uri' => 
+  array (
+    'mode' => 'short',
+    'controllerName' => 'controller',
+    'actionName' => 'action',
+    'normal' => 
+    array (
+      'mode' => 'normal',
+      'trim' => '0',
+      'symbol' => '&',
+      'extenstion' => '.html',
+    ),
+    'middle' => 
+    array (
+      'mode' => 'middle',
+      'trim' => '1',
+      'symbol' => '/',
+      'extenstion' => '.html',
+    ),
+    'short' => 
+    array (
+      'mode' => 'short',
+      'trim' => '1',
+      'symbol' => '/',
+      'extenstion' => '.html',
+    ),
+  ),
+)
+?>

+ 31 - 0
private/tmp/product.db.ini.php

@@ -0,0 +1,31 @@
+<?php 
+ return array (
+  'readOrWriteSeparation' => '0',
+  'driver' => 'pdo',
+  'use_db_driver' => 'mysql',
+  'master' => 
+  array (
+    'db' => 'istudy',
+    'host' => '127.0.0.1',
+    'user' => 'root',
+    'password' => '119328118',
+  ),
+  'slave' => 
+  array (
+    0 => 
+    array (
+      'db' => 'istudy',
+      'host' => '127.0.0.1',
+      'user' => 'root',
+      'password' => '119328118',
+    ),
+    1 => 
+    array (
+      'db' => 'istudy',
+      'host' => '127.0.0.1',
+      'user' => 'root',
+      'password' => '119328118',
+    ),
+  ),
+)
+?>

+ 9 - 3
public/index.php

@@ -1,6 +1,12 @@
 <?php
 require_once('../Qii/Qii.php');
 $app = \Qii::getInstance();
-$app->setConfig('site', ['env' => 'product', ['siteName' => 'Qii'] ]);
-$app->run();
-new s();
+$app->setWorkspace('../private')
+->setCachePath('tmp')
+->setAppConfigure('configure/app.ini')
+->setUseNamespace('Bootstrap', false)
+->setLoger('Plugins\loger')
+->setDB('configure/db.ini')
+->setRouter('configure/router.config.php')
+->setBootstrap()
+->run();

Některé soubory nejsou zobrazeny, neboť je v těchto rozdílových datech změněno mnoho souborů