@@ -48,13 +48,12 @@ class <proxyShortClassName> extends \<className> implements \<baseProxyInterface
4848{
4949 <useLazyGhostTrait>
5050
51- /**
52- * @internal
53- */
54- public bool $__isCloning = false;
55-
56- public function __construct(?\Closure $initializer = null)
51+ public function __construct(?\Closure $initializer = null, ?\Closure $cloner = null)
5752 {
53+ if ($cloner !== null) {
54+ return;
55+ }
56+
5857 self::createLazyGhost($initializer, <skippedProperties>, $this);
5958 }
6059
@@ -63,17 +62,6 @@ public function __isInitialized(): bool
6362 return isset($this->lazyObjectState) && $this->isLazyObjectInitialized();
6463 }
6564
66- public function __clone()
67- {
68- $this->__isCloning = true;
69-
70- try {
71- $this->__doClone();
72- } finally {
73- $this->__isCloning = false;
74- }
75- }
76-
7765 public function __serialize(): array
7866 {
7967 <serializeImpl>
@@ -98,6 +86,9 @@ public function __serialize(): array
9886 */
9987 private $ identifierFlattener ;
10088
89+ /** @var ProxyDefinition[] */
90+ private $ definitions = [];
91+
10192 /**
10293 * Initializes a new instance of the <tt>ProxyFactory</tt> class that is
10394 * connected to the given <tt>EntityManager</tt>.
@@ -131,6 +122,26 @@ public function __construct(EntityManagerInterface $em, $proxyDir, $proxyNs, $au
131122 $ this ->identifierFlattener = new IdentifierFlattener ($ this ->uow , $ em ->getMetadataFactory ());
132123 }
133124
125+ /**
126+ * {@inheritDoc}
127+ */
128+ public function getProxy ($ className , array $ identifier )
129+ {
130+ $ proxy = parent ::getProxy ($ className , $ identifier );
131+
132+ if (! $ this ->em ->getConfiguration ()->isLazyGhostObjectEnabled ()) {
133+ return $ proxy ;
134+ }
135+
136+ $ initializer = $ this ->definitions [$ className ]->initializer ;
137+
138+ $ proxy ->__construct (static function (Proxy $ object ) use ($ initializer , $ proxy ): void {
139+ $ initializer ($ object , $ proxy );
140+ });
141+
142+ return $ proxy ;
143+ }
144+
134145 /**
135146 * {@inheritDoc}
136147 */
@@ -158,7 +169,7 @@ protected function createProxyDefinition($className)
158169 $ cloner = $ this ->createCloner ($ classMetadata , $ entityPersister );
159170 }
160171
161- return new ProxyDefinition (
172+ return $ this -> definitions [ $ className ] = new ProxyDefinition (
162173 ClassUtils::generateProxyClassName ($ className , $ this ->proxyNs ),
163174 $ classMetadata ->getIdentifierFieldNames (),
164175 $ classMetadata ->getReflectionProperties (),
@@ -231,15 +242,15 @@ private function createInitializer(ClassMetadata $classMetadata, EntityPersister
231242 /**
232243 * Creates a closure capable of initializing a proxy
233244 *
234- * @return Closure(Proxy):void
245+ * @return Closure(Proxy, Proxy ):void
235246 *
236247 * @throws EntityNotFoundException
237248 */
238249 private function createLazyInitializer (ClassMetadata $ classMetadata , EntityPersister $ entityPersister ): Closure
239250 {
240- return function (Proxy $ proxy ) use ($ entityPersister , $ classMetadata ): void {
241- $ identifier = $ classMetadata ->getIdentifierValues ($ proxy );
242- $ entity = $ entityPersister ->loadById ($ identifier , $ proxy -> __isCloning ? null : $ proxy );
251+ return function (Proxy $ proxy, Proxy $ original ) use ($ entityPersister , $ classMetadata ): void {
252+ $ identifier = $ classMetadata ->getIdentifierValues ($ original );
253+ $ entity = $ entityPersister ->loadById ($ identifier , $ original );
243254
244255 if ($ entity === null ) {
245256 throw EntityNotFoundException::fromClassNameAndIdentifier (
@@ -248,7 +259,7 @@ private function createLazyInitializer(ClassMetadata $classMetadata, EntityPersi
248259 );
249260 }
250261
251- if (! $ proxy-> __isCloning ) {
262+ if ($ proxy === $ original ) {
252263 return ;
253264 }
254265
@@ -315,15 +326,14 @@ private function generateUseLazyGhostTrait(ClassMetadata $class): string
315326 isLazyObjectInitialized as private;
316327 createLazyGhost as private;
317328 resetLazyObject as private;
318- __clone as private __doClone;
319329 } ' ), $ code );
320330
321331 return $ code ;
322332 }
323333
324334 private function generateSkippedProperties (ClassMetadata $ class ): string
325335 {
326- $ skippedProperties = [' __isCloning ' => true ];
336+ $ skippedProperties = [];
327337 $ identifiers = array_flip ($ class ->getIdentifierFieldNames ());
328338 $ filter = ReflectionProperty::IS_PUBLIC | ReflectionProperty::IS_PROTECTED | ReflectionProperty::IS_PRIVATE ;
329339 $ reflector = $ class ->getReflectionClass ();
0 commit comments