1

我想对 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中有一个合理的范例来做到这一点吗?

4

1 回答 1

1

为什么不以与文件和行相同的方式设置跟踪和先前?

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);
    }
  }

编辑:

请参阅下面的评论,了解为什么我之前使用此代码逃脱了。

为什么不把你的 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...");
    }
}
于 2012-07-12T14:56:54.897 回答