在函数覆盖中不抛出异常


php not throwing an Exception in function overriding

我有一个名为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,你的问题在评论中得到了完美的回答:

  1. 在重写中,方法名和参数(arg 's)必须是相同。

  2. final方法不能被重写

  3. 私有方法从不参与重写,因为这些方法在子类中不可见。

  4. 不允许重写递减访问说明符

如果你迫切需要这个功能-你的(非常规的)选项将是:

  1. 为方法使用公共作用域,在PHPDoc字符串中为其他开发人员记录其限制的功能。你可以使用PECL扩展,如runkit sandbox http://php.net/book.runkit
  2. 选择代码生成或预处理器。
  3. 选择不同的语言

编辑

注意,protected子方法也对父方法隐藏,但总是有一个在子方法中重写__call()的选项。一般来说,对于像ORM这样严肃的设计来说,制作太多"神奇的"重写可能是不好的。

p>

相信最终开发一个DSL可能是您项目的最终目标。在此之前,继续您的项目是收集各自经验的好方法。GL !