27岁,山西运城人,职业电商经理人,前端开发工作者,从事过网站建设、网络推广、SEO、SEM、信息流推广、二类电商、网络运维、软件开发,等相关电商工作,经验较为丰富,小米技术社区致力于为广大从事Web前端开发的人员提供一些力所能及的引导和帮助 ...[更多]
E-mail:mzze@163.com
Q Q:32362389
W X:xiaomi168527
27岁,山西运城人,职业电商经理人,网络工程师兼运维,从事过运营商网络建设,企业网络建设、优化。数据中心网络维护等通过,经验丰富,座右铭:当自己休息的时候,别忘了别人还在奔跑。 ...[更多]
大于花一样的年龄,河南郑州是我家,2010年在北京接触团购网,2011年进入天猫淘宝一待就是四年,如今已经将设计走向国际化(ps:误打误撞开始进入阿里巴巴国际站的设计,嘿嘿)五年电商设计,丰富经验,从事过天猫淘宝阿里各项设计,店铺运营,产品拍摄;我将我的经历与您分享是我的快乐!座右铭:越努力越幸运! ...[更多]
E-mail:97157726@qq.com
Q Q:97157726
文件参考:MVC综合案例 ←本篇案例上接此文章
将文件存放到不同的目录以后,由于类文件地址发生了变化,所以无法完成自动加载类,那么下面主要任务就是围绕如何实现类的自动加载展开。
由于每次都请求入口文件,所以”.“表示入口文件所在的目录
通过文件目录地址做命名空间,这样获取了命名空间就能知道文件存放的地址。
Model.class.php
namespace Core; class Model { ...
MyPDO.class.php
namespace Core; class MyPDO{ ...
ProductsModel.class.php
<?php namespace Model; //products模型用来操作products表 class ProductsModel extends Model{ ...
ProductsController.class.php
<?php namespace Controller\Admin; //商品模块 class ProductsController { ...
由于文件路径使用频率很高,而且路径比较长,所以将固定不变的路径定义成路径常量
知识点
1、getcwd():入口文件的绝对路径 2、windows下默认的目录分隔符是`\`,Linux下默认的目录分隔符是`/`。DIRECTORY_SEPARATOR常量根据不同的操作系统返回不同的目录分隔符。
代码实现
在Core文件夹下创建Framework.class.php
private static function initConst(){ define('DS', DIRECTORY_SEPARATOR); //定义目录分隔符 define('ROOT_PATH', getcwd().DS); //入口文件所在的目录 define('APP_PATH', ROOT_PATH.'Application'.DS); //application目录 define('CONFIG_PATH', APP_PATH.'Config'.DS); define('CONTROLLER_PATH', APP_PATH.'Controller'.DS); define('MODEL_PATH', APP_PATH.'Model'.DS); define('VIEW_PATH', APP_PATH.'View'.DS); define('FRAMEWORK_PATH', ROOT_PATH.'Framework'.DS); define('CORE_PATH', FRAMEWORK_PATH.'Core'.DS); define('LIB_PATH', FRAMEWORK_PATH.'Lib'.DS); define('TRAITS_PATH', ROOT_PATH.'Traits'.DS); }
1、在config目录下创建config.php
<?php return array( //数据库配置 'database'=>array(), //应用程序配置 'app' =>array( 'dp' => 'Admin', //默认平台 'dc' => 'Products', //默认控制器 'da' => 'list' //默认方法 ), );
2、在框架类中引入配置文件
<br class="Apple-interchange-newline"><div></div> private static function initConfig(){ $GLOBALS['config']=require CONFIG_PATH.'config.php'; }
思考:配置文件为什么不保存在常量中?
答:因为7.0之前,常量不能保存数组和对象。
p:【platform】平台
c:【controller】控制器
a:【action】方法
private static function initRoutes(){ $p=$_GET['p']??$GLOBALS['config']['app']['dp']; $c=$_GET['c']??$GLOBALS['config']['app']['dc']; $a=$_GET['a']??$GLOBALS['config']['app']['da']; $p=ucfirst(strtolower($p)); $c=ucfirst(strtolower($c)); //首字母大写 $a=strtolower($a); //转成小写 define('PLATFROM_NAME', $p); //平台名常量 define('CONTROLLER_NAME', $c); //控制器名常量 define('ACTION_NAME', $a); //方法名常量 define('__URL__', CONTROLLER_PATH.$p.DS); //当前请求控制器的目录地址 define('__VIEW__',VIEW_PATH.$p.DS); //当前视图的目录地址 }
private static function initAutoLoad(){ spl_autoload_register(function($class_name){ $namespace= dirname($class_name); //命名空间 $class_name= basename($class_name); //类名 if(in_array($namespace, array('Core','Lib'))) //命名空间在Core和Lib下 $path= FRAMEWORK_PATH.$namespace.DS.$class_name.'.class.php'; elseif($namespace=='Model') //文件在Model下 $path=MODEL_PATH.$class_name.'.class.php'; elseif($namespace=='Traits') //文件在Traits下 $path=TRAITS_PATH.$class_name.'.class.php'; else //控制器 $path=CONTROLLER_PATH.PLATFROM_NAME.DS.$class_name.'.class.php'; if(file_exists($path) && is_file($path)) require $path; }); }
private static function initDispatch(){ $controller_name='\Controller\\'.PLATFROM_NAME.'\\'.CONTROLLER_NAME.'Controller'; //拼接控制器类名 $action_name=ACTION_NAME.'Action'; //拼接方法名 $obj=new $controller_name(); $obj->$action_name(); }
class Framework{ //启动框架 public static function run(){ self::initConst(); self::initConfig(); self::initRoutes(); self::initAutoLoad(); self::initDispatch(); } ...
<?php require './Framework/Core/Framework.class.php'; Framework::run();
run()方法调用后就启动了框架。
(1)连接数据库的参数从配置文件中获取
class Model { ... //连接数据库 private function initMyPDO() { $this->mypdo= MyPDO::getInstance($GLOBALS['config']['database']); } }
(2)更改ProductsControleller控制器
<?php namespace Controller\Admin; //商品模块 class ProductsController { //获取商品列表 public function listAction() { //实例化模型 $model=new \Model\ProductsModel(); $list=$model->getList(); //加载视图 require __VIEW__.'products_list.html'; } //删除商品 public function delAction() { ... $model=new \Model\ProductsModel(); ... } }
(3)更改ProductsModel类
<?php namespace Model; class ProductsModel extends \Core\Model{ }
(4)更改MyPDO类
... private function fetchType($type){ switch ($type){ case 'num': return \PDO::FETCH_NUM; case 'both': return \PDO::FETCH_BOTH; case 'obj': return \PDO::FETCH_OBJ; default: return \PDO::FETCH_ASSOC; } } ... //所有的内置类都在公共的命名空间下。
测试:成功
有的控制器操作完毕后要跳转,有的不需要,
解决:将跳转的方法封装到traits中。
代码实现
(1)将准备好的图片拷贝到Public目录下
(2)在Traits目录中创建Jump.class.php
<?php //跳转的插件 namespace Traits; trait Jump{ //封装成功的跳转 public function success($url,$info='',$time=1){ $this->redirect($url, $info, $time, 'success'); } //封装失败跳转 public function error($url,$info='',$time=3){ $this->redirect($url, $info, $time, 'error'); } /* * 作用:跳转的方法 * @param $url string 跳转的地址 * @param $info string 显示信息 * @param $time int 停留时间 * @param $flag string 显示模式 success|error */ private function redirect($url,$info,$time,$flag){ if($info=='') header ("location:{$url}"); else{ echo <<<str <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <!-- <meta http-equiv="refresh" content="3;http://www.php.com"/> --> <title>Document</title> <style> body{ text-align: center; font-family: '微软雅黑'; font-size: 18px; } #success,#error{ font-size: 36px; margin: 10px auto; } #success{ color: #090; } #error{ color: #F00; } </style> </head> <body> <img src="/Public/images/{$flag}.fw.png"> <div id='{$flag}'>{$info}</div> <div><span id='t'>{$time}</span>秒以后跳转</div> </body> </html> <script> window.onload=function(){ var t={$time}; setInterval(function(){ document.getElementById('t').innerHTML=--t; if(t==0) location.href='index.php'; },1000) } </script> str; exit; } } }
在ProductsController控制器中使用原型
namespace Controller\Admin; //商品模块 class ProductsController{ use \Traits\Jump; //复用代码 ...
入口
<a href="index.php?p=Admin&c=Products&a=del&proid=<?=$rows['proID']?>" onclick="return confirm('确定要删除吗')">删除</a>
控制器(ProductsController)
public function delAction() { $id=(int)$_GET['proid']; //如果参数明确是整数,要强制转成整形 $model=new \Model\ProductsModel(); if($model->del($id)) $this->success('index.php?p=Admin&c=Products&a=list', '删除成功'); else $this->error('index.php?p=admin&c=Products&a=list', '删除失败'); }
模型、视图
无改变
本站内容均为小米原创,转载请注明出处:小米技术社区>> 编程思想-MVC的框架目录结构和其作用