Может ли конструктор не создавать объект?

Dovg

Продвинутый новичок
Может ли конструктор не создавать объект?

Хочется странного....

PHP:
if ($a = new A($somevars))
{

}
Конструктор что-то делает, если делает успешно, то объект создается, если нет, то нет
пробовал делать как написано в http://ru2.php.net/manual/ru/language.oop.constructor.php#30869
PHP:
class A
{
  function A()
  {
      // ...
      // some error occurred
      $this = null;
      return;  
  }
}

if ($a = new A())
{
  // success, use $a ...
}
Натыкаюсь на Fatal error: Cannot re-assign $this in ...

Подскажите, есть ли какое-нибудь решение, которое работало в PHP4; PHP5?
в комментариях пишут про запись состояния в какое-нибудь свойство класса и потом уже проверку его
в этом случае объект все равно создается, по другому нельзя?
 

Crazy

Developer
Re: Может ли конструктор не создавать объект?

Автор оригинала: Dovg
Хочется странного....
Именно. Не надо этого хотеть.

Нужно проектировать классы так, чтобы проблеме не возникала. Например, вспомнить про factory, которая может проверить все нужные условия и при необходимости отказаться от создания и просто вернуть null или кинуть исключение.

Это 2003 год. Возьми PHP того времени -- и будет работать. Только нафиг?
 

dark-demon

d(^-^)b
Crazy, а в чём принципиальная разница между фабрикой и умным конструктором?


Dovg, если создавать объект не через new, а через статическую функцию класса, то всё замечательно работает.

Код:
class a {
	function a() {
		echo 'object created ';
	}
	static function obj($b) {
		return $b ? new a() : null;
	}
}

var_dump(a::obj(1));
var_dump(a::obj(0));
 

Crazy

Developer
Автор оригинала: dark-demon
Crazy, а в чём принципиальная разница между фабрикой и умным конструктором?
Разве в моем предыдущем сообщении это не сказано? В том, что фабрика не пытается создавать экземпляр, если известно, что все равно не получится. В отличие от умного конструктора, который на полдороге начинает кричать "Shit happens!" и пытается сделать сеппуку.


если создавать объект не через new, а через статическую функцию класса, то всё замечательно работает.
Это чем-то отличается от того, что я предложил выше? :)
 

dark-demon

d(^-^)b
Crazy, да, под фабрикой обычно подразумевается что-то более универсальное. :)
а мой код - это скорее не фабрика, а один единственный конвеер ;)
 

Dovg

Продвинутый новичок
dark-demon
Crazy
Большое спасибо!
Сделал через статичную функцию.
 

Crazy

Developer
Автор оригинала: dark-demon
а мой код - это скорее не фабрика, а один единственный конвеер ;)
Твой код -- именно фабрика. Отдельная сущность, которой делегированы очень узкие права: создавать экземпляры объектов.
 

dark-demon

d(^-^)b
тогда, любой конструктор - это фабрика, которой делегированы очень узкие права: создавать экземпляры объектов. :)
 

demongloom

Новичок
Если в конструкторе скидывается exception то обьект не создается. Обрабатывать так:

class obj {
public function __construct($a) {
if(!$a) {
throw new exception("given not true", E_USER_WARNING);
} // if
} // function
} // class

try {
$v1 = new obj(true); // пройдет
$v2 = new obj(false); // будет исключение
} catch( exception $e ) {
echo $e->getMessage();
} // try

var_dump($v1);
var_dump($v2);
 

Crazy

Developer
demongloom, что в переменную не присваивается -- верю. Это очевидно.

А вот на счет "объект не создается" -- на момент кидания исключения он УЖЕ создан. Ага?
 

AnToXa

prodigy-одаренный ребенок
А вот на счет "объект не создается" -- на момент кидания исключения он УЖЕ создан. Ага?
ну строго говоря не совсем так :)
выделены ресурсы, но объект пока не создан, и не существует, начнется как только отработает ctor.
 

Crazy

Developer
AnToXa, я плохо знаю PHP5. Поэтому вопросы:

1. Могу ли я из конструктора вызывать нестатические методы этого объекта?
2. Могу ли я из конструктора передавать $this другим уже существующим объектам или присваивать в глобальные переменные?
 

AnToXa

prodigy-одаренный ребенок
Crazy
я тоже в общем-то нюасны пхп5 плохо знаю :)
я говорю с точки зрения "общей эрудиции".

1. скорее да чем нет.
2. да.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
картина Репина "приплыли" ... пациент скорее жив :)
создается, уже существует, на чем же registry и работает - и вопрос не в PHP :)

PHP:
class A{
function __construct() {
     ... 
     $GLOBALS['obj'][__CLASS__]=$this;
}
}
...
new A; //объект искать в $GLOBALS['obj']['A']
 

AnToXa

prodigy-одаренный ребенок
а теперь после присваивания globals ставим throw Exception(); или как там в пхп это, и привет :)
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Автор оригинала: AnToXa
а теперь после присваивания globals ставим throw Exception(); или как там в пхп это, и привет :)
что значит "и привет" - "всё-равно работает"? :)
PHP:
class A{
    public $x=1;
    function __construct() {
        $GLOBALS['obj'][__CLASS__]=$this;
        throw new Exception('',1);
    }
}//class end


try{
    new A();
}catch (Exception $E){
    echo $GLOBALS['obj']['A']->x;
}

echo $GLOBALS['obj']['A']->x;
вывод: 11
 

AnToXa

prodigy-одаренный ребенок
хм! значит в пхп объект существует уже до входа в конструктор, я, признаться, удивлен :)

значит был неправ, ага.

-~{}~ 10.06.07 22:31:

хотя до меня тут дошло, что в языках с автоматическим управлением памятью это естественная политика.
 
Сверху