我有一个名为DataBoundObject
的类,它非常大。而且效果很好。这是我开发的ORM类。它的一个功能是自动执行setXXX()和getXXX()函数,因此不需要编码。下面的函数完成
public function __call($strFunction, $arArguments) {
$strMethodType = substr ( $strFunction, 0, 3 );
$strMethodMember = substr ( $strFunction, 3 );
if(!is_callable(array($this, $strFunction)))
throw new Exception("Function cannot be called!");
switch ($strMethodType) {
case "set" :
return ($this->SetAccessor ( $strMethodMember, $arArguments [0] ));
break;
case "get" :
return ($this->GetAccessor ( $strMethodMember ));
break;
default :
throw new Exception ( "Non existent method call dude!" );
}
return false;
}
现在在派生这个的类中,我像这样重写一个函数:
<?php
require_once ('DataBoundObject.php');
/**
* ORM extension of BUBBLES_HOTEL_REVIEWS Tabel
* @author footy
* @copyright Ajitah
*
*/
class reviews extends DataBoundObject {
protected $ReviewID;
//Other codes
private function setReviewID($ReviewID) {
throw new Exception ( "Cannot set the review ID Explicitly" );
}
//Other codes
//Other codes
//Other codes
//Other codes
//Other codes
}
$x = new reviews();
$x->setReviewID(5);
?>
因此,最后我创建了一个新对象,并尝试调用setReviewID()
函数,这是私有的。为什么不产生任何Exception
?何况is_callable()
还真!
编辑
主要是我需要帮助纠正这个问题,使它抛出一个Exception
你不能在PHP中使用__call magic重写private方法。我允许自己引用php.net网站http://php.net/language.oop5.visibility#92995,你的问题在评论中得到了完美的回答:
在重写中,方法名和参数(arg 's)必须是相同。
final方法不能被重写
私有方法从不参与重写,因为这些方法在子类中不可见。
不允许重写递减访问说明符
如果你迫切需要这个功能-你的(非常规的)选项将是:
- 为方法使用公共作用域,在PHPDoc字符串中为其他开发人员记录其限制的功能。你可以使用PECL扩展,如runkit sandbox http://php.net/book.runkit 选择代码生成或预处理器。
- 选择不同的语言
编辑
注意,protected子方法也对父方法隐藏,但总是有一个在子方法中重写__call()的选项。一般来说,对于像ORM这样严肃的设计来说,制作太多"神奇的"重写可能是不好的。
p>
相信最终开发一个DSL可能是您项目的最终目标。在此之前,继续您的项目是收集各自经验的好方法。GL !