class ClassA { function __construct(ClassB $paramB) { } } class ClassB { function __construct(ClassA $paramA) { } } 

Question: how can this dependency be solved so that as a result of execution there were only 2 objects without intermediate or otherwise, that there were only 2 of these constructors in the call stack.

    1 answer 1

    I will skip the lecture, why it is impossible to write code like this, what to do with the architect who did this and immediately then I will write how you can still get out.

    The most simple and cheat - through the mechanism of Reflection .

     $r = new ReflectionClass('ClassA'); $a = $r->newInstanceWithoutConstructor(); $b = new ClassB($a); $a->__construct($b); 

    ReflectionClass::newInstanceWithoutConstructor is available starting from PHP 5.4 and allows you to get a class object without calling a constructor. Of course, the class in this case may be inoperable. At the same time, the constructor is the usual class method that can be called.

    Of course, there is a problem when both designers need a correctly initialized parameter class. In this case, just pull out the hands of the author and refactor normal.

    More hassle, but it is also possible to do it through the mechanism of serialization. The result of serialize is a string. unserialize can restore the object. You can make a string yourself, knowing how objects are serialized. An example in the comments to the manual is (I will quote for completeness of the answer):

     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); } 

    With the adjustment of the code, probably, even in PHP4 you will be able to create an object. But not all classes can be serialized and, accordingly, unpacked back.

    • but a small lecture would not hurt all the same :) Thanks for the cheat method - beautiful feint with your ears - rjhdby
    • This situation is fortunately not from my project, I found interesting solutions on github's open spaces) - Shadow33