├── .htaccess ├── README.md ├── application ├── admin │ ├── controller │ │ ├── Common.php │ │ └── Index.php │ ├── model │ │ └── User.php │ └── view │ │ └── index.html ├── common │ ├── 404 │ │ ├── images │ │ │ ├── 404.png │ │ │ └── 404_bg.jpg │ │ └── index.php │ └── Helper.php ├── config │ └── Config.php ├── home │ ├── controller │ │ ├── Common.php │ │ └── Index.php │ ├── model │ │ └── User.php │ └── view │ │ └── default │ │ └── index │ │ └── index.php └── log │ └── php.error.log ├── composer.json ├── index.php └── system ├── Init.php ├── common └── Helper.php └── core ├── Config.php ├── Database.php ├── Exception.php ├── Loader.php ├── Model.php └── Route.php /.htaccess: -------------------------------------------------------------------------------- 1 | 2 | Options +FollowSymlinks 3 | RewriteEngine On 4 | RewriteRule ^(system) - [F,L] 5 | RewriteCond %{REQUEST_FILENAME} !-f 6 | RewriteCond %{REQUEST_FILENAME} !-d 7 | RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L] 8 | 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Idea framework 超轻量级PHP框架 2 | ## Idea核心理念 3 | * 用户体验目标:简单到极致! 4 | * 降低框架学习成本,以最好的通用性开发低耦合的产品。 5 | 6 | ## 框架功能简述 7 | * 超轻量级框架,拥有框架应有的核心功能。 8 | * 完全基于OOP思想、MVC架构开发。 9 | * 自动加载psr-4标准化,编码遵守PSR-2 10 | * 支持PHP7.x+,支持跨平台开发。 11 | * 支持自定义项目结构,入口绑定支持(多入口)。 12 | * 完善的路由支持:普通模式、PATHINFO、伪静态等。 13 | * 原生PHP模板引擎,可轻松扩展其它模板引擎(如smarty、twig等)。 14 | * 数据操作基于PDO,多数据库支持,CURD使用原生SQL,无须深入学习框架。 15 | * 推荐使用composer进行类库扩展。 16 | 17 | 文档地址:http://www.kancloud.cn/yunfei_z/framework 18 | 19 | 电子邮箱:20874823@qq.com 20 | 21 | 作者主页:https://ashub.cn 22 | 23 | #### 当前版本:V1.0 24 | 25 | #### 2016-10-18 发布Idea framework V1.0 正式版 26 | -------------------------------------------------------------------------------- /application/admin/controller/Common.php: -------------------------------------------------------------------------------- 1 | 返回'; 27 | } 28 | } -------------------------------------------------------------------------------- /application/admin/model/User.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {#$title#} 5 | 6 | 7 |

后台首页

