ShopCMS 开发文档
HFramework 开发文档

ShopCMS 二次开发快速入门

ShopCMS充分利用了面向对象的机制,所有CMS类和方法都可以被重写或继承,基本的继承逻辑如下图:





入口文件负责加载基本文件或类库;
您的项目可以继承CMS系统的类库,继承CMS类库可以让少写很多代码,从而加快开发。但继承CMS不是必须的,在开发过程中,可以根据您的具体情况选择继承或者不继承;
您的项目也可以直接继承框架的类库,直接使用框架类的方法,同继承CMS类库一样,继承框架类也不是必须的;
CMS的类库继承自框架的类库;
框架除了提供基本的操作方法(比如渲染模板、字符校验、图片处理等),还起到调度类和文件的作用,实现MVC架构的具体功能;
关于MVC的介绍,点击这里»»

以用户注册为例,可参阅入口文件:index.php文件,关于类的加载过程说明如下:

用户访问  index.php?_=user/register,其中,user/register是请求路由,用于定位控制器类和调用的方法,调度过程如下:

1,index.php 收到请求,首先导入框架的基类:require(ROOT.'/framework/H.php')

2,index.php 导入CMS类:H::import(...)...,导入的过程,类不会实时加载,只有实际被实例化 new 的时候才被自动加载;
注:CMS类只有被导入才能被继承和调用,网站前端和管理后台导入的类各不相同,管理后台导入的具体类,可参考管理后台的index.php文件

3,index.php 调用框架的run方法:H::run(),进行初始化运作;

4,框架根据请求路由,尝试加载application/controller目录中的UserCtrl.php文件,并尝试实例化名为UserCtrl的类。
其中Ctrl是框架规定的控制器类文件名的后缀,控制器类文件在命名时必须带上,且类名与文件名同名。
如果发现UserCtrl类有继承,则根据被继承的类名查找父类,例如,UserCtrl类的写法如下:
<?php
/**
 * 用户控制器类
 */
class UserCtrl extends CUserCtrl{
	$User = new User();
	$data = $User->getUserInfo();//array
	$this->render('register', $data);
//......
}
框架尝试加载父类CUserCtrl.php类文件,找到就停止查找,尝试的顺序如下:
application/model/CUserCtrl.php,尝试的原因是:框架自动导入;
application/common/CUserCtrl.php,尝试的原因是:框架自动导入;
application/CMS/controller/CUserCtrl.php,尝试的原因是:在index.php中有动导入;
application/CMS/common/CUserCtrl.php,尝试的原因是:在index.php中有中有导入;
......
如果您在index.php中导入了其他类,仍会继续尝试加载,先导入的类文件或目录优先尝试加载,文件的优先级大于目录的优先级。
如果均没有找到,则报错,程序退出。
从上面的过程可以看出,如果您在application/common目录中同名重写CMS中的类,则CMS中的同名类永不会被加载,这样可以达到完全覆盖的目的。


5,当控制器类实例化之后,框架尝试调用控制器实例的register()方法,register()方法可以是自定义的或者继承的,如果没有此方法,或者此方法不是public的,则会报错,程序结束。

6,在register()方法中,一般会调用render()方法,此方法被定义在框架的控制器基类中:/framework/HController.php,用于把变量输出到对应的模板文件中,
如: $this->render('register', $data),会把$data中的数据,以变量的形式推送到application/view/user/register.php的模板文件中;
在register()方法中,你也可以调用 $this->show() 方法,show()方法也被定义在HController.php中,用于输出json到客户端;
你也可以根据自身的需求,自定义的其他的输出格式;

7,在控制器类的register方法中,如果有调用或者实例化其他的类,框架会尝试自动加载这个类,例如,有 new User() ,则尝试加载User类的顺序是:
application/model/User.php,尝试的原因是:框架自动导入;
application/common/User.php,尝试的原因是:框架自动导入;
application/CMS/model/User.php,尝试的原因是:在index.php中有导入;
aplication/CMS/common/User.php,尝试的原因是:在index.php中有导入;
......
如果您在index.php中导入了其他类,仍会继续尝试加载。
如果User.php类有继承,则也是按照上述顺序查找。

7,程序运行结束。

8,特别提醒:
  8.1:在非DEBUG模式下,框架会根据请求路由,自动缓存需要的类文件的地址。所以,在非DEBUG下,类的尝试加载过程只做一次,以后的请求就会根据缓存精准定位类文件。
  8.2:自定义类、第三方类的导入,不一定要在index.php中导入,可以在方法中或者类的定义前导入,只要在您使用前导入即可。   8.3:CMS类也不是必须导入的,如果您不需要CMS中已有的功能,您也不必导入。
  8.4:重要!!不建议您修改framework和cms目录中的文件,您的开发应在application目录中完成,这样当我们CMS升级或者框架升级的时候,您可以直接下载覆盖,从而轻松升级。

本文是笼统的介绍类的调度过程,有不清楚的逻辑或者名词,或者数据库的读写、SESSION、缓存等内容,可参考HFramework的开发文档。
关键词:MVC开发 PHP面向对象开发 php惰加载 php类自动加载 autoloader PHP类自动缓存
阅读:1031 | 发布时间:03-21 14:46