从PHP5.4开始,PHP实现了代码复用的方法,这个方法被称为traits,这个功能用来解决PHP只支持单继承的问题。
举例来说,我们设计一个网站,它有不同的类,如用户(user)、页面(page)、文章(article)等。当我们开发时,如果有一个能够不去关心对象类型,每个类里都有一个调试方法,用来打印出一个指定对象的信息,那对我们的调试是非常有用的。
比如这个方法是这样定义的:
function myVarDump(){ //打印对象的信息 }
方法里的调试逻辑我省略了,你可以自行添加想实现的调试逻辑。
接下来我们需要在每个类中添加粘贴这个方法,但是这样做会造成不必要的代码冗余,而且一旦该方法的定义有更改,后面就需要修改很多东西。
通常情况下,当我们需要在多个不同类中使用同一个方法的时候,可使用include包含再静态引用,另外继承是一个不错的解决方案。
在PHP中,每个类只能单一继承,即每个类只能从一个父类继承,这样的话就不能为多个类指定同一个通用的父类。解决办法是有的,那就是现在介绍的traits。这个功能允许我们在不使用继承的情况下为一个类增加方法。
我们创建traits,要使用trait关键字,后面的命名和类名规范是相同的,加上命名和内容定义即可,如下代码清单2-34所示:
代码清单2-34 traits的定义
Trait examTrait{ //属性 function someFunction(){ //方法内容 } }
traits和抽象类、接口一样,不能从trait创建一个对象(继承)。我们需要另一个关键字use来在一个类中增加一个trait用例。代码如下:
class someClass{ use SomeTrait; //类的定义内容 }
就像在一个PHP脚本中使用include包含一个外部的PHP脚本就能使其马上生效一样,在这里增加一个use TraitName语句就可以使这个trait的代码在当前类生效。
现在,当我们创建了一个SomeClass类型的对象时,这个对象就有了someFunction()方法。
$obj = new SomeClass(); $obj -> someFunction();
在下列的示例程序中,我们将使用trait实现上述的调试程序,并且在一个类中使用trait。要实现这个功能,我们将使用3个函数,虽然在前面没有提及这3个函数,从函数名中也能看得出它们的各自作用。
下面我们新建一个PHP脚本,保存为tDebug.php。我们将在一个单独脚本中定义trait,在另一个脚本里引用对象。tDebug.php的代码清单如下:
代码清单2-35 tDebug.php脚本内容
<?php trait tDebug{ public function dumpObject(){ //取得类名称 $class = get_class($this); //取得属性 $attributes = get_object_vars($this); //取得方法 $attributes = get_object_vars($this); //打印头内容 echo “<h2>关于对象信息$class object</h2>”; //打印属性 echo “<h3>属性</h3>”; foreach($attribtes as $k=>$v){ echo “<li>$k : $v </li>”; } echo “</li></ul>”; //打印方法 echo “<h3>方法</h3>”; foreach($methods as $v){ echo “<li>$v </li>”; } echo “</li></ul>”; }//结束方法 }//结束一个trait定义