8 | 欢迎您,{#$info#}。 9 | 10 | -------------------------------------------------------------------------------- /application/common/404/images/404.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codingcn/Idea-framework/c57b91befffd192be0a1ebfba772bb839d00def7/application/common/404/images/404.png -------------------------------------------------------------------------------- /application/common/404/images/404_bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codingcn/Idea-framework/c57b91befffd192be0a1ebfba772bb839d00def7/application/common/404/images/404_bg.jpg -------------------------------------------------------------------------------- /application/common/404/index.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 404 Not Found! 8 | 91 | 92 | 93 |
94 | > 95 |
96 |

温馨提示,您访问的地址不存在!

97 |

98 | 99 | 网址有错误>请检查地址是否完整或存在多余字符
100 |        101 |     102 | 网址已失效>可能页面已删除,活动已下线等 103 |

104 |

您正在寻找的页面无法找到, 105 | onclick="history.go(-1)">回到首页?

106 | 107 |
108 |
109 | 110 | -------------------------------------------------------------------------------- /application/common/Helper.php: -------------------------------------------------------------------------------- 1 | debug output:
'; 21 | $func($val); 22 | echo ''; 23 | } 24 | 25 | /** 26 | * 打印框架已定义常量 27 | * @return mixed $constArr 数组格式所有的预定义常量 28 | */ 29 | function printConst() 30 | { 31 | $constArr = get_defined_constants(true); 32 | echo '
';
33 |     var_dump($constArr['user']);
34 |     echo '
'; 35 | } -------------------------------------------------------------------------------- /application/config/Config.php: -------------------------------------------------------------------------------- 1 | [ 13 | 'system' => FRAMEWORK_PATH . 'core', 14 | 'app' => ROOT_PATH . 'application', 15 | //'test' => ROOT_PATH.'test', 16 | ], 17 | /** 18 | * 应用类库的根命名空间 19 | */ 20 | 'app_namespace' => 'app', 21 | 22 | 23 | /** 24 | * 文件(包括控制器/模型/类库等)命名均为pascal命名 25 | * 26 | * 默认命名空间及目录均为小写模式 27 | * 28 | * 设置为true即开启pascal命名法 29 | * 目录及命名空间首字母需大写 30 | * 31 | */ 32 | 'default_charset' => 'UTF-8', 33 | 'default_timezone' => 'PRC', 34 | 35 | 36 | 37 | /** 38 | * true为显示错误 39 | * 错误显示开关 40 | */ 41 | 'display_errors' => true, 42 | 43 | /** 44 | * 该项仅在(display_errors = false)条件下有效 45 | * 页面错误模板(404页面) 46 | */ 47 | 'error_template' => APP_PATH . 'common/404/index.php', 48 | /** 49 | * 该项仅在(display_errors = false)条件下有效 50 | * php错误写到日志文件 51 | */ 52 | 'error_log_file' => APP_PATH . 'log/php.error.log', 53 | 54 | 55 | 56 | /** 57 | * URL大小写配置,true为不区分大小写,false为区分 58 | * 推荐设置为区分大小写 59 | */ 60 | 'url_case' => true, 61 | /** 62 | * 仅当url_case为true时,该项有效 63 | * URL驼峰命名分隔符 64 | * 该项不能与path_separator设为相同值,避免冲突 65 | * 66 | * 当控制器或操作方法的命名是两个单词拼接时,且使用驼峰法 67 | * 下面两种URL写法是等效的, 68 | * http://servername.com/Idea-framework/index.php/home/MyClass/sayHello 69 | * http://servername.com/Idea-framework/home/my_class/say_hello 70 | */ 71 | 'url_case_separator' => '_', 72 | 73 | 74 | /** 75 | * 应用扩展目录 76 | * 该项为框架内置import()函数提供支持 77 | */ 78 | 'extend_path' => APP_PATH . 'extend/', 79 | 80 | /** 81 | * composer自动加载文件引入 82 | */ 83 | 'composer_aotuload_file' => APP_PATH . 'vendor/autoload.php', 84 | 85 | 86 | /** 87 | * 设置默认操作 88 | * 严格区分大小写,请正确设置 89 | */ 90 | 'model_dir' => 'model', //模型目录 91 | 'controller_dir' => 'controller', //控制器目录 92 | 'default_module' => 'home', //默认模块(平台、分组) 93 | 'default_controller' => 'Index', //默认控制器(该项首字母必须大写,因为控制器文件名是大驼峰命名的) 94 | 'default_action' => 'index', //默认控制器方法 95 | 96 | 97 | /** 98 | * URL路由模式选择 99 | * 1. 普通模式 如:http://servername.com/index.php?m=Home&c=User&a=login 100 | * 2. PATHINFO 如:http://servername.com/index.php/Home/User/login 101 | * 3. 当配置伪静态后,URL可以更加简洁,如http://servername.com/Home/User/login 102 | */ 103 | 'url_mode' => '1', 104 | 105 | /** 106 | * url_mode为2时该项生效 107 | * URL分割符,在开启PATHINFO模式下有效,如:http://servername.com/index.php/Home-User-login 108 | * * 该项不能与url_case_separator设为相同值,避免冲突 109 | */ 110 | 'path_separator' => '/', 111 | 112 | /** 113 | * 设置默认dsn,必须在dsn列表中存在 114 | * 115 | */ 116 | 'default_dsn' => 'master', 117 | 118 | /** 119 | * dsn列表 120 | * 更多dsn设置可以参考PHP官方手册 121 | */ 122 | 'dsn' => [ 123 | 'master' => [ 124 | 'mysql:127.0.0.1;port=3306;dbname=mydb', 125 | 'root', 126 | '123456', 127 | [ 128 | //array $driver_options 129 | PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES "utf8"', 130 | PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, 131 | PDO::ATTR_PERSISTENT => false, 132 | //更多驱动选项请参考PHP手册 133 | ] 134 | ], 135 | 'mysql_slave1' => [ 136 | 'mysql:host=localhost;port=3306;dbname=test', 137 | 'root', 138 | '123456', 139 | [ 140 | //array $driver_options 141 | PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES "utf8"', 142 | PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, 143 | ] 144 | ], 145 | /* 146 | 'mssql' => [ 147 | 'odbc:Driver={SQL Server};Server=localhost;Database=mydb', 148 | 'sa', 149 | '123456' 150 | ], 151 | 152 | 'oci' => ['oci:dbname=//db.example.com:1521/mydb','username','password'], 153 | 154 | 'sqlite' => 'sqlite:c:/data/sqlite.db', 155 | 156 | 'postgreSQL'=>[pgsql:host=localhost;port=5432;dbname=testdb], 157 | */ 158 | ], 159 | 160 | 161 | //这里可以添加更多自己的配置 162 | 163 | ]; -------------------------------------------------------------------------------- /application/home/controller/Common.php: -------------------------------------------------------------------------------- 1 | tpl_path = APP_PATH . 'home/view/default/'; 20 | 21 | } 22 | 23 | } -------------------------------------------------------------------------------- /application/home/controller/Index.php: -------------------------------------------------------------------------------- 1 | 框架已成功部署,"; 18 | $ok .= "

欢迎使用 Idea framework!

"; 19 | $ok .= " 20 | Idea官网 21 | 在线手册 22 | 后台管理"; 23 | $no = '

Warning:服务器环境错误!

24 | 错误信息:没有开启pdo_mysql扩展!
25 | 帮助信息:请尝试打开php.ini将 去除;extension=php_pdo_mysql.dll 前面的分号,并重启服务器'; 26 | require $this->tpl_path . 'index/index.php'; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /application/home/model/User.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Idea framework! 6 | 7 | 8 | 15 | 16 | -------------------------------------------------------------------------------- /application/log/php.error.log: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codingcn/Idea-framework/c57b91befffd192be0a1ebfba772bb839d00def7/application/log/php.error.log -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "idea/framework", 3 | "description": "The idea framework!", 4 | "type": "project", 5 | "homepage": "https://ashub.cn", 6 | "keywords": [ 7 | "PHP", 8 | "Framework", 9 | "MVC", 10 | "Simple" 11 | ], 12 | "authors": [ 13 | { 14 | "name": "Alan", 15 | "email": "20874823@qq.com", 16 | "homepage": "https://199461.com", 17 | "role": "Developer" 18 | } 19 | ], 20 | "license": "MIT", 21 | "require": { 22 | "php": ">=5.4", 23 | "filp/whoops":"*", 24 | "symfony/debug": "^3.1", 25 | "symfony/var-dumper": "^3.1" 26 | }, 27 | "config": { 28 | "vendor-dir": "application/vendor" 29 | }, 30 | "repositories": { 31 | "packagist": { 32 | "type": "composer", 33 | "url": "https://packagist.phpcomposer.com" 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | get(); 20 | break; 21 | case 1: 22 | return $config->get($args[0]); 23 | break; 24 | case 2: 25 | $config->set($args[0], $args[1]); 26 | break; 27 | default: 28 | return false; 29 | break; 30 | } 31 | } 32 | 33 | /** 34 | * 自定义Model方法,对模型类进行单例化 35 | * @param null $model_name 36 | * @param null $model_method 37 | * @return object 38 | */ 39 | function model($model_name = null, $model_method = null) 40 | { 41 | if (is_null($model_method)) { 42 | $obj = \system\Model::getModel(config('app_namespace') . '\\' . MODULE . '\\' . config('model_dir') . '\\' . $model_name); 43 | } else { 44 | $obj = \system\Model::getModel(config('app_namespace') . '\\' . MODULE . '\\' . config('model_dir') . '\\' . $model_name)->$model_method(); 45 | } 46 | return $obj; 47 | } 48 | 49 | 50 | /** 51 | * 类库加载函数 52 | * @param $class_file 53 | * @throws Exception 54 | */ 55 | function import($class_file) 56 | { 57 | $class_path = config('extend_path') . trim($class_file, '/') . '.php'; 58 | try { 59 | if (file_exists($class_path)) { 60 | include $class_path; 61 | } else { 62 | throw new \system\Exception("所加载类不存在," . $class_path); 63 | } 64 | } catch (\system\Exception $e) { 65 | $e->getDetail(); 66 | } 67 | } 68 | 69 | function notFound() 70 | { 71 | header("HTTP/1.1 404 Not Found"); 72 | header("status: 404 Not Found"); 73 | include config('error_template'); 74 | exit; 75 | } 76 | 77 | /** 78 | * 直接跳转方法 79 | * @access protected 80 | * @param string $jumpUrl 跳转地址 81 | */ 82 | function direct($jumpUrl = '') 83 | { 84 | header("Location:$jumpUrl"); 85 | exit; 86 | } 87 | 88 | /** 89 | * 等待提示跳转 90 | * @access protected 91 | * @param string $message 提示信息 92 | * @param string $jumpUrl 跳转地址 93 | * @param int $waitTime 跳转时间(单位:秒) 94 | */ 95 | function wait($jumpUrl = '', $message = '', $waitTime = 3) 96 | { 97 | header("Refresh:$waitTime;URL=$jumpUrl"); 98 | if (is_file($message)) { 99 | include $message; 100 | } else { 101 | echo $message; 102 | } 103 | exit; 104 | } 105 | -------------------------------------------------------------------------------- /system/core/Config.php: -------------------------------------------------------------------------------- 1 | 6 | * @datetime 2016/10/4 13:18 7 | * @copyright Copyright (c) 2016 8 | * @version 1.0 9 | */ 10 | 11 | namespace system; 12 | 13 | 14 | /** 15 | * Class Config 16 | * @package system 17 | */ 18 | class Config 19 | { 20 | private $config = []; 21 | private static $instance; 22 | 23 | 24 | /** 25 | * @return Config 获得单例对象 26 | */ 27 | public static function getInstance() 28 | { 29 | if (!(self::$instance instanceof self)) { 30 | self::$instance = new self; 31 | } 32 | return self::$instance; 33 | } 34 | 35 | /** 36 | * 加载配置文件 37 | * Config constructor. 38 | */ 39 | private function __construct() 40 | { 41 | if (file_exists(CONFIG_FILE)) { 42 | 43 | } 44 | if (empty($this->config) && is_readable(CONFIG_FILE)) { 45 | return $this->config = include CONFIG_FILE; 46 | } else { 47 | return $this->config = []; 48 | } 49 | } 50 | 51 | private function __clone() {} 52 | 53 | /** 54 | * 获取配置参数 55 | * @param null $name 参数名 56 | * @return array|bool|mixed 参数值 57 | */ 58 | public function get($name = null) 59 | { 60 | if (isset($this->config) && empty($name)) { 61 | return $this->config; 62 | } 63 | $path = explode('.', $name); 64 | $value = $this->config; 65 | foreach ($path as $param) { 66 | if (isset($value[$param])) { 67 | $value = $value[$param]; 68 | } else { 69 | return false; 70 | } 71 | } 72 | return $value; 73 | } 74 | 75 | /** 76 | * 动态设置配置(递归) 77 | * @param $name string 配置值 78 | * @param $value string 配置参数 79 | * @return array 80 | */ 81 | public function set($name, $value) 82 | { 83 | $path = explode('.', $name); 84 | for ($i = count($path) - 1; $i >= 0; $i--) { 85 | $value = [$path[$i] => $value]; 86 | } 87 | $this->config = self::array_merge_multi($this->config, $value); 88 | return $this->config; 89 | } 90 | 91 | /** 92 | * [array_merge_multi description] 93 | * @return array 合并多维数组 94 | */ 95 | private static function array_merge_multi() 96 | { 97 | $args = func_get_args(); 98 | $array = []; 99 | foreach ($args as $arg) { 100 | if (is_array($arg)) { 101 | foreach ($arg as $k => $v) { 102 | if (is_array($v)) { 103 | $array[$k] = isset($array[$k]) ? $array[$k] : []; 104 | $array[$k] = self::array_merge_multi($array[$k], $v); 105 | } else { 106 | $array[$k] = $v; 107 | } 108 | } 109 | } 110 | } 111 | return $array; 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /system/core/Database.php: -------------------------------------------------------------------------------- 1 | newInstanceArgs($dsn); 50 | } else { 51 | self::$instance[$key] = new \PDO($dsn); 52 | } 53 | } 54 | //返回连接 55 | return self::$instance[$key]; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /system/core/Exception.php: -------------------------------------------------------------------------------- 1 | 6 | * @datetime 2016/10/13 17:55 7 | * @copyright Copyright (c) 2016 8 | * @version 1.0 9 | */ 10 | 11 | namespace system; 12 | 13 | 14 | /** 15 | * Class Exception 16 | * @package system 17 | */ 18 | class Exception extends \Exception 19 | { 20 | /** 21 | * NotFoundException constructor. 22 | * @param string $message 23 | * @param int $code 24 | */ 25 | public function __construct($message, $code = 0) 26 | { 27 | // 确保所有变量都被正确赋值 28 | parent::__construct($message, $code); 29 | } 30 | 31 | public function getDetail() 32 | { 33 | echo '

出现异常了!

'; 34 | $msg = '

错误内容:' . $this->getMessage() . '

'; 35 | $msg .= '

异常抛出位置:' . $this->getFile() . ',第' . $this->getLine() . '

'; 36 | $msg .= '

异常追踪信息:' . $this->getTraceAsString() . '

'; 37 | echo $msg; 38 | exit; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /system/core/Loader.php: -------------------------------------------------------------------------------- 1 | 6 | * @datetime 2016/8/16 13:12 7 | * @copyright Copyright (c) 2016 8 | * @version 1.0 9 | */ 10 | namespace system; 11 | 12 | /** 13 | * Class Loader 14 | * @package system 15 | */ 16 | class Loader 17 | { 18 | 19 | private static $prefixes = []; 20 | 21 | public static function run() 22 | { 23 | self::setHeader(); 24 | //系统类映射 25 | self::getMapList(); 26 | // 注册自动加载ideaAutoload方法 27 | self::register(); 28 | self::composerload(); 29 | //实例化路由 30 | try { 31 | new Route(); 32 | } catch (Exception $e) { 33 | $e->getDetail(); 34 | } 35 | } 36 | private static function setHeader() 37 | { 38 | header("Content-type:text/html;Charset=".config('default_charset')); 39 | date_default_timezone_set(config('default_timezone')); 40 | } 41 | 42 | /** 43 | * 注册自动加载 44 | * 45 | * @return void 46 | */ 47 | public static function register() 48 | { 49 | spl_autoload_register('self::ideaAutoload'); 50 | } 51 | 52 | /** 53 | * 为命名空间前缀添加一个对应的基目录. 54 | * 55 | * @param string $prefix 命名空间前缀. 56 | * @param string $base_dir 基目录 57 | * namespace. 58 | * @param bool $prepend 前缀一致的两个base_dir,为true的在列表最开始插入 59 | * @return void 60 | */ 61 | 62 | public static function addNamespace($prefix, $base_dir, $prepend = false) 63 | { 64 | //格式化命名空间前缀,以反斜杠结束 65 | $prefix = trim($prefix, '\\') . '\\'; 66 | //格式化基目录以正斜杠结尾 67 | $base_dir = rtrim($base_dir, '/') . DIRECTORY_SEPARATOR; 68 | $base_dir = rtrim($base_dir, DIRECTORY_SEPARATOR) . '/'; 69 | //初始化命名空间前缀数组 70 | //如果前缀已存在数组中则跳过,否则存入数组 71 | if (isset(self::$prefixes[$prefix]) === false) { 72 | self::$prefixes[$prefix] = []; 73 | } 74 | 75 | if ($prepend) { 76 | //命名空间前缀相同时,后增基目录 77 | array_unshift(self::$prefixes[$prefix], $base_dir); 78 | } else { 79 | //前增 80 | array_push(self::$prefixes[$prefix], $base_dir); 81 | } 82 | } 83 | 84 | private static function getMapList() 85 | { 86 | foreach (Config::getInstance()->get('namespace_map_list') as $key => $value) { 87 | self::addNamespace($key, $value); 88 | } 89 | } 90 | 91 | /** 92 | * IdeaPHP框架自动加载方法 93 | * @param string $class_name 自动加载类/接口名 94 | * @return bool|mixed 映射文件名存在就加载,否则返回false 95 | */ 96 | private static function ideaAutoload($class_name) 97 | { 98 | // 当前命名空间前缀 99 | $prefix = $class_name; 100 | //从后面开始遍历完全合格类名中的命名空间名称,来查找映射的文件名 101 | while (false !== $pos = strrpos($prefix, '\\')) { 102 | // 命名空间前缀 103 | $prefix = substr($class_name, 0, $pos + 1); 104 | // 相对的类名 105 | $relative_class = substr($class_name, $pos + 1); 106 | //尝试加载与映射文件相对的类 107 | $mapped_file = self::loadMappedFile($prefix, $relative_class); 108 | if ($mapped_file) { 109 | return $mapped_file; 110 | } 111 | //去除前缀的反斜杠 112 | $prefix = rtrim($prefix, '\\'); 113 | } 114 | return false; 115 | } 116 | 117 | /** 118 | * 根据命名空间及相对类来加载映射文件. 119 | * 120 | * @param string $prefix 命名空间前缀 121 | * @param string $relative_class 相对类名 122 | * @return mixed Boolean 没有映射文件被加载为 false 123 | */ 124 | 125 | private static function loadMappedFile($prefix, $relative_class) 126 | { 127 | //这个命名空间前缀是否存在基本的目录? 128 | if (isset(self::$prefixes[$prefix]) === false) { 129 | return false; 130 | } 131 | 132 | $relative_class = str_replace('\\', '/', $relative_class); 133 | 134 | foreach (self::$prefixes[$prefix] as $base_dir) { 135 | $file = $base_dir . $relative_class . '.php'; 136 | // 如果映射文件存在就加载它 137 | if (self::requireFile($file)) { 138 | // 做一其他事 139 | } 140 | } 141 | return false; 142 | } 143 | 144 | /** 145 | * 如果文件存在,就从文件系统加载它 146 | * 147 | * @param string $file 加载文件 148 | * @return bool 文件存在 true 149 | */ 150 | private static function requireFile($file) 151 | { 152 | if (file_exists($file)) { 153 | include $file; 154 | return true; 155 | } 156 | return false; 157 | } 158 | private static function composerload() 159 | { 160 | //composer自动加载 161 | file_exists(config('composer_aotuload_file')) ? include config('composer_aotuload_file') : false; 162 | } 163 | } 164 | 165 | -------------------------------------------------------------------------------- /system/core/Model.php: -------------------------------------------------------------------------------- 1 | 6 | * @datetime 2016/4/22 13:12 7 | * @copyright Copyright (c) 2016 8 | * @version 1.0 9 | */ 10 | namespace system; 11 | 12 | 13 | class Model 14 | { 15 | //存储实例化的数据库操作对象 16 | protected static $db; 17 | protected static $dsn_key; 18 | 19 | /** 20 | * Model constructor. 21 | */ 22 | public function __construct() 23 | { 24 | //pdo对象 25 | self::$db = self::connect(); 26 | } 27 | 28 | /** 29 | * 选择数据源 30 | * @param $key string 数据源key 31 | * @return object pdo对象 32 | */ 33 | protected static function connect($key = null) 34 | { 35 | self::$dsn_key = isset($key) ? $key : config('default_dsn'); 36 | try { 37 | self::$db = Database::getInstance(self::$dsn_key); 38 | } catch (\PDOException $e) { 39 | echo '

数据库异常!

'; 40 | echo '

异常信息:' . $e->getMessage() . '

'; 41 | echo '

异常信息追踪:' . $e->getTraceAsString() . '

'; 42 | exit; 43 | } 44 | return self::$db; 45 | } 46 | 47 | 48 | /** 49 | * 获得模型的单例对象 50 | * 针对所有模型 调用方法 $UserModel=self::getModel('User'); 51 | * Helper.php内的方法model(模型名,模型方法名);进行调用该类 52 | * @param string $model_name 需要得到单例对象的模型的名字,例如"User"或者"UserModel" 53 | * @return object 该模型类的单例对象 54 | */ 55 | public static function getModel($model_name) 56 | { 57 | //储存所有的模型方法 58 | static $model_lists = []; //'User'=>Object(UserModel) 59 | //判断该模型类是否已经实例化对象 60 | if (!isset($model_lists[$model_name])) { 61 | //该模型类对象不存在,则实例化 62 | $model_class_name = $model_name; 63 | $model_lists[$model_name] = new $model_class_name(); 64 | } 65 | //返回获取的模型对象 66 | return $model_lists[$model_name]; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /system/core/Route.php: -------------------------------------------------------------------------------- 1 | 6 | * @datetime 2016/8/16 13:12 7 | * @copyright Copyright (c) 2016 8 | * @version 1.0 9 | */ 10 | namespace system; 11 | 12 | 13 | /** 14 | * Class Route 15 | * @package system 16 | */ 17 | class Route 18 | { 19 | private $current_module; //当前模块 20 | private $current_controller; //当前控制器 21 | private $current_action; //当前操作 22 | private $moduleDir; //模块目录 23 | private $controllerFile; //控制器文件 24 | private $controllerClassName; //控制器名 25 | private $controllerObj; 26 | 27 | /** 28 | * 加载配置信息 29 | */ 30 | public function __construct() 31 | { 32 | //设置__ROOT__值 33 | $this->setRoot(); 34 | //路由解析 35 | $this->parseUrl(); 36 | //大小写判断 37 | $this->judgmentCase(); 38 | //调用方法 39 | $this->newAction(); 40 | } 41 | 42 | /** 43 | * 判断是否SSL协议 44 | * @return boolean 45 | */ 46 | private static function isSsl() 47 | { 48 | if (isset($_SERVER['HTTPS']) && ('1' == $_SERVER['HTTPS'] || 'on' == strtolower($_SERVER['HTTPS']))) { 49 | return true; 50 | } elseif (isset($_SERVER['SERVER_PORT']) && ('443' == $_SERVER['SERVER_PORT'])) { 51 | return true; 52 | } 53 | return false; 54 | } 55 | 56 | /** 57 | * 设置__ROOT__常量值 58 | */ 59 | private function setRoot() 60 | { 61 | $scheme = self::isSsl() ? 'https://' : 'http://'; 62 | if (PHP_SAPI != 'cli') { 63 | //服务器方式(URL),项目的根路径,也就是网站根目录 64 | define('__ROOT__', trim($scheme . $_SERVER['HTTP_HOST'] . $_SERVER["SCRIPT_NAME"], '/')); 65 | define('ENTRANCE', substr(__ROOT__, strrpos(__ROOT__, '/') + 1)); //入口文件名 66 | define('__APP__', rtrim($scheme . $_SERVER['HTTP_HOST'] . $_SERVER['SCRIPT_NAME'], ENTRANCE) . APP_NAME); 67 | } else { 68 | // 当前应用地址 69 | define('__ROOT__', ROOT_PATH . '/'); 70 | define('__APP__', rtrim(ROOT_PATH, ENTRANCE) . APP_NAME . '/'); 71 | } 72 | } 73 | 74 | /** 75 | * 分发参数 76 | */ 77 | private function parseUrl() 78 | { 79 | if (config('url_mode') == '1') { 80 | $this->current_module = isset($_GET['m']) ? $_GET['m'] : config('default_module'); 81 | //通过判断url里面是否存在c参数,如果没有则设为默认控制器 82 | $this->current_controller = isset($_GET['c']) ? $_GET['c'] : config('default_controller'); 83 | $this->current_action = isset($_GET['a']) ? $_GET['a'] : config('default_action'); 84 | } elseif (config('url_mode') == '2') { 85 | if (isset($_SERVER['PATH_INFO'])) { 86 | $paths = explode(config('path_separator'), trim($_SERVER['PATH_INFO'], '/')); 87 | $url_module = array_shift($paths); 88 | $url_controller = array_shift($paths); 89 | $url_action = array_shift($paths); 90 | //传值操作 91 | for ($i = 0; $i < count($paths); $i += 2) { 92 | if (isset($paths[$i + 1])) { 93 | $_GET[$paths[$i]] = $paths[$i + 1]; 94 | } elseif (config('display_errors') == false) { 95 | notFound(); 96 | } else { 97 | throw new Exception($paths[$i] . '未设置一个参数值'); 98 | } 99 | } 100 | } 101 | $this->current_module = !empty($url_module) ? $url_module : config('default_module'); 102 | //通过判断url里面是否存在c参数,如果没有则设为默认控制器 103 | $this->current_controller = !empty($url_controller) ? $url_controller : config('default_controller'); 104 | $this->current_action = !empty($url_action) ? $url_action : config('default_action'); 105 | } else { 106 | throw new Exception('不存在的路由参数url_mode,' . config('url_mode')); 107 | } 108 | } 109 | 110 | /** 111 | * 字符串命名风格转换 112 | * type 0 将Java风格转换为C的风格(下划线分割) 113 | * 1 将C风格转换为Java的风格(大驼峰) 114 | * 2 转型为小驼峰 115 | * @param string $name 字符串 116 | * @param boolean $type 转换类型 117 | * @return string 118 | */ 119 | private static function parseName($name, $type = 0) 120 | { 121 | if ($type == 0) { 122 | $replace = preg_replace_callback( 123 | '/' . config('url_case_separator') . '([a-zA-Z])/', 124 | function ($match) { 125 | return strtoupper($match[1]); 126 | }, 127 | $name); 128 | return ucfirst($replace); 129 | } elseif ($type == 1) { 130 | $replace = strtolower(trim(preg_replace('/[A-Z]/', config('url_case_separator') . '\0', $name), config('url_case_separator'))); 131 | return $replace; 132 | } elseif ($type == 2) { 133 | $replace = preg_replace_callback( 134 | '/' . config('url_case_separator') . '([a-zA-Z])/', 135 | function ($match) { 136 | return strtoupper($match[1]); 137 | }, 138 | $name); 139 | return $replace; 140 | } 141 | } 142 | 143 | /** 144 | * 判断大小写并定义url常量 145 | */ 146 | private function judgmentCase() 147 | { 148 | $url_case = config('url_case'); 149 | 150 | define('MODULE', $this->current_module); 151 | define('CONTROLLER', $url_case ? self::parseName($this->current_controller, 0) : $this->current_controller); 152 | define('ACTION', $url_case ? self::parseName($this->current_action, 2) : $this->current_action); 153 | 154 | if (config('url_mode') == '1') { 155 | define('__MODULE__', __ROOT__ . '?m=' . MODULE); 156 | define('__CONTROLLER__', __MODULE__ . '&c=' . CONTROLLER); 157 | define('__ACTION__', __CONTROLLER__ . '&a=' . ACTION); 158 | } elseif (config('url_mode') == '2') { 159 | define('__MODULE__', __ROOT__ . '/' . MODULE); 160 | define('__CONTROLLER__', __MODULE__ . config('path_separator') . CONTROLLER); 161 | define('__ACTION__', __CONTROLLER__ . config('path_separator') . ACTION); 162 | } 163 | 164 | $this->controllerClassName = config('app_namespace') . '\\' . MODULE . '\\' . config('controller_dir') . '\\' . CONTROLLER; 165 | //模块文件夹 166 | $this->moduleDir = APP_PATH . MODULE; 167 | 168 | //控制器文件 169 | $this->controllerFile = $this->moduleDir . '/' . config('controller_dir') . '/' . CONTROLLER . '.php'; 170 | } 171 | 172 | /** 173 | * 实例化控制器并调用操作 174 | */ 175 | private function newAction() 176 | { 177 | if (!is_dir($this->moduleDir)) { 178 | if (config('display_errors') == false) { 179 | notFound(); 180 | } else { 181 | throw new Exception('不存在的模块,' . $this->moduleDir); 182 | } 183 | } elseif (!file_exists($this->controllerFile)) { 184 | if (config('display_errors') == false) { 185 | notFound(); 186 | } else { 187 | throw new Exception('不存在的控制器,' . $this->controllerFile); 188 | } 189 | } 190 | if (class_exists($this->controllerClassName)) { 191 | $this->controllerObj = new $this->controllerClassName(); 192 | } elseif (config('display_errors') == false) { 193 | notFound(); 194 | } else { 195 | throw new Exception($this->controllerClassName . '控制器类不存在'); 196 | } 197 | 198 | if (method_exists($this->controllerClassName, ACTION)) { 199 | //开始实例方法 200 | $this->controllerObj->{ACTION}(); //可变方法 201 | } elseif (config('display_errors') == false) { 202 | notFound(); 203 | } else { 204 | throw new Exception(ACTION . '操作方法不存在'); 205 | } 206 | 207 | } 208 | } 209 | --------------------------------------------------------------------------------