尚方宝剑之说
我首先要说的是,我不太清楚为什么使用包含方法的基类,包含数据的子类和动态类加载不能最好地解决这个问题。我假设你有充分的理由。一旦您的提供商支持PHP 5.4,您就可以使用特征做您想做的事情。代码文件:if ($pet === 'dog') include 'dog.php';elseif ($pet === 'cat') include 'cat.php';else die('Unknown pet');class Pet {
use PetSounds;}$myPet = new Pet();$myPet->speak();文件cat.phptrait PetSounds {
function speak() { echo 'meow'; }}文件dog.phptrait PetSounds {
function speak() { echo 'woof'; }}您可以通过将两个包含文件命名为相同,将它们放在不同的子目录中,并使用set_include_path()或定义__autoload()函数来在它们之间进行选择,从而使其更加清晰。就像我说的那样,使用继承可以更好地解决同样的问题。如果您有多重继承类型问题,例如,如果您有四种宠物,五种颜色和三种头发类型,并且您需要为60个不同类别中的每一种提供不同的方法组合,这是正确的解决方案。5.4目前只是一个候选版本(截至2012年2月24日),甚至一旦发布,大多数主机将不会支持它好几个月 - 我们发布5.3版本之前需要18个月才能支持它。在此之前,您必须编写完全独立且完整的类文件。但是,您可以根据特征的最终更改来设置类的格式。现在,您可以使用魔术方法部分获得所需内容,并在可用时轻松升级到特征。代码文件:if ($pet === 'dog') include 'dog.php';elseif ($pet === 'cat') include 'cat.php';else die('Unknown pet');class Pet {
public function __call($name, array $arguments)
{
array_unshift($arguments, $this);
return call_user_func_array("TraitFunc_$name", $arguments);
}}$myPet = new Pet();$myPet->speak();文件cat.phpfunction TraitFunc_speak(Pet $that) { echo 'meow'; }文件dog.phpfunction TraitFunc_speak(Pet $that) { echo 'woof'; }但是您受到限制,因为您的函数无法访问私有和受保护的类属性和方法,并且您无法使用此方法来提供诸如__get()之类的魔术方法。特征将解决这两个限制。