Skip to content

Commit f64a924

Browse files
[12.x] Cache Singleton/Scoped attribute checks (#56633)
* wip * flush * fix logic * name * name * formatting --------- Co-authored-by: Taylor Otwell <[email protected]>
1 parent 5521c5e commit f64a924

File tree

1 file changed

+32
-8
lines changed

1 file changed

+32
-8
lines changed

src/Illuminate/Container/Container.php

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,13 @@ class Container implements ArrayAccess, ContainerContract
130130
*/
131131
protected $checkedForAttributeBindings = [];
132132

133+
/**
134+
* Whether a class has already been checked for Singleton or Scoped attributes.
135+
*
136+
* @var array<class-string, "scoped"|"singleton"|null>
137+
*/
138+
protected $checkedForSingletonOrScopedAttributes = [];
139+
133140
/**
134141
* All of the registered rebound callbacks.
135142
*
@@ -281,7 +288,7 @@ public function isShared($abstract)
281288
return false;
282289
}
283290

284-
if (($scopedType = $this->getScopedTyped(new ReflectionClass($abstract))) === null) {
291+
if (($scopedType = $this->getScopedTyped($abstract)) === null) {
285292
return false;
286293
}
287294

@@ -297,20 +304,36 @@ public function isShared($abstract)
297304
/**
298305
* Determine if a ReflectionClass has scoping attributes applied.
299306
*
300-
* @param ReflectionClass<object> $reflection
307+
* @param ReflectionClass<object>|class-string $reflection
301308
* @return "singleton"|"scoped"|null
302309
*/
303-
protected function getScopedTyped(ReflectionClass $reflection): ?string
310+
protected function getScopedTyped(ReflectionClass|string $reflection): ?string
304311
{
305-
if (! empty($reflection->getAttributes(Singleton::class))) {
306-
return 'singleton';
312+
$className = $reflection instanceof ReflectionClass
313+
? $reflection->getName()
314+
: $reflection;
315+
316+
if (array_key_exists($className, $this->checkedForSingletonOrScopedAttributes)) {
317+
return $this->checkedForSingletonOrScopedAttributes[$className];
307318
}
308319

309-
if (! empty($reflection->getAttributes(Scoped::class))) {
310-
return 'scoped';
320+
try {
321+
$reflection = $reflection instanceof ReflectionClass
322+
? $reflection
323+
: new ReflectionClass($reflection);
324+
} catch (ReflectionException) {
325+
return $this->checkedForSingletonOrScopedAttributes[$className] = null;
326+
}
327+
328+
$type = null;
329+
330+
if (! empty($reflection->getAttributes(Singleton::class))) {
331+
$type = 'singleton';
332+
} elseif (! empty($reflection->getAttributes(Scoped::class))) {
333+
$type = 'scoped';
311334
}
312335

313-
return null;
336+
return $this->checkedForSingletonOrScopedAttributes[$className] = $type;
314337
}
315338

316339
/**
@@ -1753,6 +1776,7 @@ public function flush()
17531776
$this->abstractAliases = [];
17541777
$this->scopedInstances = [];
17551778
$this->checkedForAttributeBindings = [];
1779+
$this->checkedForSingletonOrScopedAttributes = [];
17561780
}
17571781

17581782
/**

0 commit comments

Comments
 (0)