有没有办法阻止在其构造函数中创建对象,以便:
$object = new Foo();
echo $object; // outputs: NULL
答案 0 :(得分:14)
不,不可能;无论您尝试从构造函数返回什么,new
关键字始终都会返回指定类的实例。这是因为在调用构造函数时,PHP已经为新对象分配了内存。换句话说,对象在那时已经存在(否则,根本就没有对象可以调用构造函数)。
您可能会引发错误或从构造函数中抛出异常,并相应地处理它们。
class Foo {
public function __construct() {
throw new Exception('Could not finish constructing');
}
}
try {
$object = new Foo();
} catch (Exception $e) {
echo $e->getMessage();
}
答案 1 :(得分:3)
不可能,但你可以proxify the creation。
<?php
class Foo {
private function __construct() {}
static function factory($create=False) {
if ($create) {
return new Foo;
}
}
}
答案 2 :(得分:2)
简单地抛出异常:
throw new Exception('thou shalt not be born!');
答案 3 :(得分: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);
?>
如果您使用的是5.3.0之前的PHP版本,那么由于后期静态绑定和get_called_class()不可用,事情会变得复杂一些。但是,PHP 5确实支持反射,您可以使用它来模拟后期静态绑定。或者,您可以实现一个单独的工厂类并向其传递一个参数,告诉它要初始化的对象类型。
另一种方法是让构造函数在失败时抛出异常并使用catch块处理它。但是,如果你正在做很多事情,这种方法可能会变得多毛,而且它应该只在你通常期望对象创建成功时使用(换句话说,如果创建失败是一种特殊情况)。
工厂方法还有其他优点,例如它可以保存已经创建的对象的缓存,如果您尝试创建两次相同的对象,它只会传递一个已经初始化的对象的引用,而不是创建一个新的。这消除了对象创建中固有的内存和处理开销,尤其是在创建涉及时间密集型任务(如复杂的SQL查询)的情况下
答案 4 :(得分:0)
如果您尝试根据一些条件阻止对象实例化,那么为什么不在创建PHP new
之前创建一个条件并实例化该类?
我的意思是,在你的例子中说:
$object = new Foo();
echo $object; // outputs: NULL
你可以将它包装在一个为你进行验证工作的函数中,或者只是一个if语句,如果你只是要实例化一次类。
像这样:
if(conditions_to_meet){
$object = new Foo();
}
else $object = NULL;
如果你需要多次实例化,那么将它包装在一个函数中并将参数传递给你的类。
希望这有帮助。