├── README.md ├── config └── config.php ├── controller └── homeController.php ├── error ├── 2011-12-28_SQL.txt ├── 2011-12-30_SQL.txt └── download.error ├── index.php ├── lib └── my_test.php ├── model └── homeModel.php ├── system ├── app.php ├── core │ ├── controller.php │ └── model.php └── lib │ ├── lib_cache.php │ ├── lib_crypt.php │ ├── lib_download.php │ ├── lib_mysql.php │ ├── lib_route.php │ ├── lib_template.php │ └── lib_thumbnail.php ├── view └── home.php └── 自己动手写PHP MVC框架教程.txt /README.md: -------------------------------------------------------------------------------- 1 | tiny-php-framework 2 | ================== 3 | 4 | This is a tiny php framework for learning MVC 5 | 6 | by yuansir-web.com 7 | 8 | 这是一个自己动手写PHP MVC框架的教程源码 9 | 具体教程请查看 http://www.yuansir-web.com/?p=438 10 | -------------------------------------------------------------------------------- /config/config.php: -------------------------------------------------------------------------------- 1 | 6 | * @version 1.0 7 | */ 8 | 9 | /*数据库配置*/ 10 | $CONFIG['system']['db'] = array( 11 | 'db_host' => 'localhost', 12 | 'db_user' => 'root', 13 | 'db_password' => '', 14 | 'db_database' => 'app', 15 | 'db_table_prefix' => 'app_', 16 | 'db_charset' => 'urf8', 17 | 'db_conn' => '', //数据库连接标识; pconn 为长久链接,默认为即时链接 18 | 19 | ); 20 | 21 | /*自定义类库配置*/ 22 | $CONFIG['system']['lib'] = array( 23 | 'prefix' => 'my' //自定义类库的文件前缀 24 | ); 25 | 26 | $CONFIG['system']['route'] = array( 27 | 'default_controller' => 'home', //系统默认控制器 28 | 'default_action' => 'index', //系统默认控制器 29 | 'url_type' => 1 /*定义URL的形式 1 为普通模式 index.php?c=controller&a=action&id=2 30 | * 2 为PATHINFO index.php/controller/action/id/2(暂时不实现) 31 | */ 32 | ); 33 | 34 | /*缓存配置*/ 35 | $CONFIG['system']['cache'] = array( 36 | 'cache_dir' => 'cache', //缓存路径,相对于根目录 37 | 'cache_prefix' => 'cache_',//缓存文件名前缀 38 | 'cache_time' => 1800, //缓存时间默认1800秒 39 | 'cache_mode' => 2, //mode 1 为serialize ,model 2为保存为可执行文件 40 | ); 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /controller/homeController.php: -------------------------------------------------------------------------------- 1 | 6 | * @version 1.0 7 | */ 8 | class homeController extends Controller { 9 | 10 | public function __construct() { 11 | parent::__construct(); 12 | } 13 | 14 | public function index() { 15 | $object = $this->load('download',FALSE); 16 | var_dump($object); 17 | exit(); 18 | // 19 | // $object->set_byfile('http://localhost/framework/error/2011-12-28_SQL.txt');//服务器文件名,包括路径 20 | // $object->filename = "2011-12-28_SQL.txt";//下载另存为的文件名 21 | // $object->download(); 22 | } 23 | } 24 | 25 | -------------------------------------------------------------------------------- /error/2011-12-28_SQL.txt: -------------------------------------------------------------------------------- 1 | 数据库不可用: 2 | 3 | 客户IP:127.0.0.1 4 | 时间 :2011-12-28 07:43:18 5 | 6 | -------------------------------------------------------------------------------- /error/2011-12-30_SQL.txt: -------------------------------------------------------------------------------- 1 | 错误SQL语句: 2 | show tables 3 | 客户IP:127.0.0.1 4 | 时间 :2011-12-30 02:54:18 5 | 6 | SQL语句错误 7 | show tables 8 | 客户IP:127.0.0.1 9 | 时间 :2011-12-30 02:54:18 10 | 11 | 错误SQL语句: 12 | show tables 13 | 客户IP:127.0.0.1 14 | 时间 :2011-12-30 02:54:42 15 | 16 | SQL语句错误 17 | show tables 18 | 客户IP:127.0.0.1 19 | 时间 :2011-12-30 02:54:42 20 | 21 | -------------------------------------------------------------------------------- /error/download.error: -------------------------------------------------------------------------------- 1 | begin download 2 | end download 3 | begin download 4 | end download 5 | begin download 6 | end download 7 | begin download 8 | end download 9 | begin download 10 | end download 11 | begin download 12 | end download 13 | begin download 14 | end download 15 | begin download 16 | end download 17 | begin download 18 | end download 19 | begin download 20 | end download 21 | begin download 22 | end download 23 | begin download 24 | end download 25 | begin download 26 | end download 27 | begin download 28 | end download 29 | begin download 30 | end download 31 | begin download 32 | end download 33 | begin download 34 | begin download 35 | begin download 36 | begin download 37 | begin download 38 | begin download 39 | begin download 40 | begin download 41 | begin download 42 | begin download 43 | end download 44 | begin download 45 | end download 46 | begin download 47 | end download 48 | begin download 49 | end download 50 | begin download 51 | end download 52 | begin download 53 | end download 54 | begin download 55 | end download 56 | begin download 57 | end download 58 | begin download 59 | end download 60 | begin download 61 | end download 62 | begin download 63 | end download 64 | begin download 65 | end download 66 | begin download 67 | end download 68 | begin download 69 | end download 70 | begin download 71 | end download 72 | begin download 73 | end download 74 | begin download 75 | end download 76 | begin download 77 | end download 78 | begin download 79 | end download 80 | begin download 81 | end download 82 | begin download 83 | end download 84 | begin download 85 | end download 86 | begin download 87 | end download 88 | begin download 89 | end download 90 | begin download 91 | end download 92 | begin download 93 | end download 94 | begin download 95 | begin download 96 | begin download 97 | begin download 98 | begin download 99 | begin download 100 | end download 101 | begin download 102 | end download 103 | begin download 104 | end download 105 | begin download 106 | end download 107 | begin download 108 | end download 109 | begin download 110 | end download 111 | begin download 112 | end download 113 | begin download 114 | end download 115 | begin download 116 | end download 117 | begin download 118 | end download 119 | begin download 120 | end download 121 | begin download 122 | end download 123 | begin download 124 | end download 125 | begin download 126 | end download 127 | -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | 6 | * @version 1.0 7 | */ 8 | require dirname(__FILE__).'/system/app.php'; 9 | require dirname(__FILE__).'/config/config.php'; 10 | Application::run($CONFIG); 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /lib/my_test.php: -------------------------------------------------------------------------------- 1 | 6 | * @version 1.0 7 | */ 8 | class homeModel extends Model{ 9 | function test(){ 10 | echo "this is test homeModel"; 11 | } 12 | 13 | function testResult(){ 14 | $this->db->show_databases(); 15 | } 16 | } 17 | 18 | 19 | -------------------------------------------------------------------------------- /system/app.php: -------------------------------------------------------------------------------- 1 | 6 | * @version 1.0 7 | */ 8 | define('SYSTEM_PATH', dirname(__FILE__)); 9 | define('ROOT_PATH', substr(SYSTEM_PATH, 0,-7)); 10 | define('SYS_LIB_PATH', SYSTEM_PATH.'/lib'); 11 | define('APP_LIB_PATH', ROOT_PATH.'/lib'); 12 | define('SYS_CORE_PATH', SYSTEM_PATH.'/core'); 13 | define('CONTROLLER_PATH', ROOT_PATH.'/controller'); 14 | define('MODEL_PATH', ROOT_PATH.'/model'); 15 | define('VIEW_PATH', ROOT_PATH.'/view'); 16 | define('LOG_PATH', ROOT_PATH.'/error/'); 17 | final class Application { 18 | public static $_lib = null; 19 | public static $_config = null; 20 | public static function init() { 21 | self::setAutoLibs(); 22 | require SYS_CORE_PATH.'/model.php'; 23 | require SYS_CORE_PATH.'/controller.php'; 24 | 25 | } 26 | /** 27 | * 创建应用 28 | * @access public 29 | * @param array $config 30 | */ 31 | public static function run($config){ 32 | self::$_config = $config['system']; 33 | self::init(); 34 | self::autoload(); 35 | self::$_lib['route']->setUrlType(self::$_config['route']['url_type']); //设置url的类型 36 | $url_array = self::$_lib['route']->getUrlArray(); //将url转发成数组 37 | self::routeToCm($url_array); 38 | } 39 | /** 40 | * 自动加载类库 41 | * @access public 42 | * @param array $_lib 43 | */ 44 | public static function autoload(){ 45 | foreach (self::$_lib as $key => $value){ 46 | require (self::$_lib[$key]); 47 | $lib = ucfirst($key); 48 | self::$_lib[$key] = new $lib; 49 | } 50 | //初始化cache 51 | if(is_object(self::$_lib['cache'])){ 52 | self::$_lib['cache']->init( 53 | ROOT_PATH.'/'.self::$_config['cache']['cache_dir'], 54 | self::$_config['cache']['cache_prefix'], 55 | self::$_config['cache']['cache_time'], 56 | self::$_config['cache']['cache_mode'] 57 | ); 58 | } 59 | } 60 | /** 61 | * 加载类库 62 | * @access public 63 | * @param string $class_name 类库名称 64 | * @return object 65 | */ 66 | public static function newLib($class_name){ 67 | $app_lib = $sys_lib = ''; 68 | $app_lib = APP_LIB_PATH.'/'.self::$_config['lib']['prefix'].'_'.$class_name.'.php'; 69 | $sys_lib = SYS_LIB_PATH.'/lib_'.$class_name.'.php'; 70 | 71 | if(file_exists($app_lib)){ 72 | require ($app_lib); 73 | $class_name = ucfirst(self::$_config['lib']['prefix']).ucfirst($class_name); 74 | return new $class_name; 75 | }else if(file_exists($sys_lib)){ 76 | require ($sys_lib); 77 | return self::$_lib['$class_name'] = new $class_name; 78 | }else{ 79 | trigger_error('加载 '.$class_name.' 类库不存在'); 80 | } 81 | } 82 | /** 83 | * 自动加载的类库 84 | * @access public 85 | */ 86 | public static function setAutoLibs(){ 87 | self::$_lib = array( 88 | 'route' => SYS_LIB_PATH.'/lib_route.php', 89 | 'mysql' => SYS_LIB_PATH.'/lib_mysql.php', 90 | 'template' => SYS_LIB_PATH.'/lib_template.php', 91 | 'cache' => SYS_LIB_PATH.'/lib_cache.php', 92 | 'thumbnail' => SYS_LIB_PATH.'/lib_thumbnail.php' 93 | ); 94 | } 95 | /** 96 | * 根据URL分发到Controller和Model 97 | * @access public 98 | * @param array $url_array 99 | */ 100 | public static function routeToCm($url_array = array()){ 101 | $app = ''; 102 | $controller = ''; 103 | $action = ''; 104 | $model = ''; 105 | $params = ''; 106 | 107 | if(isset($url_array['app'])){ 108 | $app = $url_array['app']; 109 | } 110 | 111 | if(isset($url_array['controller'])){ 112 | $controller = $model = $url_array['controller']; 113 | if($app){ 114 | $controller_file = CONTROLLER_PATH.'/'.$app.'/'.$controller.'Controller.php'; 115 | $model_file = MODEL_PATH.'/'.$app.'/'.$model.'Model.php'; 116 | }else{ 117 | $controller_file = CONTROLLER_PATH.'/'.$controller.'Controller.php'; 118 | $model_file = MODEL_PATH.'/'.$model.'Model.php'; 119 | } 120 | }else{ 121 | $controller = $model = self::$_config['route']['default_controller']; 122 | if($app){ 123 | $controller_file = CONTROLLER_PATH.'/'.$app.'/'.self::$_config['route']['default_controller'].'Controller.php'; 124 | $model_file = MODEL_PATH.'/'.$app.'/'.self::$_config['route']['default_controller'].'Model.php'; 125 | }else{ 126 | $controller_file = CONTROLLER_PATH.'/'.self::$_config['route']['default_controller'].'Controller.php'; 127 | $model_file = MODEL_PATH.'/'.self::$_config['route']['default_controller'].'Model.php'; 128 | } 129 | } 130 | if(isset($url_array['action'])){ 131 | $action = $url_array['action']; 132 | }else{ 133 | $action = self::$_config['route']['default_action']; 134 | } 135 | 136 | if(isset($url_array['params'])){ 137 | $params = $url_array['params']; 138 | } 139 | if(file_exists($controller_file)){ 140 | if (file_exists($model_file)) { 141 | require $model_file; 142 | } 143 | require $controller_file; 144 | $controller = $controller.'Controller'; 145 | $controller = new $controller; 146 | if($action){ 147 | if(method_exists($controller, $action)){ 148 | isset($params) ? $controller ->$action($params) : $controller ->$action(); 149 | }else{ 150 | die('控制器方法不存在'); 151 | } 152 | }else{ 153 | die('控制器方法不存在'); 154 | } 155 | }else{ 156 | die('控制器不存在'); 157 | } 158 | } 159 | 160 | 161 | 162 | } 163 | 164 | 165 | -------------------------------------------------------------------------------- /system/core/controller.php: -------------------------------------------------------------------------------- 1 | 6 | * @version 1.0 7 | */ 8 | class Controller{ 9 | 10 | public function __construct() { 11 | // header('Content-type:text/html;chartset=utf-8'); 12 | } 13 | /** 14 | * 实例化模型 15 | * @access final protected 16 | * @param string $model 模型名称 17 | */ 18 | final protected function model($model) { 19 | if (empty($model)) { 20 | trigger_error('不能实例化空模型'); 21 | } 22 | $model_name = $model . 'Model'; 23 | return new $model_name; 24 | } 25 | /** 26 | * 加载类库 27 | * @param string $lib 类库名称 28 | * @param Bool $my 如果FALSE默认加载系统自动加载的类库,如果为TRUE则加载非自动加载类库 29 | * @return type 30 | */ 31 | final protected function load($lib,$auto = TRUE){ 32 | if(empty($lib)){ 33 | trigger_error('加载类库名不能为空'); 34 | }elseif($auto === TRUE){ 35 | return Application::$_lib[$lib]; 36 | }elseif($auto === FALSE){ 37 | return Application::newLib($lib); 38 | } 39 | } 40 | /** 41 | * 加载系统配置,默认为系统配置 $CONFIG['system'][$config] 42 | * @access final protected 43 | * @param string $config 配置名 44 | */ 45 | final protected function config($config){ 46 | return Application::$_config[$config]; 47 | } 48 | /** 49 | * 加载模板文件 50 | * @access final protect 51 | * @param string $path 模板路径 52 | * @return string 模板字符串 53 | */ 54 | final protected function showTemplate($path,$data = array()){ 55 | $template = $this->load('template'); 56 | $template->init($path,$data); 57 | $template->outPut(); 58 | } 59 | } 60 | 61 | 62 | -------------------------------------------------------------------------------- /system/core/model.php: -------------------------------------------------------------------------------- 1 | 6 | * @version 1.0 7 | */ 8 | class Model { 9 | protected $db = null; 10 | 11 | final public function __construct() { 12 | header('Content-type:text/html;chartset=utf-8'); 13 | $this->db = $this->load('mysql'); 14 | $config_db = $this->config('db'); 15 | $this->db->init( 16 | $config_db['db_host'], 17 | $config_db['db_user'], 18 | $config_db['db_password'], 19 | $config_db['db_database'], 20 | $config_db['db_conn'], 21 | $config_db['db_charset'] 22 | ); //初始话数据库类 23 | } 24 | /** 25 | * 根据表前缀获取表名 26 | * @access final protected 27 | * @param string $table_name 表名 28 | */ 29 | final protected function table($table_name){ 30 | $config_db = $this->config('db'); 31 | return $config_db['db_table_prefix'].$table_name; 32 | } 33 | /** 34 | * 加载类库 35 | * @param string $lib 类库名称 36 | * @param Bool $my 如果FALSE默认加载系统自动加载的类库,如果为TRUE则加载自定义类库 37 | * @return type 38 | */ 39 | final protected function load($lib,$my = FALSE){ 40 | if(empty($lib)){ 41 | trigger_error('加载类库名不能为空'); 42 | }elseif($my === FALSE){ 43 | return Application::$_lib[$lib]; 44 | }elseif($my === TRUE){ 45 | return Application::newLib($lib); 46 | } 47 | } 48 | /** 49 | * 加载系统配置,默认为系统配置 $CONFIG['system'][$config] 50 | * @access final protected 51 | * @param string $config 配置名 52 | */ 53 | final protected function config($config=''){ 54 | return Application::$_config[$config]; 55 | } 56 | 57 | 58 | 59 | 60 | } 61 | 62 | 63 | -------------------------------------------------------------------------------- /system/lib/lib_cache.php: -------------------------------------------------------------------------------- 1 | 6 | * @version 1.0 7 | */ 8 | final class Cache{ 9 | private $cache_dir = null; 10 | private $cache_prefix = null; 11 | private $cache_time = null; 12 | private $cache_mode = null; 13 | /** 14 | * 初始化参数 15 | * @param string $cache_dir 缓存存放的目录 16 | * @param int $cache_time 缓存时间 17 | * @param int $cache_mod 缓存模式 18 | */ 19 | public function init($cache_dir = 'cache',$cache_prefix = 'cache_',$cache_time = 1800,$cache_mod = 1) { 20 | $this->cache_dir = $cache_dir; 21 | $this->cache_prefix = $cache_prefix; 22 | $this->cache_time = $cache_time; 23 | $this->cache_mode = $cache_mod; 24 | } 25 | /** 26 | * 设置缓存 27 | * @param string 缓存名 28 | * @param array 缓存内容 29 | */ 30 | public function set($id,$data){ 31 | if(!isset($id)){ 32 | return false; 33 | } 34 | $cache = array( 35 | 'file' => $this->getFileName($id, $this->cache_dir), 36 | 'data' => $data 37 | ); 38 | return $this->writeCache($cache); 39 | } 40 | /** 41 | * 获取缓存 42 | * @param string $id 缓存名称 43 | * @return bool/array 44 | */ 45 | public function get($id){ 46 | if(!$this->hasCache($id)){ 47 | return false; 48 | } 49 | $data = $this->getCacheData($id); 50 | return $data; 51 | } 52 | /** 53 | * 获取缓存目录 54 | * @return string 55 | */ 56 | public function getCacheDir(){ 57 | return $cache_dir = trim($this->cache_dir,'/'); 58 | } 59 | /** 60 | * 获取完整缓存文件名称 61 | * @param string $id 缓存名 62 | * @return string 63 | */ 64 | public function getFileName($id){ 65 | return $this->getCacheDir().'/'.$this->cache_prefix.$id.'.php'; 66 | } 67 | /** 68 | * 根据缓存文件返回缓存名称 69 | * @param type $file 70 | */ 71 | public function getCacheName($file){ 72 | if(!file_exists($file)){ 73 | return FALSE; 74 | } 75 | $filename = basename($file); 76 | preg_match('/^'.$this->cache_prefix.'(.*).php$/i', $filename,$matches); 77 | return $matches[1]; 78 | } 79 | /** 80 | * 写入缓存 81 | * @param array $cache 缓存数据 82 | */ 83 | public function writeCache($cache = array()){ 84 | if(!is_dir($this->getCacheDir())){ 85 | mkdir($this->getCacheDir(),0777); 86 | }elseif(!is_writable($this->getCacheDir())){ 87 | chmod($this->getCacheDir(), 0777); 88 | } 89 | 90 | if($this->cache_mode == 1){ 91 | $content = serialize($cache['data']); 92 | }else{ 93 | $content = "getFileName($id))){ 121 | if(time() > filemtime($this->getFileName($id))+$this->cache_time){ 122 | unlink($this->getFileName($id)); 123 | } 124 | } 125 | return file_exists($this->getFileName($id)) ? TRUE : FALSE; 126 | } 127 | /** 128 | * 删除一条缓存 129 | * @param string $id 缓存名 130 | * @return bool 131 | */ 132 | public function deleteCache($id){ 133 | if($this->hasCache($id)){ 134 | return unlink($this->getFileName($id)); 135 | }else{ 136 | trigger_error('缓存不存在'); 137 | } 138 | } 139 | /** 140 | * 获取缓存数据 141 | * @param string $id 缓存名 142 | * @return array 143 | */ 144 | public function getCacheData($id){ 145 | if(!$this->hasCache($id)){ 146 | return false; 147 | } 148 | if($this->cache_mode == 1){ 149 | $fp = @fopen($this->getFileName($id), r); 150 | $data = @fread($fp, filesize($this->getFileName($id))); 151 | @fclose($fp); 152 | return unserialize($data); 153 | }else{ 154 | return include $this->getFileName($id); 155 | } 156 | } 157 | /** 158 | * 清空缓存 159 | * @return bool 160 | */ 161 | public function flushCache(){ 162 | $glob = @glob($this->getCacheDir().'/'.$this->cache_prefix.'*'); 163 | if($glob){ 164 | foreach($glob as $item){ 165 | $id = $this->getCacheName($item); 166 | $this->deleteCache($id); 167 | } 168 | } 169 | return TRUE; 170 | } 171 | 172 | } 173 | 174 | 175 | -------------------------------------------------------------------------------- /system/lib/lib_crypt.php: -------------------------------------------------------------------------------- 1 | 7 | * @version 1.0 8 | */ 9 | class Crypt { 10 | 11 | public function encrypt($string, $key) { 12 | $str_len = strlen($string); 13 | $key_len = strlen($key); 14 | for ($i = 0; $i < $str_len; $i++) { 15 | for ($j = 0; $j < $key_len; $j++) { 16 | $string[$i] = $string[$i] ^ $key[$j]; 17 | } 18 | } 19 | return $string; 20 | } 21 | 22 | public function decrypt($string, $key) { 23 | $str_len = strlen($string); 24 | $key_len = strlen($key); 25 | for ($i = 0; $i < $str_len; $i++) { 26 | for ($j = 0; $j < $key_len; $j++) { 27 | $string[$i] = $key[$j] ^ $string[$i]; 28 | } 29 | } 30 | return $string; 31 | } 32 | 33 | } -------------------------------------------------------------------------------- /system/lib/lib_download.php: -------------------------------------------------------------------------------- 1 | 7 | * @version 1.0 8 | */ 9 | class download { 10 | 11 | var $debug = true; 12 | var $errormsg = ''; 13 | var $Filter = array(); 14 | var $filename = ''; 15 | var $mineType = 'text/plain'; 16 | var $xlq_filetype = array(); 17 | 18 | /** 19 | * 初始化 20 | * @param string $file_filter 禁止下载的文件,文件后缀 21 | * @param type $isdebug 22 | */ 23 | function init($file_filter='', $isdebug=true) { 24 | $this->setFilter($fileFilter); 25 | $this->setDebug($isdebug); 26 | $this->setFileType(); 27 | } 28 | 29 | function setFilter($fileFilter) { 30 | if (empty($fileFilter)) 31 | return; 32 | $this->Filter = explode(',', strtolower($fileFilter)); 33 | } 34 | 35 | function setDebug($debug) { 36 | $this->debug = $debug; 37 | } 38 | 39 | function setFileName($filename) { 40 | $this->filename = $filename; 41 | } 42 | 43 | function downloadFile($filename) { 44 | $this->setFileName($filename); 45 | if ($this->filecheck()) { 46 | $fn = array_pop(explode('/', strtr($this->filename, '', '/'))); 47 | header("Pragma: public"); 48 | header("Expires: 0"); // set expiration time 49 | header("Cache-Component: must-revalidate, post-check=0, pre-check=0"); 50 | header("Content-type:" . $this->mineType); 51 | header("Content-Length: " . filesize($this->filename)); 52 | header("Content-Disposition: attachment; filename=\"$fn\""); 53 | header('Content-Transfer-Encoding: binary'); 54 | readfile($this->filename); 55 | return true; 56 | } else { 57 | return false; 58 | } 59 | } 60 | 61 | function getErrorMsg() { 62 | return $this->errormsg; 63 | } 64 | 65 | function fileCheck() { 66 | $filename = $this->filename; 67 | if (file_exists($filename)) { 68 | $filetype = strtolower(array_pop(explode('.', $filename))); 69 | if (in_array($filetype, $this->Filter)) { 70 | $this->errormsg.=$filename . '不允许下载!'; 71 | if ($this->debug) 72 | exit($filename . '不允许下载!'); 73 | return false; 74 | }else { 75 | if (function_exists("mime_content_type")) { 76 | $this->mineType = mime_content_type($filename); 77 | } 78 | if (empty($this->mineType)) { 79 | if (isset($this->xlq_filetype[$filetype])) 80 | $this->mineType = $this->xlq_filetype[$filetype]; 81 | } 82 | if (!empty($this->mineType)) 83 | return true; 84 | else { 85 | $this->errormsg.='获取文件类型时候发生错误,或者不存在预定文件类型内'; 86 | if ($this->debug) 87 | exit('获取文件类型出错'); 88 | return false; 89 | } 90 | } 91 | }else { 92 | $this->errormsg.='SORRY,你要下载的文件不存在!!'; 93 | if ($this->debug) 94 | exit($filename . '不存在!'); 95 | return false; 96 | } 97 | } 98 | 99 | function setFileType() { 100 | $this->xlq_filetype['chm'] = 'application/octet-stream'; 101 | $this->xlq_filetype['ppt'] = 'application/vnd.ms-powerpoint'; 102 | $this->xlq_filetype['xls'] = 'application/vnd.ms-excel'; 103 | $this->xlq_filetype['doc'] = 'application/msword'; 104 | $this->xlq_filetype['exe'] = 'application/octet-stream'; 105 | $this->xlq_filetype['rar'] = 'application/octet-stream'; 106 | $this->xlq_filetype['js'] = "javascrīpt/js"; 107 | $this->xlq_filetype['css'] = "text/css"; 108 | $this->xlq_filetype['hqx'] = "application/mac-binhex40"; 109 | $this->xlq_filetype['bin'] = "application/octet-stream"; 110 | $this->xlq_filetype['oda'] = "application/oda"; 111 | $this->xlq_filetype['pdf'] = "application/pdf"; 112 | $this->xlq_filetype['ai'] = "application/postsrcipt"; 113 | $this->xlq_filetype['eps'] = "application/postsrcipt"; 114 | $this->xlq_filetype['es'] = "application/postsrcipt"; 115 | $this->xlq_filetype['rtf'] = "application/rtf"; 116 | $this->xlq_filetype['mif'] = "application/x-mif"; 117 | $this->xlq_filetype['csh'] = "application/x-csh"; 118 | $this->xlq_filetype['dvi'] = "application/x-dvi"; 119 | $this->xlq_filetype['hdf'] = "application/x-hdf"; 120 | $this->xlq_filetype['nc'] = "application/x-netcdf"; 121 | $this->xlq_filetype['cdf'] = "application/x-netcdf"; 122 | $this->xlq_filetype['latex'] = "application/x-latex"; 123 | $this->xlq_filetype['ts'] = "application/x-troll-ts"; 124 | $this->xlq_filetype['src'] = "application/x-wais-source"; 125 | $this->xlq_filetype['zip'] = "application/zip"; 126 | $this->xlq_filetype['bcpio'] = "application/x-bcpio"; 127 | $this->xlq_filetype['cpio'] = "application/x-cpio"; 128 | $this->xlq_filetype['gtar'] = "application/x-gtar"; 129 | $this->xlq_filetype['shar'] = "application/x-shar"; 130 | $this->xlq_filetype['sv4cpio'] = "application/x-sv4cpio"; 131 | $this->xlq_filetype['sv4crc'] = "application/x-sv4crc"; 132 | $this->xlq_filetype['tar'] = "application/x-tar"; 133 | $this->xlq_filetype['ustar'] = "application/x-ustar"; 134 | $this->xlq_filetype['man'] = "application/x-troff-man"; 135 | $this->xlq_filetype['sh'] = "application/x-sh"; 136 | $this->xlq_filetype['tcl'] = "application/x-tcl"; 137 | $this->xlq_filetype['tex'] = "application/x-tex"; 138 | $this->xlq_filetype['texi'] = "application/x-texinfo"; 139 | $this->xlq_filetype['texinfo'] = "application/x-texinfo"; 140 | $this->xlq_filetype['t'] = "application/x-troff"; 141 | $this->xlq_filetype['tr'] = "application/x-troff"; 142 | $this->xlq_filetype['roff'] = "application/x-troff"; 143 | $this->xlq_filetype['shar'] = "application/x-shar"; 144 | $this->xlq_filetype['me'] = "application/x-troll-me"; 145 | $this->xlq_filetype['ts'] = "application/x-troll-ts"; 146 | $this->xlq_filetype['gif'] = "image/gif"; 147 | $this->xlq_filetype['jpeg'] = "image/pjpeg"; 148 | $this->xlq_filetype['jpg'] = "image/pjpeg"; 149 | $this->xlq_filetype['jpe'] = "image/pjpeg"; 150 | $this->xlq_filetype['ras'] = "image/x-cmu-raster"; 151 | $this->xlq_filetype['pbm'] = "image/x-portable-bitmap"; 152 | $this->xlq_filetype['ppm'] = "image/x-portable-pixmap"; 153 | $this->xlq_filetype['xbm'] = "image/x-xbitmap"; 154 | $this->xlq_filetype['xwd'] = "image/x-xwindowdump"; 155 | $this->xlq_filetype['ief'] = "image/ief"; 156 | $this->xlq_filetype['tif'] = "image/tiff"; 157 | $this->xlq_filetype['tiff'] = "image/tiff"; 158 | $this->xlq_filetype['pnm'] = "image/x-portable-anymap"; 159 | $this->xlq_filetype['pgm'] = "image/x-portable-graymap"; 160 | $this->xlq_filetype['rgb'] = "image/x-rgb"; 161 | $this->xlq_filetype['xpm'] = "image/x-xpixmap"; 162 | $this->xlq_filetype['txt'] = "text/plain"; 163 | $this->xlq_filetype['c'] = "text/plain"; 164 | $this->xlq_filetype['cc'] = "text/plain"; 165 | $this->xlq_filetype['h'] = "text/plain"; 166 | $this->xlq_filetype['html'] = "text/html"; 167 | $this->xlq_filetype['htm'] = "text/html"; 168 | $this->xlq_filetype['htl'] = "text/html"; 169 | $this->xlq_filetype['rtx'] = "text/richtext"; 170 | $this->xlq_filetype['etx'] = "text/x-setext"; 171 | $this->xlq_filetype['tsv'] = "text/tab-separated-values"; 172 | $this->xlq_filetype['mpeg'] = "video/mpeg"; 173 | $this->xlq_filetype['mpg'] = "video/mpeg"; 174 | $this->xlq_filetype['mpe'] = "video/mpeg"; 175 | $this->xlq_filetype['avi'] = "video/x-msvideo"; 176 | $this->xlq_filetype['qt'] = "video/quicktime"; 177 | $this->xlq_filetype['mov'] = "video/quicktime"; 178 | $this->xlq_filetype['moov'] = "video/quicktime"; 179 | $this->xlq_filetype['movie'] = "video/x-sgi-movie"; 180 | $this->xlq_filetype['au'] = "audio/basic"; 181 | $this->xlq_filetype['snd'] = "audio/basic"; 182 | $this->xlq_filetype['wav'] = "audio/x-wav"; 183 | $this->xlq_filetype['aif'] = "audio/x-aiff"; 184 | $this->xlq_filetype['aiff'] = "audio/x-aiff"; 185 | $this->xlq_filetype['aifc'] = "audio/x-aiff"; 186 | $this->xlq_filetype['swf'] = "application/x-shockwave-flash"; 187 | } 188 | 189 | } 190 | 191 | //$download = new download(); 192 | //$download->downloadFile('./logo.png'); 193 | -------------------------------------------------------------------------------- /system/lib/lib_mysql.php: -------------------------------------------------------------------------------- 1 | 6 | * @version 1.0 7 | */ 8 | final class Mysql { 9 | private $db_host; //数据库主机 10 | private $db_user; //数据库用户名 11 | private $db_pwd; //数据库用户名密码 12 | private $db_database; //数据库名 13 | private $conn; //数据库连接标识; 14 | private $result; //执行query命令的结果资源标识 15 | private $sql; //sql执行语句 16 | private $row; //返回的条目数 17 | private $coding; //数据库编码,GBK,UTF8,gb2312 18 | private $bulletin = true; //是否开启错误记录 19 | private $show_error = true; //测试阶段,显示所有错误,具有安全隐患,默认关闭 20 | private $is_error = false; //发现错误是否立即终止,默认true,建议不启用,因为当有问题时用户什么也看不到是很苦恼的 21 | 22 | /*构造函数*/ 23 | // public function __construct($db_host, $db_user, $db_pwd, $db_database, $conn, $coding) { 24 | // $this->db_host = $db_host; 25 | // $this->db_user = $db_user; 26 | // $this->db_pwd = $db_pwd; 27 | // $this->db_database = $db_database; 28 | // $this->conn = $conn; 29 | // $this->coding = $coding; 30 | // $this->connect(); 31 | // } 32 | /*初始化函数*/ 33 | public function init($db_host, $db_user, $db_pwd, $db_database, $conn, $coding) { 34 | $this->db_host = $db_host; 35 | $this->db_user = $db_user; 36 | $this->db_pwd = $db_pwd; 37 | $this->db_database = $db_database; 38 | $this->conn = $conn; 39 | $this->coding = $coding; 40 | $this->connect(); 41 | } 42 | /*数据库连接*/ 43 | public function connect() { 44 | if ($this->conn == "pconn") { 45 | //永久链接 46 | $this->conn = mysql_pconnect($this->db_host, $this->db_user, $this->db_pwd); 47 | } else { 48 | //即时链接 49 | $this->conn = mysql_connect($this->db_host, $this->db_user, $this->db_pwd); 50 | } 51 | 52 | if (!mysql_select_db($this->db_database, $this->conn)) { 53 | if ($this->show_error) { 54 | $this->show_error("数据库不可用:", $this->db_database); 55 | } 56 | } 57 | mysql_query("SET NAMES $this->coding"); 58 | } 59 | 60 | /*数据库执行语句,可执行查询添加修改删除等任何sql语句*/ 61 | public function query($sql) { 62 | if ($sql == "") { 63 | $this->show_error("SQL语句错误:", "SQL查询语句为空"); 64 | } 65 | $this->sql = $sql; 66 | 67 | $result = mysql_query($this->sql, $this->conn); 68 | 69 | if (!$result) { 70 | //调试中使用,sql语句出错时会自动打印出来 71 | if ($this->show_error) { 72 | $this->show_error("错误SQL语句:", $this->sql); 73 | } 74 | } else { 75 | $this->result = $result; 76 | } 77 | return $this->result; 78 | } 79 | 80 | /*创建添加新的数据库*/ 81 | public function create_database($database_name) { 82 | $database = $database_name; 83 | $sqlDatabase = 'create database ' . $database; 84 | $this->query($sqlDatabase); 85 | } 86 | 87 | /*查询服务器所有数据库*/ 88 | //将系统数据库与用户数据库分开,更直观的显示? 89 | public function show_databases() { 90 | $this->query("show databases"); 91 | echo "现有数据库:" . $amount = $this->db_num_rows(); 92 | echo "
"; 93 | $i = 1; 94 | while ($row = $this->fetch_array()) { 95 | echo "$i $row[Database]"; 96 | echo "
"; 97 | $i++; 98 | } 99 | } 100 | 101 | //以数组形式返回主机中所有数据库名 102 | public function databases() { 103 | $rsPtr = mysql_list_dbs($this->conn); 104 | $i = 0; 105 | $cnt = mysql_num_rows($rsPtr); 106 | while ($i < $cnt) { 107 | $rs[] = mysql_db_name($rsPtr, $i); 108 | $i++; 109 | } 110 | return $rs; 111 | } 112 | 113 | /*查询数据库下所有的表*/ 114 | public function show_tables($database_name) { 115 | $this->query("show tables"); 116 | echo "现有数据库:" . $amount = $this->db_num_rows(); 117 | echo "
"; 118 | $i = 1; 119 | while ($row = $this->fetch_array()) { 120 | $columnName = "Tables_in_" . $database_name; 121 | echo "$i $row[$columnName]"; 122 | echo "
"; 123 | $i++; 124 | } 125 | } 126 | 127 | /* 128 | mysql_fetch_row() array $row[0],$row[1],$row[2] 129 | mysql_fetch_array() array $row[0] 或 $row[id] 130 | mysql_fetch_assoc() array 用$row->content 字段大小写敏感 131 | mysql_fetch_object() object 用$row[id],$row[content] 字段大小写敏感 132 | */ 133 | 134 | /*取得结果数据*/ 135 | public function mysql_result_li() { 136 | return mysql_result($str); 137 | } 138 | 139 | /*取得记录集,获取数组-索引和关联,使用$row['content'] */ 140 | public function fetch_array() { 141 | return mysql_fetch_array($this->result); 142 | } 143 | 144 | //获取关联数组,使用$row['字段名'] 145 | public function fetch_assoc() { 146 | return mysql_fetch_assoc($this->result); 147 | } 148 | 149 | //获取数字索引数组,使用$row[0],$row[1],$row[2] 150 | public function fetch_row() { 151 | return mysql_fetch_row($this->result); 152 | } 153 | 154 | //获取对象数组,使用$row->content 155 | public function fetch_Object() { 156 | return mysql_fetch_object($this->result); 157 | } 158 | 159 | //简化查询select 160 | public function findall($table) { 161 | $this->query("SELECT * FROM $table"); 162 | } 163 | 164 | //简化查询select 165 | public function select($table, $columnName = "*", $condition = '', $debug = '') { 166 | $condition = $condition ? ' Where ' . $condition : NULL; 167 | if ($debug) { 168 | echo "SELECT $columnName FROM $table $condition"; 169 | } else { 170 | $this->query("SELECT $columnName FROM $table $condition"); 171 | } 172 | } 173 | 174 | //简化删除del 175 | public function delete($table, $condition, $url = '') { 176 | if ($this->query("DELETE FROM $table WHERE $condition")) { 177 | if (!empty ($url)) 178 | $this->Get_admin_msg($url, '删除成功!'); 179 | } 180 | } 181 | 182 | //简化插入insert 183 | public function insert($table, $columnName, $value, $url = '') { 184 | if ($this->query("INSERT INTO $table ($columnName) VALUES ($value)")) { 185 | if (!empty ($url)) 186 | $this->Get_admin_msg($url, '添加成功!'); 187 | } 188 | } 189 | 190 | //简化修改update 191 | public function update($table, $mod_content, $condition, $url = '') { 192 | //echo "UPDATE $table SET $mod_content WHERE $condition"; exit(); 193 | if ($this->query("UPDATE $table SET $mod_content WHERE $condition")) { 194 | if (!empty ($url)) 195 | $this->Get_admin_msg($url); 196 | } 197 | } 198 | 199 | /*取得上一步 INSERT 操作产生的 ID*/ 200 | public function insert_id() { 201 | return mysql_insert_id(); 202 | } 203 | 204 | //指向确定的一条数据记录 205 | public function db_data_seek($id) { 206 | if ($id > 0) { 207 | $id = $id -1; 208 | } 209 | if (!@ mysql_data_seek($this->result, $id)) { 210 | $this->show_error("SQL语句有误:", "指定的数据为空"); 211 | } 212 | return $this->result; 213 | } 214 | 215 | // 根据select查询结果计算结果集条数 216 | public function db_num_rows() { 217 | if ($this->result == null) { 218 | if ($this->show_error) { 219 | $this->show_error("SQL语句错误", "暂时为空,没有任何内容!"); 220 | } 221 | } else { 222 | return mysql_num_rows($this->result); 223 | } 224 | } 225 | 226 | // 根据insert,update,delete执行结果取得影响行数 227 | public function db_affected_rows() { 228 | return mysql_affected_rows(); 229 | } 230 | 231 | //输出显示sql语句 232 | public function show_error($message = "", $sql = "") { 233 | if (!$sql) { 234 | echo "" . $message . ""; 235 | echo "
"; 236 | } else { 237 | echo "
"; 238 | echo "错误信息提示:
"; 239 | echo "
"; 240 | echo "
"; 241 | echo "错误号:12142"; 242 | echo "

