【问题标题】:php typecast constructorphp 类型转换构造函数
【发布时间】:2012-07-12 08:33:16
【问题描述】:

我想对 PHP 异常进行类型转换。考虑以下代码:

class myException extends Exception {
  function __construct( $mOrigin = "", $iCode = 0, Exception $oPrevious = null){
    if(is_string($mOrigin)){
      parent::__construct($mOrigin, $iCode, $oPrevious);
    } elseif ($mOrigin instanceof Exception) {
      parent::__construct($mOrigin->getMessage(),$mOrigin->getCode(),$mOrigin->getPrevious());
      $this->file = $mOrigin->getFile();
      $this->line = $mOrigin->getLine();
    } else {
      parent::__construct("\$mOrigin has wrong type", self::eFatal, $oPrevious);
    }
  }

想法是将标准异常转换为 myException,保留 原始 堆栈跟踪。由于保存跟踪的变量是私有的,我无法立即复制这些值,CTOR 会为 myException 生成一个新值。

最初的想法当然是使用克隆,但我几乎无法重新分配 $this,可以吗?

所以我想做的是一个 C++ 风格的类型转换 CTOR。 PHP 中是否有合理的范例来执行此操作?

【问题讨论】:

    标签: php oop constructor clone


    【解决方案1】:

    为什么不直接设置 trace & previous 和 file & line 一样?

    class myException extends Exception {
      function __construct( $mOrigin = "", $iCode = 0, Exception $oPrevious = null){
        if(is_string($mOrigin)){
          parent::__construct($mOrigin, $iCode, $oPrevious);
        } elseif ($mOrigin instanceof Exception) {
          parent::__construct($mOrigin->getMessage(),$mOrigin->getCode(),$mOrigin->getPrevious());
          $this->file     = $mOrigin->getFile();
          $this->line     = $mOrigin->getLine();
          $this->trace    = $mOrigin->getTrace();
          $this->previous = $mOrigin->getPrevious();
        } else {
          parent::__construct("\$mOrigin has wrong type", self::eFatal, $oPrevious);
        }
      }
    

    编辑:

    请参阅下面的 cmets,了解为什么我之前没有使用此代码。

    为什么不把你的 myException 类变成一个装饰器:

    class myException extends Exception {
      private $_oException;
    
      function __construct( $mOrigin = "", $iCode = 0, Exception $oPrevious = null){
        if(is_string($mOrigin)){
          parent::__construct($mOrigin, $iCode, $oPrevious);
        } elseif ($mOrigin instanceof Exception) {
          $this->_oException = $mOrigin;
          parent::__construct($mOrigin->getMessage(),$mOrigin->getCode(),$mOrigin->getPrevious());
          $this->file     = $mOrigin->getFile();
          $this->line     = $mOrigin->getLine();
        } else {
          parent::__construct("\$mOrigin has wrong type", self::eFatal, $oPrevious);
        }
      }
    
      function getTrace()
      {
         return $this->_oException->getTrace();
      }
    
      function getPrevious()
      {
        return $this->_oException->getPrevious();
      }
    }
    

    更多信息:

    我对 php-general 进行了跟进,结果发现这是 预期的行为,它在 Java 等中也同样有效。您可以覆盖子类中的成员变量,并拥有一个单独的同名存储。这在java中编译得很好

    public class PrivateAccess
    {
        private Boolean isAccessible = true;
    
        public Boolean getAccessible()
        {
            return isAccessible;
        }
    }
    class PrivateAccessChild extends PrivateAccess
    {
        private Boolean isAccessible = false;
    
        public Boolean getAccessible()
        {
            return isAccessible;
        }
    
        public Boolean getParentAccessible()
        {
            return super.getAccessible();
        }
    
        public static void main(String[] args)
        {   
            PrivateAccessChild pAccess = new PrivateAccessChild();
    
            if(!pAccess.getAccessible())
                System.out.println("we're hitting the child here...");
    
            if(pAccess.getParentAccessible())
                System.out.println("we're hitting the parent here...");
    
            System.out.println("we're done here...");
        }
    }
    

    【讨论】:

    • 因为tracepreviousException私有
    • 很公平 - 奇怪的是,上面的代码运行时没有错误,甚至注意到error_reporting = E_ALL | E_STRICT,看看它是否适合你。
    • 天哪,看起来 PHP 在您尝试设置私有值时根本不会抱怨,就像您从子类调用私有方法时所做的那样......,我有另一个想法;我会在一分钟内发布。
    • LOL,经过进一步的实验,很明显您甚至可以使用 PHP 对私有成员变量的愚蠢处理作为一项功能。如果您在 myException 中为 getTrace 和 getPrevious 添加简单的 getter 方法,则原始代码将起作用。
    • 酷,我想我会和装饰者一起去。这应该会继续工作,即使他们有一天应该修复语言。非常感谢。
    猜你喜欢
    • 2016-02-22
    • 1970-01-01
    • 1970-01-01
    • 2015-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-21
    • 2019-04-06
    相关资源
    最近更新 更多