php不会在函数覆盖中抛出异常

时间:2011-07-20 09:49:48

标签: php oop override class-design

我有一个名为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

1 个答案:

答案 0 :(得分:2)

您无法在PHP中使用__call magic覆盖私有方法。我允许自己引用php.net网站http://php.net/language.oop5.visibility#92995,你的问题在评论中得到了很好的回答:

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

  2.   
  3. 无法覆盖最终方法。

  4.   
  5. 私有方法永远不会参与覆盖因为   这些方法在子类中不可见。

  6.   
  7. 虽然不允许覆盖递减访问说明符

  8.   

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

  1. 使用方法的公共范围,在PHPDoc字符串中记录其对其他开发人员的限制功能。
  2. 您可以使用PECL扩展程序,例如 runkit sandbox http://php.net/book.runkit
  3. 转到代码生成或预处理器。
  4. 选择其他语言。
  5. 修改

    请注意, protected 子方法也隐藏在父级中,但总是有一个选项可以覆盖子级中的__call()。一般来说,制作太多“神奇”的覆盖对于像ORM设计这样严肃的事情来说可能是一种不好的品味。

    PS

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