class ClassA {
function __construct(ClassB $paramB) {
}
}
class ClassB {
function __construct(ClassA $paramA) {
}
}
Вопрос: как можно решить данную зависимость чтобы в результате выполнения было только 2 объекта без промежуточных или по другому чтобы в стеке вызова было только 2 этих конструктора.
Пропущу лекцию, почему так писать код нельзя, что сделать с архитектором такое сделавшим и сразу тогда уж напишу, как всё-таки выкрутиться можно.
Самое простое и читерское - через механизм Reflection
.
$r = new ReflectionClass('ClassA');
$a = $r->newInstanceWithoutConstructor();
$b = new ClassB($a);
$a->__construct($b);
ReflectionClass::newInstanceWithoutConstructor
доступен начиная с PHP 5.4 и позволяет получить объект класса без вызова конструктора. Разумеется, класс в этом случае может быть неработоспособным. В то же время конструктор является обычным методом класса, который возможно вызвать.
Конечно, возможна проблема, когда обоим конструкторам требуется корректно инициализированный класс параметра. В этом случае только вырвать руки автору и отрефакторить нормально.
Больше мороки, но так же возможно сделать через механизм сериализации. Результат serialize
- строка. unserialize
может восстановить объект. Строку же можно составить самостоятельно, зная как объекты сериализуются. Пример в комментариях к мануалу есть (процитирую для полноты ответа):
function createInstanceWithoutConstructor($class){
$reflector = new ReflectionClass($class);
$properties = $reflector->getProperties();
$defaults = $reflector->getDefaultProperties();
$serealized = "O:" . strlen($class) . ":\"$class\":".count($properties) .':{';
foreach ($properties as $property){
$name = $property->getName();
if($property->isProtected()){
$name = chr(0) . '*' .chr(0) .$name;
} elseif($property->isPrivate()){
$name = chr(0) . $class. chr(0).$name;
}
$serealized .= serialize($name);
if(array_key_exists($property->getName(),$defaults) ){
$serealized .= serialize($defaults[$property->getName()]);
} else {
$serealized .= serialize(null);
}
}
$serealized .="}";
return unserialize($serealized);
}
С корректировкой кода, вероятно, даже в PHP4 получится создать объект. Но не все классы возможно сериализовать и, соответственно, распаковать обратно.
Виртуальный выделенный сервер (VDS) становится отличным выбором
Сразу прошу прощения, если глупый вопрос, но я так и не понял, есть ли такое в yii2, и если есть - то как им пользоватьсяЧто я имею ввиду: есть такой...