2011-01-26 61 views
5

有没有一种方法,以防止它的构造函数中创建对象,因此:打破构造

$object = new Foo(); 
echo $object; // outputs: NULL 
+0

[PHP构造函数返回NULL。]的可能的重复(http://stackoverflow.com/questions/2214724/php-constructor-to-return-a-null) – 2011-01-26 11:12:58

回答

13

不,不可能的; new关键字总是返回指定类的实例,无论您尝试从构造函数返回什么。这是因为在调用构造函数时,PHP已经完成为新对象分配内存。换句话说,该对象已经存在于此点(否则,根本就没有对象可以调用构造函数)。

您可以引发错误或从构造函数中抛出异常,并相应地处理这些异常。

class Foo { 
    public function __construct() { 
     throw new Exception('Could not finish constructing'); 
    } 
} 

try { 
    $object = new Foo(); 
} catch (Exception $e) { 
    echo $e->getMessage(); 
} 
2

简单地抛出一个异常:

throw new Exception('thou shalt not be born!'); 
+0

这不会阻止对象从存在创建。 – 2011-01-26 11:12:08

+0

啊哈!有趣的+1! – Tivie 2012-07-23 00:49:32

1

你可以实现一个工厂来为你做对象创建。如果您使用的是PHP 5.3.0以上版本,那么您将可以访问一个名为Late Static Binding的功能,从而使这一切变得简单。

<?php 
class MyObject 
{ 
    protected $loadSuccess = false; 

    protected function __construct ($foo, $bar, $baz) 
    { 
     // Just a random 50/50 success probability. Put real logic for testing success here 
     $this -> loadSuccess = (mt_rand (0, 99) > 49); 
    } 

    static public function factory ($foo, $bar, $baz) 
    { 
     $objClass = get_called_class(); 
     $obj = new $objClass ($foo, $bar, $baz); 
     if ($obj -> loadSuccess) 
     { 
      return ($obj); 
     } 
    } 
} 

class MySubClass extends MyObject 
{ 
    protected function __construct ($foo, $bar, $baz) 
    { 
     parent::__construct ($foo, $bar, $baz); 
     if ($this -> loadSuccess) 
     { 
      echo ('Hello, I\'m a ' . get_called_class() . '<br>'); 
     } 
    } 
} 

class MySubSubClass extends MySubClass 
{ 
    protected function __construct ($foo, $bar, $baz) 
    { 
     parent::__construct ($foo, $bar, $baz); 
     if ($this -> loadSuccess) 
     { 
      echo ($foo * $bar * $baz . '<br>'); 
     } 
    } 
} 

$o1 = MyObject::factory (1, 2, 3); // Base class 
$o2 = MySubClass::factory (4, 5, 6); // Child class 
$o3 = MySubSubClass::factory(7, 8, 9); // Descendent class 

var_dump ($o1); 
var_dump ($o2); 
var_dump ($o3); 
?> 

如果您使用的是PHP版本的5.3.0版本之前然后事情变得有点复杂迟静态绑定和get_called_class()不可用。但是,PHP 5支持反射,您可以使用它来模拟晚期静态绑定。或者,你可以实现一个单独的工厂类,并向它传递一个参数,告诉它你想要初始化什么样的对象。

另一种方法是让你的构造函数在失败时抛出异常,并用catch块处理它。然而,如果你做了很多事情,这种方法会变得多毛,只有当你通常期望对象创建成功时(换句话说,如果创建失败是一种特殊情况),这种方法才会被使用。

工厂方法有其他优点,例如它可以容纳已经创建的对象的缓存,并且如果您尝试两次创建相同的对象,它只会向您传递一个引用已经初始化的对象,而不是创造一个新的。这消除了对象创建时固有的内存和处理开销,尤其是在创建过程涉及诸如复杂SQL查询之类的时间密集型任务时。

0

如果尝试根据几个条件停止实例化对象,那么为什么不创建一个条件之前,你甚至打PHP new并实例化类?

我的意思是,说在你的榜样:

$object = new Foo(); 
echo $object; // outputs: NULL 

你可以在做验证工作,对您或只是简单的if语句,如果你只是要实例化的类,一旦一个函数把它包。

像这样:

if(conditions_to_meet){ 
    $object = new Foo(); 
} 
else $object = NULL; 

,如果您需要到多次实例化,然后在一个函数把它包装和参数传递给你的类。

希望这会有所帮助。