【问题标题】:PHP constructor to return a NULLPHP构造函数返回一个NULL
【发布时间】:2010-02-06 21:03:46
【问题描述】:

我有这个代码。 User 对象构造函数是否有可能以某种方式失败,以便为 $this->LoggedUser 分配一个 NULL 值并在构造函数返回后释放该对象?

$this->LoggedUser = NULL;
if ($_SESSION['verbiste_user'] != false)
  $this->LoggedUser = new User($_SESSION['verbiste_user']);    

【问题讨论】:

  • 第一个问题很好。
  • 我见过某个流行的 CMS,它在构造函数中返回 FALSE。这是怎么回事?!?!
  • 只是想为了文档的缘故我会在这里插话。由于日期很早,您看到的 CMS 可能是为 PHP4 构建的。 PHP4 曾经允许很多不好的事情,其中​​最重要的是允许用户在命名构造函数中覆盖 $this(例如 $this = false)。

标签: php constructor error-handling null


【解决方案1】:

假设您使用的是 PHP 5,您可以在构造函数中抛出异常:

class NotFoundException extends Exception {}

class User {
    public function __construct($id) {
        if (!$this->loadById($id)) {
             throw new NotFoundException();
        }
    }
}

$this->LoggedUser = NULL;
if ($_SESSION['verbiste_user'] != false) {
    try {
        $this->LoggedUser = new User($_SESSION['verbiste_user']);
    } catch (NotFoundException $e) {}
}

为清楚起见,您可以将其包装在静态工厂方法中:

class User {
    public static function load($id) {
        try {
            return new User($id);
        } catch (NotFoundException $unfe) {
            return null;
        }
    }
    // class body here...
}

$this->LoggedUser = NULL;
if ($_SESSION['verbiste_user'] != false)
    $this->LoggedUser = User::load($_SESSION['verbiste_user']);

顺便说一句,PHP 4 的某些版本允许您在构造函数中将 $this 设置为 NULL,但我认为从未得到正式批准,并且最终删除了“功能”。

【讨论】:

  • +1 IMO,这是指示构造对象失败的正确OO方式。
  • 这取决于故障的性质。如果是例外,是的。如果构造函数的参数不符合标准,我认为没有。
  • Pekka,我不确定什么样的“错误参数”不会例外?如果您不能创建具有特定参数集的有效对象,那肯定是异常的,应该抛出异常吗?你能举一个例子来澄清你正在考虑的区别吗? (我看到你在下面的答案中这样做了,这在这里很有用,但我无法编辑你的评论!)
【解决方案2】:

AFAIK 无法做到这一点,new 将始终返回该对象的实例。

解决这个问题我通常做的是:

  • ->valid 布尔标志添加到确定对象是否已成功加载的对象。然后构造函数将设置标志

  • 创建一个执行new命令的包装函数,成功时返回新对象,失败时销毁它并返回false

-

function get_car($model)
      {
        $car = new Car($model);
        if ($car->valid === true) return $car; else return false;
     } 

我很想知道替代方法,但我不知道。

【讨论】:

  • 感谢您的澄清。所以基本上我可以将新命令包装在 try...catch 中,然后在构造函数中引发异常?
  • 好问题!我认为你可以,但我觉得这听起来不太对劲。如果我创建一个模型为“Ford”的对象汽车,则可能只是数据库中没有该型号的汽车。这并不是 exceptions 的真正目的。这更像是一种预期的情况。我很想看看还有什么其他答案,什么被视为处理这个问题的“正确”方式。
  • 这是在用肮脏的方式做事,检查@jaz303的回答
【解决方案3】:

这样考虑。当你使用new 时,你会得到一个新对象。时期。你正在做的是你有一个搜索现有用户的函数,并在找到时返回它。最好的表达方式可能是静态类函数,例如 User::findUser()。当您从基类派生类时,这也可以扩展。

【讨论】:

  • 这听起来最合乎逻辑,是的。我才刚刚开始使用 PHP 进行 OO 编程,所以我不完全确定如何以“正确”的方式处理事情。
【解决方案4】:

工厂可能在这里有用:

class UserFactory
{
    static public function create( $id )
    {
        return (
            filter_var( 
                $id,
                FILTER_VALIDATE_INT, 
                [ 'options' => [ 'min_range' => 1, ] ]
            )
                ? new User( $id )
                : null
        );
  }
}

【讨论】:

    【解决方案5】:

    当构造函数由于某种未知原因失败时,它不会返回 NULL 值或 FALSE,但会引发异常。与 PHP5 的一切一样。如果您不处理异常,则脚本将停止执行并出现未捕获异常错误。

    【讨论】:

    • 构造函数什么时候抛出异常?什么时候返回假?或者你的意思是,如果不能满足某个条件,构造函数应该抛出异常?
    • 你的构造函数应该抛出异常。
    【解决方案6】:

    可能是这样的:

    class CantCreateException extends Exception{
    }
    
    class SomeClass {
        public function __construct() {
           if (something_bad_happens) {
              throw ( new CantCreateException());
           }
        }
    }
    
    try{
      $obj = new SomeClass();
    }
    catch(CantCreateException $e){
       $obj = null;
    }
    if($obj===null) echo "couldn't create object";
    //jaz303 stole my idea an wrap it into a static method
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-04-11
      • 2021-07-20
      • 2012-12-03
      • 2016-08-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-20
      相关资源
      最近更新 更多