我有一个名为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
答案 0 :(得分:2)
您无法在PHP中使用__call magic覆盖私有方法。我允许自己引用php.net网站http://php.net/language.oop5.visibility#92995,你的问题在评论中得到了很好的回答:
在重写中,方法名称和参数(arg)必须是 相同。
无法覆盖最终方法。
私有方法永远不会参与覆盖因为 这些方法在子类中不可见。
- 醇>
虽然不允许覆盖递减访问说明符
如果您迫切需要此功能 - 您的(非常规)选项将是:
修改强>
请注意, protected 子方法也隐藏在父级中,但总是有一个选项可以覆盖子级中的__call()。一般来说,制作太多“神奇”的覆盖对于像ORM设计这样严肃的事情来说可能是一种不好的品味。
PS
我相信最终开发DSL可能是您项目的最终目标。在此之前,继续您的项目是收集各自经验的好方法。 GL!