2010-02-06 165 views
47

我有这段代码。 User对象构造函数有可能以某种方式失败,因此$this->LoggedUser被分配了一个NULL值,并且该对象在构造函数返回后被释放?PHP构造函数返回NULL

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

大顺便说一下第一个问题。 – 2010-02-06 21:20:35

+0

我见过一个流行的CMS,它在构造函数中返回FALSE。那是怎么回事?!?! – loungerdork 2011-10-31 03:17:27

+1

只是觉得我会在这里为了文档的缘故。由于日期还早,因此您所看到的CMS可能是为PHP4构建的。 PHP4用来允许很多不好的事情,其中​​最重要的是允许用户在命名构造函数中覆盖$ this(例如$ this = false)。 – techdude 2014-12-31 22:52:21

回答

62

假设你正在使用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设置为NUL L在构造函数中,但我认为从未被正式认可,并且“特征”最终被删除。

+4

+1 IMO,这是指示构建对象失败的正确OO方式。 – 2010-02-06 21:26:20

+1

这取决于失败的性质。如果这是一个例外,是的。如果构造函数的参数不符合标准,那么在我看来没有。 – 2010-02-06 21:35:01

+5

佩卡,我不确定什么样的“坏参数”不会是一个例外?如果你不能用一组特定的参数创建一个有效的对象,并且应该抛出异常?你能举个例子来澄清你所想的区别吗? (我看到你在下面的答案中做了,这在这里会很有用,但我不能编辑你的评论!) – 2012-05-14 11:01:01

11

AFAIK这不能完成,new将始终返回对象的一个​​实例。

我最常做的来解决这个:

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

  • 创建了执行new命令的封装功能,成功返回新的对象,如果失败,破坏了它,并返回false

-

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

我很想听听其他方法,但我不知道。

+0

谢谢澄清。 所以基本上我可以只是试试新的命令...捕获然后在构造函数中引发异常? – Tibor 2010-02-06 21:13:40

+1

好问题!我认为你*可以*,但它并不适合我。如果我使用“福特”模型创建对象汽车,则可能只是该数据库中没有该型号的汽车。这不是真正的*例外*是为什么设计的。这是更多的预期条件。我很想看看还有什么其他答案出现,什么被视为处理这个问题的“正确”方式。 – 2010-02-06 21:16:48

+0

这是在肮脏的方式做事情,检查@ jaz303的回答 – minhajul 2015-11-19 12:13:37

3

当构造函数由于某些未知原因而失败时,它不会返回NULL值或FALSE,但会引发异常。与使用PHP5的一切一样。如果你没有处理异常,那么脚本将停止执行,并带有未捕获异常错误。

+1

什么时候构造函数抛出异常?当它返回false?或者你的意思是,如果某个条件无法满足,构造函数应该抛出异常? – 2010-02-06 21:13:38

+1

你的构造函数应该抛出异常。 – Tom 2012-10-04 14:30:57

5

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

+0

这听起来最符合逻辑,是的。我刚刚开始使用PHP进行OO编程,因此我不完全确定如何以“正确”方式处理事情。 – Tibor 2010-02-06 21:22:42

3

也许是这样的:

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 
4

一个工厂可能是有用的位置:

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