Хорошо, я заинтересовался этим вопросом, потому что достиг той точки, когда я хотел бы узнать точные пределы PHP, включая такие маленькие хаки. Надеюсь, я буду иметь смысл так поздно ночью и немного пива во мне. Из-за уродливого хакерства я действительно ожидаю, что меня отвергнут.
Очевидно, что вы не можете сделать $this = $that
. Вы также не можете изменить глобальную переменную, которую вы сейчас пытаетесь превратить в объект, пока он создается, и попытка сделать это будет проигнорирована. Как Чарльз сказал ранее, это не может быть разумно сделано. Не с clone
, не serialize()
, ничего внутри __construct()
.
Таким образом, необоснованно, если вы хотите, чтобы $ a сначала стал объектом класса A, а затем преобразовать промежуточное создание в класс B, попробуйте этот псевдо-метод: вам придется вызывать __construct класса A два раза подряд. Первый раз обработать конструкцию класса A. Второй раз завершить объект, преобразовав его в класс B. Класс A обрабатывает первую половину конструкции, а класс B - вторую:
class A {
function __construct() {
$args = func_get_args(); // just to tell us the first round of __construct already occured
if (array_key_exists(0, $args) AND $args[0]) {
$GLOBALS['a'] = new B($GLOBALS['a']);
// stop because "reconstruction" has stopped. Nothing else you can do to $a in this scope.
$this->aprop2 = "yay";
// Seriously, stop. Don't bother putting more code at this point, you're wasting your time. Consider $a 'converted and returned' already.
}
// build on an object of class a here
}
}
class B {
function __construct($var) {
// maybe you'd like to do something with old $a? If so, here's $var for you
// continue constructing where A left off.
}
}
$a = new A(); // object of class A
$a->__construct(true); // object of class B
Может быть, вместо этого сделать другой метод класса A с более важным звучанием, который делает то же самое для преобразования глобального $ a в объект класса B, просто чтобы он не выглядел так глупо, как мой пример. Другими словами, вы, вероятно, уже делаете это настолько хорошо, насколько позволяет PHP.
Редактировать: На самом деле вышеприведенное - не более чем $a = new A(); $a = new B($a);
. Для лучшей читаемости и удобства сопровождения кода вы можете не использовать мой пример и вместо этого выбрать реализацию класса фабрики или обработчика, который создает и манипулирует этими объектами для вас. Я нашел краткую и проницательную статью www.ibm.com , объясняющую концепцию фабрик, как они применяются в PHP. Может быть концептуально, вам нужен статический класс, который действует как CD-чейнджер, и именно здесь Return by Reference - для работы с переменной ссылкой на объект в любой области видимости - и Variable Objects (см. комментарии midir на этой странице) - для динамической установки или работы с объектом - удобно.