"; 243 | echo "错误原因:" . mysql_error() . "

"; 244 | echo "
"; 245 | echo "" . $message . ""; 246 | echo "
"; 247 | echo "
" . $sql . "
"; 248 | $ip = $this->getip(); 249 | if ($this->bulletin) { 250 | $time = date("Y-m-d H:i:s"); 251 | $message = $message . "\r\n$this->sql" . "\r\n客户IP:$ip" . "\r\n时间 :$time" . "\r\n\r\n"; 252 | 253 | $server_date = date("Y-m-d"); 254 | $filename = $server_date . "_SQL.txt"; 255 | $file_path = ROOT_PATH."/error/" . $filename; 256 | $error_content = $message; 257 | //$error_content="错误的数据库,不可以链接"; 258 | $file = ROOT_PATH."/error"; //设置文件保存目录 259 | 260 | //建立文件夹 261 | if (!file_exists($file)) { 262 | if (!mkdir($file, 0777)) { 263 | //默认的 mode 是 0777,意味着最大可能的访问权 264 | die("upload files directory does not exist and creation failed"); 265 | } 266 | } 267 | 268 | //建立txt日期文件 269 | if (!file_exists($file_path)) { 270 | 271 | //echo "建立日期文件"; 272 | fopen($file_path, "w+"); 273 | 274 | //首先要确定文件存在并且可写 275 | if (is_writable($file_path)) { 276 | //使用添加模式打开$filename,文件指针将会在文件的开头 277 | if (!$handle = fopen($file_path, 'a')) { 278 | echo "不能打开文件 $filename"; 279 | exit; 280 | } 281 | 282 | //将$somecontent写入到我们打开的文件中。 283 | if (!fwrite($handle, $error_content)) { 284 | echo "不能写入到文件 $filename"; 285 | exit; 286 | } 287 | 288 | //echo "文件 $filename 写入成功"; 289 | 290 | echo "——错误记录被保存!"; 291 | 292 | //关闭文件 293 | fclose($handle); 294 | } else { 295 | echo "文件 $filename 不可写"; 296 | } 297 | 298 | } else { 299 | //首先要确定文件存在并且可写 300 | if (is_writable($file_path)) { 301 | //使用添加模式打开$filename,文件指针将会在文件的开头 302 | if (!$handle = fopen($file_path, 'a')) { 303 | echo "不能打开文件 $filename"; 304 | exit; 305 | } 306 | 307 | //将$somecontent写入到我们打开的文件中。 308 | if (!fwrite($handle, $error_content)) { 309 | echo "不能写入到文件 $filename"; 310 | exit; 311 | } 312 | 313 | //echo "文件 $filename 写入成功"; 314 | echo "——错误记录被保存!"; 315 | 316 | //关闭文件 317 | fclose($handle); 318 | } else { 319 | echo "文件 $filename 不可写"; 320 | } 321 | } 322 | 323 | } 324 | echo "
"; 325 | if ($this->is_error) { 326 | exit; 327 | } 328 | } 329 | echo "
"; 330 | echo "
"; 331 | 332 | echo "
"; 333 | } 334 | 335 | //释放结果集 336 | public function free() { 337 | @ mysql_free_result($this->result); 338 | } 339 | 340 | //数据库选择 341 | public function select_db($db_database) { 342 | return mysql_select_db($db_database); 343 | } 344 | 345 | //查询字段数量 346 | public function num_fields($table_name) { 347 | //return mysql_num_fields($this->result); 348 | $this->query("select * from $table_name"); 349 | echo "
"; 350 | echo "字段数:" . $total = mysql_num_fields($this->result); 351 | echo "
";
352 | 		for ($i = 0; $i < $total; $i++) {
353 | 			print_r(mysql_fetch_field($this->result, $i));
354 | 		}
355 | 		echo "
"; 356 | echo "
"; 357 | } 358 | 359 | //取得 MySQL 服务器信息 360 | public function mysql_server($num = '') { 361 | switch ($num) { 362 | case 1 : 363 | return mysql_get_server_info(); //MySQL 服务器信息 364 | break; 365 | 366 | case 2 : 367 | return mysql_get_host_info(); //取得 MySQL 主机信息 368 | break; 369 | 370 | case 3 : 371 | return mysql_get_client_info(); //取得 MySQL 客户端信息 372 | break; 373 | 374 | case 4 : 375 | return mysql_get_proto_info(); //取得 MySQL 协议信息 376 | break; 377 | 378 | default : 379 | return mysql_get_client_info(); //默认取得mysql版本信息 380 | } 381 | } 382 | 383 | //析构函数,自动关闭数据库,垃圾回收机制 384 | public function __destruct() { 385 | if (!empty ($this->result)) { 386 | $this->free(); 387 | } 388 | // mysql_close($this->conn); 389 | } //function __destruct(); 390 | 391 | /*获得客户端真实的IP地址*/ 392 | function getip() { 393 | if (getenv("HTTP_CLIENT_IP") && strcasecmp(getenv("HTTP_CLIENT_IP"), "unknown")) { 394 | $ip = getenv("HTTP_CLIENT_IP"); 395 | } else 396 | if (getenv("HTTP_X_FORWARDED_FOR") && strcasecmp(getenv("HTTP_X_FORWARDED_FOR"), "unknown")) { 397 | $ip = getenv("HTTP_X_FORWARDED_FOR"); 398 | } else 399 | if (getenv("REMOTE_ADDR") && strcasecmp(getenv("REMOTE_ADDR"), "unknown")) { 400 | $ip = getenv("REMOTE_ADDR"); 401 | } else 402 | if (isset ($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], "unknown")) { 403 | $ip = $_SERVER['REMOTE_ADDR']; 404 | } else { 405 | $ip = "unknown"; 406 | } 407 | return ($ip); 408 | } 409 | function inject_check($sql_str) { //防止注入 410 | $check = eregi('select|insert|update|delete|\'|\/\*|\*|\.\.\/|\.\/|union|into|load_file|outfile', $sql_str); 411 | if ($check) { 412 | echo "输入非法注入内容!"; 413 | exit (); 414 | } else { 415 | return $sql_str; 416 | } 417 | } 418 | function checkurl() { //检查来路 419 | if (preg_replace("/https?:\/\/([^\:\/]+).*/i", "\\1", $_SERVER['HTTP_REFERER']) !== preg_replace("/([^\:]+).*/", "\\1", $_SERVER['HTTP_HOST'])) { 420 | header("Location: http://yuansir-web.com"); 421 | exit(); 422 | } 423 | } 424 | 425 | } 426 | 427 | -------------------------------------------------------------------------------- /system/lib/lib_route.php: -------------------------------------------------------------------------------- 1 | 6 | * @version 1.0 7 | */ 8 | final class Route{ 9 | public $url_query; 10 | public $url_type; 11 | public $route_url = array(); 12 | 13 | 14 | public function __construct() { 15 | $this->url_query = parse_url($_SERVER['REQUEST_URI']); 16 | } 17 | /** 18 | * 设置URL类型 19 | * @access public 20 | */ 21 | public function setUrlType($url_type = 2){ 22 | if($url_type > 0 && $url_type <3){ 23 | $this->url_type = $url_type; 24 | }else{ 25 | trigger_error("指定的URL模式不存在!"); 26 | } 27 | } 28 | 29 | /** 30 | * 获取数组形式的URL 31 | * @access public 32 | */ 33 | public function getUrlArray(){ 34 | $this->makeUrl(); 35 | return $this->route_url; 36 | } 37 | /** 38 | * @access public 39 | */ 40 | public function makeUrl(){ 41 | switch ($this->url_type){ 42 | case 1: 43 | $this->querytToArray(); 44 | break; 45 | case 2: 46 | $this->pathinfoToArray(); 47 | break; 48 | } 49 | } 50 | /** 51 | * 将query形式的URL转化成数组 52 | * @access public 53 | */ 54 | public function querytToArray(){ 55 | $arr = !empty ($this->url_query['query']) ?explode('&', $this->url_query['query']) :array(); 56 | $array = $tmp = array(); 57 | if (count($arr) > 0) { 58 | foreach ($arr as $item) { 59 | $tmp = explode('=', $item); 60 | $array[$tmp[0]] = $tmp[1]; 61 | } 62 | if (isset($array['app'])) { 63 | $this->route_url['app'] = $array['app']; 64 | unset($array['app']); 65 | } 66 | if (isset($array['controller'])) { 67 | $this->route_url['controller'] = $array['controller']; 68 | unset($array['controller']); 69 | } 70 | if (isset($array['action'])) { 71 | $this->route_url['action'] = $array['action']; 72 | unset($array['action']); 73 | } 74 | if(count($array) > 0){ 75 | $this->route_url['params'] = $array; 76 | } 77 | }else{ 78 | $this->route_url = array(); 79 | } 80 | } 81 | /** 82 | * 将PATH_INFO的URL形式转化为数组 83 | * @access public 84 | */ 85 | public function pathinfoToArray(){ 86 | 87 | } 88 | } 89 | 90 | 91 | -------------------------------------------------------------------------------- /system/lib/lib_template.php: -------------------------------------------------------------------------------- 1 | 7 | * @version 1.0 8 | */ 9 | final class Template { 10 | public $template_name = null; 11 | public $data = array(); 12 | public $out_put = null; 13 | 14 | public function init($template_name,$data = array()) { 15 | $this->template_name = $template_name; 16 | $this->data = $data; 17 | $this->fetch(); 18 | } 19 | /** 20 | * 加载模板文件 21 | * @access public 22 | * @param string $file 23 | */ 24 | public function fetch() { 25 | $view_file = VIEW_PATH . '/' . $this->template_name . '.php'; 26 | if (file_exists($view_file)) { 27 | extract($this->data); 28 | ob_start(); 29 | include $view_file; 30 | $content = ob_get_contents(); 31 | ob_end_clean(); 32 | $this->out_put = $content; 33 | } else { 34 | trigger_error('加载 ' . $view_file . ' 模板不存在'); 35 | } 36 | } 37 | /** 38 | * 输出模板 39 | * @access public 40 | * @return string 41 | */ 42 | public function outPut(){ 43 | echo $this->out_put; 44 | } 45 | /** 46 | * 写入静态化文件 47 | * @access public 48 | */ 49 | // public function toHtml() { 50 | // if (!is_dir(ROOT_PATH . '/cache/template/')) { 51 | // mkdir(ROOT_PATH . '/cache/template/', 0777); 52 | // } 53 | // if (!$fp = @fopen(ROOT_PATH . '/cache/template/' . $filename . '.html', 'w')) { 54 | // trigger_error('文件 ' . ROOT_PATH . '/cache/template/' . $filename . '.html' . ' 不能打开'); 55 | // } 56 | // if (fwrite($fp, $content) == FALSE) { 57 | // trigger_error('文件 ' . ROOT_PATH . '/cache/template/' . $filename . '.html' . ' 写入失败'); 58 | // } 59 | // fclose($fp); 60 | // } 61 | 62 | } 63 | 64 | -------------------------------------------------------------------------------- /system/lib/lib_thumbnail.php: -------------------------------------------------------------------------------- 1 | maxWidth = $maxWidth; 34 | $this->maxHeight = $maxHeight; 35 | $this->scale = $scale; 36 | $this->inflate = $inflate; 37 | $this->types = array( 38 | 'image/jpeg', 39 | 'image/png', 40 | 'image/gif' 41 | ); 42 | //加载MIME类型图像的函数名称 43 | $this->imgLoaders = array( 44 | 'image/jpeg' => 'imagecreatefromjpeg', 45 | 'image/png' => 'imagecreatefrompng', 46 | 'image/gif' => 'imagecreatefromgif' 47 | ); 48 | //储存创建MIME类型图片的函数名称 49 | $this->imgCreators = array( 50 | 'image/jpeg' => 'imagejpeg', 51 | 'image/png' => 'imagepng', 52 | 'image/gif' => 'imagegif' 53 | ); 54 | } 55 | /** 56 | * 文件方式加载图片 57 | * @param string $image 源图片 58 | * @return bool 59 | */ 60 | public function loadFile($image){ 61 | if(!$dims = @getimagesize($image)){ 62 | trigger_error("源图片不存在"); 63 | } 64 | if(in_array($dims['mime'], $this->types)){ 65 | $loader = $this->imgLoaders[$dims['mime']]; 66 | $this->source = $loader($image); 67 | $this->sourceWidth = $dims[0]; 68 | $this->sourceHeight = $dims[1]; 69 | $this->sourceMime = $dims['mime']; 70 | $this->initThumb(); 71 | return TRUE; 72 | }else{ 73 | trigger_error('不支持'.$dims['mime']."图片类型"); 74 | } 75 | } 76 | /** 77 | * 字符串方式加载图片 78 | * @param string $image 字符串 79 | * @param string $mime 图片类型 80 | * @return type 81 | */ 82 | public function loadData($image,$mime){ 83 | if(in_array($mime, $this->types)){ 84 | if($this->source = @imagecreatefromstring($image)){ 85 | $this->sourceWidth = imagesx($this->source); 86 | $this->sourceHeight = imagesy($this->source); 87 | $this->sourceMime = $mime; 88 | $this->initThumb(); 89 | return TRUE; 90 | }else{ 91 | trigger_error("不能从字符串加载图片"); 92 | } 93 | }else{ 94 | trigger_error("不支持".$mime."图片格式"); 95 | } 96 | } 97 | /** 98 | * 生成缩略图 99 | * @param string $file 文件名。如果不为空则储存为文件,否则直接输出到浏览器 100 | */ 101 | public function buildThumb($file = null){ 102 | $creator = $this->imgCreators[$this->sourceMime]; 103 | if(isset($file)){ 104 | return $creator($this->thumb,$file); 105 | }else{ 106 | return $creator($this->thumb); 107 | } 108 | } 109 | /** 110 | * @access public 111 | */ 112 | public function initThumb(){ 113 | if($this->scale){ 114 | if($this->sourceWidth > $this->sourceHeight){ 115 | $this->thumbWidth = $this->maxWidth; 116 | $this->thumbHeight = floor($this->sourceHeight*($this->maxWidth/$this->sourceWidth)); 117 | }elseif($this->sourceWidth < $this->sourceHeight){ 118 | $this->thumbHeight = $this->maxHeight; 119 | $this->thumbWidth = floor($this->sourceWidth*($this->maxHeight/$this->sourceHeight)); 120 | }else{ 121 | $this->thumbWidth = $this->maxWidth; 122 | $this->thumbHeight = $this->maxHeight; 123 | } 124 | } 125 | $this->thumb = imagecreatetruecolor($this->thumbWidth, $this->thumbHeight); 126 | 127 | if($this->sourceWidth <= $this->maxWidth && $this->sourceHeight <= $this->maxHeight && $this->inflate == FALSE){ 128 | $this->thumb = $this->source; 129 | }else{ 130 | imagecopyresampled($this->thumb, $this->source, 0, 0, 0, 0, $this->thumbWidth, $this->thumbHeight, $this->sourceWidth, $this->sourceHeight); 131 | } 132 | } 133 | 134 | public function getMine(){ 135 | return $this->sourceMime; 136 | } 137 | 138 | public function getThumbWidth(){ 139 | return $this->thumbWidth; 140 | } 141 | 142 | public function getThumbHeight(){ 143 | return $this->thumbHeight; 144 | } 145 | 146 | } 147 | 148 | /** 149 | * 缩略图类调用示例(文件) 150 | */ 151 | //$thumb = new Thumbnail(200, 200); 152 | //$thumb->loadFile('wap.gif'); 153 | //header('Content-Type:'.$thumb->getMine()); 154 | //$thumb->buildThumb(); 155 | ///** 156 | // * 缩略图类调用示例(字符串) 157 | // */ 158 | //$thumb = new Thumbnail(200, 200); 159 | //$image = file_get_contents('wap.gif'); 160 | //$thumb->loadData($image, 'image/jpeg'); 161 | //$thumb->buildThumb('wap_thumb.gif'); -------------------------------------------------------------------------------- /view/home.php: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 |
5 | 6 | 7 |
8 | 用户名:
9 | 密码:
10 | 11 |
12 | 13 | -------------------------------------------------------------------------------- /自己动手写PHP MVC框架教程.txt: -------------------------------------------------------------------------------- 1 | 自己动手写PHP MVC框架 2 | 3 | 来自:yuansir-web.com / yuansir@live.cn 4 | 5 | PHP的框架众多,对于哪个框架最好,哪个框架最烂,是否应该用框架,对于这些争论在论坛里面都有人争论,这里不做评价, 6 | 个人觉得根据自己需求,选中最佳最适合自己MVC框架,并在开发中能够体现出敏捷开发的效果就OK了,作为一个PHPer要提高自己的对PHP和MVC的框架的认识,所以自己写一个MVC框架是很有必要的, 7 | 即使不是很完善,但是自己动手写一个轻量简洁的PHP MVC框架起码对MVC的思想有一定的了解,而且经过自己后期的完善会渐渐形成一个自己熟悉的一个PHP框架。 8 | 9 | 来写一个PHP MVC框架开发的简明教程,首先声明,教程里面的框架不是一个完善的框架,只是一种思路,当然每个人对MVC框架实现的方法肯定是有差异的,希望高手多提意见多指正,和我一样的菜鸟多讨论多交流,刚接触MVC的PHPer多学习。 10 | 11 | 首先,我们在项目中建立如下目录和文件: 12 | 13 | app 14 | |-controller 存放控制器文件 15 | |-model 存放模型文件 16 | |-view 存放视图文件 17 | |-lib 存放自定义类库 18 | |-config 存放配置文件 19 | |--config.php 系统配置文件 20 | |-system 系统核心目录 21 | |-index.php 入口文件 22 | 23 | 新件的index.php为入口文件,我们这里采用单一入口,入口文件的内容很简单: 24 | 25 | 30 | * @version 1.0 31 | */ 32 | require dirname(__FILE__).'/system/app.php'; 33 | require dirname(__FILE__).'/config/config.php'; 34 | Application::run($CONFIG); 35 | 36 | 入口文件主要做了2件事,第一引入系统的驱动类,第二是引入配置文件,然后运行run()方法,传入配置作为参数,具体这2个文件是什么内容,我们接下来继续看。 37 | 38 | 先看一下config/config.php文件,里面其实是一个$CONFIG变量,这个变量存放的全局的配置: 39 | 40 | 45 | * @version 1.0 46 | */ 47 | 48 | /*数据库配置*/ 49 | $CONFIG['system']['db'] = array( 50 | 'db_host' => 'localhost', 51 | 'db_user' => 'root', 52 | 'db_password' => '', 53 | 'db_database' => 'app', 54 | 'db_table_prefix' => 'app_', 55 | 'db_charset' => 'urf8', 56 | 'db_conn' => '', //数据库连接标识; pconn 为长久链接,默认为即时链接 57 | 58 | ); 59 | 60 | /*自定义类库配置*/ 61 | $CONFIG['system']['lib'] = array( 62 | 'prefix' => 'my' //自定义类库的文件前缀 63 | ); 64 | 65 | $CONFIG['system']['route'] = array( 66 | 'default_controller' => 'home', //系统默认控制器 67 | 'default_action' => 'index', //系统默认控制器 68 | 'url_type' => 1 /*定义URL的形式 1 为普通模式 index.php?c=controller&a=action&id=2 69 | * 2 为PATHINFO index.php/controller/action/id/2(暂时不实现) 70 | */ 71 | ); 72 | 73 | /*缓存配置*/ 74 | $CONFIG['system']['cache'] = array( 75 | 'cache_dir' => 'cache', //缓存路径,相对于根目录 76 | 'cache_prefix' => 'cache_',//缓存文件名前缀 77 | 'cache_time' => 1800, //缓存时间默认1800秒 78 | 'cache_mode' => 2, //mode 1 为serialize ,model 2为保存为可执行文件 79 | ); 80 | 81 | 我这里有意识的定义$CONFIG['system']数组表示是系统的配置文件,当然你可以在里面定义$CONFIG['myconfig']为表示在定义的配置,以后在程序的控制器,模型,视图中来调用,都个很自由。 82 | 具体配置值代表什么意思注视很清楚了,下面的如果程序中有详细注释的我就不解释啦,呵呵 83 | 84 | 再来看一下system/app.php文件,主要是干嘛的: 85 | 86 | 91 | * @version 1.0 92 | */ 93 | define('SYSTEM_PATH', dirname(__FILE__)); 94 | define('ROOT_PATH', substr(SYSTEM_PATH, 0,-7)); 95 | define('SYS_LIB_PATH', SYSTEM_PATH.'/lib'); 96 | define('APP_LIB_PATH', ROOT_PATH.'/lib'); 97 | define('SYS_CORE_PATH', SYSTEM_PATH.'/core'); 98 | define('CONTROLLER_PATH', ROOT_PATH.'/controller'); 99 | define('MODEL_PATH', ROOT_PATH.'/model'); 100 | define('VIEW_PATH', ROOT_PATH.'/view'); 101 | define('LOG_PATH', ROOT_PATH.'/error/'); 102 | final class Application { 103 | public static $_lib = null; 104 | public static $_config = null; 105 | public static function init() { 106 | self::setAutoLibs(); 107 | require SYS_CORE_PATH.'/model.php'; 108 | require SYS_CORE_PATH.'/controller.php'; 109 | 110 | } 111 | /** 112 | * 创建应用 113 | * @access public 114 | * @param array $config 115 | */ 116 | public static function run($config){ 117 | self::$_config = $config['system']; 118 | self::init(); 119 | self::autoload(); 120 | self::$_lib['route']->setUrlType(self::$_config['route']['url_type']); 121 | $url_array = self::$_lib['route']->getUrlArray(); 122 | self::routeToCm($url_array); 123 | } 124 | /** 125 | * 自动加载类库 126 | * @access public 127 | * @param array $_lib 128 | */ 129 | public static function autoload(){ 130 | foreach (self::$_lib as $key => $value){ 131 | require (self::$_lib[$key]); 132 | $lib = ucfirst($key); 133 | self::$_lib[$key] = new $lib; 134 | } 135 | //初始化cache 136 | if(is_object(self::$_lib['cache'])){ 137 | self::$_lib['cache']->init( 138 | ROOT_PATH.'/'.self::$_config['cache']['cache_dir'], 139 | self::$_config['cache']['cache_prefix'], 140 | self::$_config['cache']['cache_time'], 141 | self::$_config['cache']['cache_mode'] 142 | ); 143 | } 144 | } 145 | /** 146 | * 加载类库 147 | * @access public 148 | * @param string $class_name 类库名称 149 | * @return object 150 | */ 151 | public static function newLib($class_name){ 152 | $app_lib = $sys_lib = ''; 153 | $app_lib = APP_LIB_PATH.'/'.self::$_config['lib']['prefix'].'_'.$class_name.'.php'; 154 | $sys_lib = SYS_LIB_PATH.'/lib_'.$class_name.'.php'; 155 | 156 | if(file_exists($app_lib)){ 157 | require ($app_lib); 158 | $class_name = ucfirst(self::$_config['lib']['prefix']).ucfirst($class_name); 159 | return new $class_name; 160 | }else if(file_exists($sys_lib)){ 161 | require ($sys_lib); 162 | return self::$_lib['$class_name'] = new $class_name; 163 | }else{ 164 | trigger_error('加载 '.$class_name.' 类库不存在'); 165 | } 166 | } 167 | /** 168 | * 自动加载的类库 169 | * @access public 170 | */ 171 | public static function setAutoLibs(){ 172 | self::$_lib = array( 173 | 'route' => SYS_LIB_PATH.'/lib_route.php', 174 | 'mysql' => SYS_LIB_PATH.'/lib_mysql.php', 175 | 'template' => SYS_LIB_PATH.'/lib_template.php', 176 | 'cache' => SYS_LIB_PATH.'/lib_cache.php', 177 | 'thumbnail' => SYS_LIB_PATH.'/lib_thumbnail.php' 178 | ); 179 | } 180 | /** 181 | * 根据URL分发到Controller和Model 182 | * @access public 183 | * @param array $url_array 184 | */ 185 | public static function routeToCm($url_array = array()){ 186 | $app = ''; 187 | $controller = ''; 188 | $action = ''; 189 | $model = ''; 190 | $params = ''; 191 | 192 | if(isset($url_array['app'])){ 193 | $app = $url_array['app']; 194 | } 195 | 196 | if(isset($url_array['controller'])){ 197 | $controller = $model = $url_array['controller']; 198 | if($app){ 199 | $controller_file = CONTROLLER_PATH.'/'.$app.'/'.$controller.'Controller.php'; 200 | $model_file = MODEL_PATH.'/'.$app.'/'.$model.'Model.php'; 201 | }else{ 202 | $controller_file = CONTROLLER_PATH.'/'.$controller.'Controller.php'; 203 | $model_file = MODEL_PATH.'/'.$model.'Model.php'; 204 | } 205 | }else{ 206 | $controller = $model = self::$_config['route']['default_controller']; 207 | if($app){ 208 | $controller_file = CONTROLLER_PATH.'/'.$app.'/'.self::$_config['route']['default_controller'].'Controller.php'; 209 | $model_file = MODEL_PATH.'/'.$app.'/'.self::$_config['route']['default_controller'].'Model.php'; 210 | }else{ 211 | $controller_file = CONTROLLER_PATH.'/'.self::$_config['route']['default_controller'].'Controller.php'; 212 | $model_file = MODEL_PATH.'/'.self::$_config['route']['default_controller'].'Model.php'; 213 | } 214 | } 215 | if(isset($url_array['action'])){ 216 | $action = $url_array['action']; 217 | }else{ 218 | $action = self::$_config['route']['default_action']; 219 | } 220 | 221 | if(isset($url_array['params'])){ 222 | $params = $url_array['params']; 223 | } 224 | if(file_exists($controller_file)){ 225 | if (file_exists($model_file)) { 226 | require $model_file; 227 | } 228 | require $controller_file; 229 | $controller = $controller.'Controller'; 230 | $controller = new $controller; 231 | if($action){ 232 | if(method_exists($controller, $action)){ 233 | isset($params) ? $controller ->$action($params) : $controller ->$action(); 234 | }else{ 235 | die('控制器方法不存在'); 236 | } 237 | }else{ 238 | die('控制器方法不存在'); 239 | } 240 | }else{ 241 | die('控制器不存在'); 242 | } 243 | } 244 | 245 | } 246 | 247 | 我叫它框架驱动类,也许不合适,但是我是这样理解的,它用来启动这个框架,做好一些初始化的工作,下面我来详细分析一下每个方法的功能: 248 | 1.首先时定义了一些常量,很明了,不解释了 249 | 2.setAutoLibs 这个方法其实就是设定那些是系统启动时自动加载的类库,类库文件都存放在SYS_LIB_PATH下面,以lib_开头的,当然这里你可以根据自己的规则来命名 250 | 3.autoload 这个方法就是用来引入你要自动加载的类,然后来实例化,用$_lib数组来保存类的实例,比如$lib['route']是system/lib/lib_route.php中lib_route类的实例 251 | 4.newLib 这个方法是用来加载你自定义的类的,自定义类存放在根目录下的lib中,但是自定义的类的文件前缀是你自己定义的,看系统配置文件里面有,我定义的是my,这样我就可以在lib 252 | 目录下新建一个自定义的类了,比如 my_test.php 253 | setUrlType(self::$_config['route']['url_type']); //设置url的类型 266 | $url_array = self::$_lib['route']->getUrlArray(); //将url转发成数组 267 | 好吧,我们来看下route的系统类到底做了说明 268 | 269 | 274 | * @version 1.0 275 | */ 276 | final class Route{ 277 | public $url_query; 278 | public $url_type; 279 | public $route_url = array(); 280 | 281 | 282 | public function __construct() { 283 | $this->url_query = parse_url($_SERVER['REQUEST_URI']); 284 | } 285 | /** 286 | * 设置URL类型 287 | * @access public 288 | */ 289 | public function setUrlType($url_type = 2){ 290 | if($url_type > 0 && $url_type <3){ 291 | $this->url_type = $url_type; 292 | }else{ 293 | trigger_error("指定的URL模式不存在!"); 294 | } 295 | } 296 | 297 | /** 298 | * 获取数组形式的URL 299 | * @access public 300 | */ 301 | public function getUrlArray(){ 302 | $this->makeUrl(); 303 | return $this->route_url; 304 | } 305 | /** 306 | * @access public 307 | */ 308 | public function makeUrl(){ 309 | switch ($this->url_type){ 310 | case 1: 311 | $this->querytToArray(); 312 | break; 313 | case 2: 314 | $this->pathinfoToArray(); 315 | break; 316 | } 317 | } 318 | /** 319 | * 将query形式的URL转化成数组 320 | * @access public 321 | */ 322 | public function querytToArray(){ 323 | $arr = !empty ($this->url_query['query']) ?explode('&', $this->url_query['query']) :array(); 324 | $array = $tmp = array(); 325 | if (count($arr) > 0) { 326 | foreach ($arr as $item) { 327 | $tmp = explode('=', $item); 328 | $array[$tmp[0]] = $tmp[1]; 329 | } 330 | if (isset($array['app'])) { 331 | $this->route_url['app'] = $array['app']; 332 | unset($array['app']); 333 | } 334 | if (isset($array['controller'])) { 335 | $this->route_url['controller'] = $array['controller']; 336 | unset($array['controller']); 337 | } 338 | if (isset($array['action'])) { 339 | $this->route_url['action'] = $array['action']; 340 | unset($array['action']); 341 | } 342 | if(count($array) > 0){ 343 | $this->route_url['params'] = $array; 344 | } 345 | }else{ 346 | $this->route_url = array(); 347 | } 348 | } 349 | /** 350 | * 将PATH_INFO的URL形式转化为数组 351 | * @access public 352 | */ 353 | public function pathinfoToArray(){ 354 | 355 | } 356 | } 357 | 358 | 359 | 注意querytToArray方法,将将query形式的URL转化成数组,比如原来是localhost/myapp/index.php/app=admin&controller=index&action=edit&id=9&fid=10 这样的url就会被转发成如下的数组 360 | array( 361 | 'app' =>'admin', 362 | 'controller' =>'index', 363 | 'action' =>'edit', 364 | 'id' =>array( 365 | 'id' =>9, 366 | 'fid' =>10 367 | ) 368 | ) 369 | 这下再耐心来看下我写的笨拙的routeToCm,来通过数组参数来分发到控制器,找到控制器以后还要引用相应的模型,然后就实例化控制器和模型,呵呵,貌似有点成型了。 370 | 371 | 372 | 下面就要开始实现 控制器-模型-视图了 373 | 我们的思路是这样的,建立一个核心模型和核心控制器,在以后自己的模型和控制器中来继承核心模型和控制器,核心模型和控制器中主要可以是一些通用的方法和必须的组建的加载,下面我们先来写核心控制器, 374 | 新建system/core/controller.php 375 | 380 | * @version 1.0 381 | */ 382 | class Controller{ 383 | 384 | public function __construct() { 385 | // header('Content-type:text/html;chartset=utf-8'); 386 | } 387 | /** 388 | * 实例化模型 389 | * @access final protected 390 | * @param string $model 模型名称 391 | */ 392 | final protected function model($model) { 393 | if (empty($model)) { 394 | trigger_error('不能实例化空模型'); 395 | } 396 | $model_name = $model . 'Model'; 397 | return new $model_name; 398 | } 399 | /** 400 | * 加载类库 401 | * @param string $lib 类库名称 402 | * @param Bool $my 如果FALSE默认加载系统自动加载的类库,如果为TRUE则加载非自动加载类库 403 | * @return object 404 | */ 405 | final protected function load($lib,$auto = TRUE){ 406 | if(empty($lib)){ 407 | trigger_error('加载类库名不能为空'); 408 | }elseif($auto === TRUE){ 409 | return Application::$_lib[$lib]; 410 | }elseif($auto === FALSE){ 411 | return Application::newLib($lib); 412 | } 413 | } 414 | /** 415 | * 加载系统配置,默认为系统配置 $CONFIG['system'][$config] 416 | * @access final protected 417 | * @param string $config 配置名 418 | */ 419 | final protected function config($config){ 420 | return Application::$_config[$config]; 421 | } 422 | /** 423 | * 加载模板文件 424 | * @access final protect 425 | * @param string $path 模板路径 426 | * @return string 模板字符串 427 | */ 428 | final protected function showTemplate($path,$data = array()){ 429 | $template = $this->load('template'); 430 | $template->init($path,$data); 431 | $template->outPut(); 432 | } 433 | } 434 | 435 | 注释都写的很清楚了吧,其实很简单,这里的加载模板的方法中load了一个系统自动加载的模板类,这个类我们在建立视图的时候再来讲,然后我们再来建核心模型的文件 436 | system/core/model.php 437 | 438 | 443 | * @version 1.0 444 | */ 445 | class Model { 446 | protected $db = null; 447 | 448 | final public function __construct() { 449 | header('Content-type:text/html;chartset=utf-8'); 450 | $this->db = $this->load('mysql'); 451 | $config_db = $this->config('db'); 452 | $this->db->init( 453 | $config_db['db_host'], 454 | $config_db['db_user'], 455 | $config_db['db_password'], 456 | $config_db['db_database'], 457 | $config_db['db_conn'], 458 | $config_db['db_charset'] 459 | ); //初始话数据库类 460 | } 461 | /** 462 | * 根据表前缀获取表名 463 | * @access final protected 464 | * @param string $table_name 表名 465 | */ 466 | final protected function table($table_name){ 467 | $config_db = $this->config('db'); 468 | return $config_db['db_table_prefix'].$table_name; 469 | } 470 | /** 471 | * 加载类库 472 | * @param string $lib 类库名称 473 | * @param Bool $my 如果FALSE默认加载系统自动加载的类库,如果为TRUE则加载自定义类库 474 | * @return type 475 | */ 476 | final protected function load($lib,$my = FALSE){ 477 | if(empty($lib)){ 478 | trigger_error('加载类库名不能为空'); 479 | }elseif($my === FALSE){ 480 | return Application::$_lib[$lib]; 481 | }elseif($my === TRUE){ 482 | return Application::newLib($lib); 483 | } 484 | } 485 | /** 486 | * 加载系统配置,默认为系统配置 $CONFIG['system'][$config] 487 | * @access final protected 488 | * @param string $config 配置名 489 | */ 490 | final protected function config($config=''){ 491 | return Application::$_config[$config]; 492 | } 493 | } 494 | 495 | 因为模型基本是处理数据库的相关内容,所以我们加载了mysql类,这个mysql类就不在这里写了,你可以自己根据习惯写自己的mysql的操作类,如果你想支持其他的数据库,完全可以自己灵活添加。 496 | 497 | 核心模型控制器已经有了,其实里面还可以添加其他你觉得必要的全局函数,这样我们开始新建一个自己的控制器和模型,来实例运用一下 498 | 新建controller/testController.php 499 | 500 | 505 | * @version 1.0 506 | */ 507 | class testController extends Controller { 508 | 509 | public function __construct() { 510 | parent::__construct(); 511 | } 512 | 513 | public function index() { 514 | echo "test"; 515 | } 516 | 517 | public function testDb() { 518 | $modTest = $this->model('test'); //示例化test模型 519 | $databases = $modTest->testDatebases(); //调用test模型中 testDatebases()方法 520 | var_dump($databases); 521 | } 522 | } 523 | 524 | testController 继承我们的核心控制器,其实在以后的每个控制器中都要继承的,现在我们通过浏览器访问 http://localhost/myapp/index.php?controller=test ,哈哈,可以输出 test 字符串了 525 | 然后我们再新建一个模型model/testModel.php 526 | 527 | 532 | * @version 1.0 533 | */ 534 | class testModel extends Model{ 535 | 536 | function testDatabases(){ 537 | $this->db->show_databases(); 538 | } 539 | } 540 | 541 | 其实就是定义了一个获取所有的数据库的方法,打开浏览器访问 http://localhost/myapp/index.php?controller=test&action=testDb,不管你信不信,反正我的浏览器是输出了所有的数据库了 542 | 543 | 现在就差视图了,其实在核心控制器的controller.php文件中已经有了一个showTemplate方法,其实就是实现了加载模板类,$data就是我们要传递给模板的变量,然后输出模板 544 | /** 545 | * 加载模板文件 546 | * @access final protect 547 | * @param string $path 模板路径 548 | * @param array $data 模板变量 549 | * @return string 模板字符串 550 | */ 551 | final protected function showTemplate($path,$data = array()){ 552 | $template = $this->load('template'); 553 | $template->init($path,$data); 554 | $template->outPut(); 555 | } 556 | 557 | 下面我们来看一下template类 558 | 559 | 564 | * @version 1.0 565 | */ 566 | final class Template { 567 | public $template_name = null; 568 | public $data = array(); 569 | public $out_put = null; 570 | 571 | public function init($template_name,$data = array()) { 572 | $this->template_name = $template_name; 573 | $this->data = $data; 574 | $this->fetch(); 575 | } 576 | /** 577 | * 加载模板文件 578 | * @access public 579 | * @param string $file 580 | */ 581 | public function fetch() { 582 | $view_file = VIEW_PATH . '/' . $this->template_name . '.php'; 583 | if (file_exists($view_file)) { 584 | extract($this->data); 585 | ob_start(); 586 | include $view_file; 587 | $content = ob_get_contents(); 588 | ob_end_clean(); 589 | $this->out_put = $content; 590 | } else { 591 | trigger_error('加载 ' . $view_file . ' 模板不存在'); 592 | } 593 | } 594 | /** 595 | * 输出模板 596 | * @access public 597 | * @return string 598 | */ 599 | public function outPut(){ 600 | echo $this->out_put; 601 | } 602 | 是不是简单,就是引入你的静态模版文件,放在缓冲区,然后输出,其实如果你想静态化某个模版,那个这个放在缓冲区的$this->out_put就有用了,你可以在里面添加一个静态化的方法。 603 | 好了,现在我们来在新建一个视图文件 view/test.php 604 | 605 | 606 | 这是,呵呵 607 | 608 | 609 | 然后修改一些我们的testController.php中的index() 610 | public function index() { 611 | $data['test'] = "yuansir-web.com"; 612 | $this->showTemplate('test', $data); 613 | } 614 | 再来浏览 http://localhost/myapp/index.php?controller=test ,可以输出 “这是 yuansir-web.com,呵呵”,那么显然我们的视图也完成了。 615 | 616 | 这样我们的自己写PHP的MVC的框架就完成了,再补充一下,有人可能疑惑如果我是想建立前台后台的,单一入口怎么办呢,其实你要是从头就看我的这个教程,看下代码就会发现,其实只要在 controller目录下新建 617 | 一个admin目录就可以在里面写控制器了,比如controller/admin/testController.php 模板引用也是同样的道理,建立 view/admin/test.php ,然后模板加上路径就可以了,$this->showTemplate('admin/test', $data); 618 | 是不是很简单,很灵活。 619 | 620 | 好了,这样我们《自己动手写PHP MVC框架》的教程就结束了,你可以模仿自己写一个,也可以根据自己的思路来写一个,我教程中的可以自己扩增成一个完善的框架,再次申明一下,教程中的代码不完善,没有做过任何基准测试,效率神马的不考虑,便捷性神马的看个人,呵呵 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | --------------------------------------------------------------------------------