Skip to content

Commit 08f859f

Browse files
[DependencyInjection][Config][Routing] Deprecate using $this or the internal scope of the loader from PHP config files
1 parent 942cea7 commit 08f859f

File tree

4 files changed

+35
-4
lines changed

4 files changed

+35
-4
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ CHANGELOG
1111
* Deprecate registering a service without a class when its id is a non-existing FQCN
1212
* Allow multiple `#[AsDecorator]` attributes
1313
* Handle returning arrays and config-builders from config files
14+
* Deprecate using `$this` or its internal scope from PHP config files; use the `$loader` variable instead
1415

1516
7.3
1617
---

Loader/PhpFileLoader.php

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,25 @@ public function load(mixed $resource, ?string $type = null): mixed
6161
class_exists(ContainerConfigurator::class);
6262

6363
// the closure forbids access to the private scope in the included file
64-
$load = \Closure::bind(function ($path, $env) use ($container, $loader, $resource, $type) {
64+
$load = \Closure::bind(static function ($path, $env) use ($container, $loader, $resource, $type) {
6565
return include $path;
66-
}, $this, ProtectedPhpFileLoader::class);
66+
}, null, null);
6767

6868
try {
69-
if (1 === $result = $load($path, $this->env)) {
70-
$result = null;
69+
try {
70+
if (1 === $result = $load($path, $this->env)) {
71+
$result = null;
72+
}
73+
} catch (\Error $e) {
74+
$load = \Closure::bind(function ($path, $env) use ($container, $loader, $resource, $type) {
75+
return include $path;
76+
}, $this, ProtectedPhpFileLoader::class);
77+
78+
if (1 === $result = $load($path, $this->env)) {
79+
$result = null;
80+
}
81+
82+
trigger_deprecation('symfony/dependency-injection', '8.1', 'Using `$this` or its internal scope in config files is deprecated, use the `$loader` variable instead in "%s" on line %d.', $e->getFile(), $e->getLine());
7183
}
7284

7385
if (\is_object($result) && \is_callable($result)) {
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<?php
2+
3+
// access the loader's internal scope to trigger deprecation
4+
$this->supports('dummy.php');

Tests/Loader/PhpFileLoaderTest.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
require_once __DIR__.'/../Fixtures/includes/fixture_app_services.php';
1616

1717
use PHPUnit\Framework\Attributes\DataProvider;
18+
use PHPUnit\Framework\Attributes\Group;
19+
use PHPUnit\Framework\Attributes\IgnoreDeprecations;
1820
use PHPUnit\Framework\TestCase;
1921
use Symfony\Component\Config\Builder\ConfigBuilderGenerator;
2022
use Symfony\Component\Config\FileLocator;
@@ -365,4 +367,16 @@ public function testReturnsGenerator()
365367
$loader->load('return_generator.php');
366368
$this->assertSame([['color' => 'red']], $container->getExtensionConfig('acme'));
367369
}
370+
371+
#[IgnoreDeprecations]
372+
#[Group('legacy')]
373+
public function testTriggersDeprecationWhenAccessingLoaderInternalScope()
374+
{
375+
$fixtures = realpath(__DIR__.'/../Fixtures');
376+
$loader = new PhpFileLoader(new ContainerBuilder(), new FileLocator($fixtures.'/config'));
377+
378+
$this->expectUserDeprecationMessageMatches('{^Since symfony/dependency-injection 8.1: Using \`\$this\` or its internal scope in config files is deprecated, use the \`\$loader\` variable instead in ".+" on line \d+\.$}');
379+
380+
$loader->load('legacy_internal_scope.php');
381+
}
368382
}

0 commit comments

Comments
 (0)