用php5.3的namespace实现类的无痛继承
来源:互联网 发布:外国人支付软件 编辑:程序博客网 时间:2024/04/29 19:56
作者:http://blog.leezhong.com/tech/2011/03/24/php-namespace-class-extend.html
标题有点怪异,先来说说正常的继承会有什么问题。假设你一个应用的Controller多次用到了View类,就像这样
<?phpclass Controller_Hello{public function action_index(){//...$view = new View('index.tpl');$view->render();}public function action_edit($id){//...$view = new View('edit.tpl');$view->render();}//...}
这个View是框架提供的,假如某一天发现View类需要新添加一个方法,最常用的就是新建一个自定义的View类继承框架的View类
<?phpclass My_View extends View{public function newMethod(){//...}}
这时以前使用View类的地方就要全部变成My_View,这是比较恐怖的。很多框架也都提供了解决方法,大体有三种
eval
这是Kohana2采用的方法,就是系统类命名为XXX_Core,然后调用的时候在autoload处,动态eval出一个XXX class,就像这样
<?php// system classclass View_Core{//...}// autoloadpublic function autoload($class){// first look into app dir// then look into modules dir// last look into system dirrequire '/path/to/'.$class.'.php';eval('class '.$class.' extends '.$class.'_Core');}
如果用户需要对该类添加新的方法,可以在app/classes里定义新的View类,同时继承View_Core类,这样使用时,因为优先级的原因,View类名可以保持不变
<?phpclass View extends View_Core{public function newMethod(){//...}}
因为使用了eval,所以不够优雅,而且有安全隐患
空壳法
这是Kohana3的做法,具体如下
<?php// system/classes/view.php// 是的,就这么一句话class View extends Kohana_View {}// system/classes/kohana/view.phpclass Kohana_View{//...}
根据优先级,最后会找到system/classes/view.php定义的View类。如果需要自己扩展Kohana_View类,可以在app/classes目录里新建一个view.php
<?phpclass View extends Kohana_View{// add your method}
这样框架就会先找到app/classes/view.php而不是system/classes/view.php,自定义View类生效,同时原先使用的View类也不需要做调整
这么做的缺点就是system/classes目录下会有大量的空壳类,有点累赘
attach behavior
这是yii采用的方法,简单说来就是通过attachBehavior方法,动态地给某个类添加新的功能
<?phpclass SomeComponent extends Component{//...}class SomeBehavior extends CBehavior{public function addWidth($width){$this->Owner->width += $width;}}$sc = new SomeComponent();$sc->attachBehavior('sb', 'SomeBehavior');$sc->addWidth(100);
需要实例化后动态调用attachBehavior方法,有点麻烦。而且不能使用父类的protected属性和方法。
用namespace实现无痛继承
所谓的无痛继承就是不用修改原先的类名,没有多余的空壳类,没有eval,不用attachBehavior,只要修改’use’就行了。代码如下
<?php// app/lib1.phpnamespace App\Lib1;class Controller{public function before(){echo 'lib1\'s before';}}
定义了一个Controller类,使用时:
<?phprequire 'lib/lib1.php';use App\Lib1\Controller;$c = new Controller();$c->before();// output: lib1's before
现在要有一个新的controller继承lib1.php的Controller,如下
<?phpnamespace App\Lib2;use App\Lib1;class Controller extends Lib1\Controller{public function before(){echo 'lib2\'s before';}}
使用时,只要将 use App\Lib1\Controller 改为 use App\Lib2\Controller 就行了
<?php// 可以通过设置autoload来解决require的问题require 'lib/lib1.php';require 'lib/lib2.php';use App\Lib2\Controller;$c = new Controller();$c->before();
是不是很方便
- 用php5.3的namespace实现类的无痛继承
- php5.3 使用namespace后性能比较及类、函数、静态方法的性能比较
- php5多重继承的bug
- 有效无痛的代码评审
- PHP5多层继承顺序的bug
- Namespace:Openstack的网络实现
- 陇南无痛引产真的不痛吗
- 无痛 SQL Schema 的10 条军规
- 无痛安装MS出品的android虚拟机
- 无痛的机器学习第一季目录
- php5类的使用
- php5.3 PHP5.4 PHP5.5 php5.6 新特性/使用PHP5.5/PHP5.6要注意的
- javascript实现namespace概念的方式
- PHP5.4以上更新的伪"多继承"--trait语法
- namespace的3种用法
- JavaScript实现类的继承
- JavaScript实现类的继承
- lua实现类的继承
- MTK平台驱动调试的资料(功能机)
- Oracle10g导入导出工具
- <FORM action=reg.asp?action=apply method=post> <INPUT type=submit value="请认真查看<服务条款和声明>(10
- Replacing container/vector in Go programs
- Hive UDF 报错
- 用php5.3的namespace实现类的无痛继承
- timer的延时和优化
- 女人,你凭什么不努力
- android studio最常用的快捷键
- Oil Deposits (搜索)
- hive 元数据为mysql安装
- qt 编译问题总结
- C#获取网页源码
- 菜鸟谈VS快捷键