diff --git a/src/Symfony/Component/DependencyInjection/CHANGELOG.md b/src/Symfony/Component/DependencyInjection/CHANGELOG.md
index 3855313ccb8e8..f59ca78ef446c 100644
--- a/src/Symfony/Component/DependencyInjection/CHANGELOG.md
+++ b/src/Symfony/Component/DependencyInjection/CHANGELOG.md
@@ -6,6 +6,7 @@ CHANGELOG
* Deprecate `!tagged` tag, use `!tagged_iterator` instead
* Add a `ContainerBuilder::registerChild()` shortcut method for registering child definitions
+ * Add support for `key-type` in `XmlFileLoader`
7.1
---
diff --git a/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php b/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php
index 661f57d21ee3f..483aa069edbcd 100644
--- a/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php
+++ b/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php
@@ -534,6 +534,21 @@ private function getArgumentsAsPhp(\DOMElement $node, string $name, string $file
$key = $arg->getAttribute('key');
}
+ switch ($arg->getAttribute('key-type')) {
+ case 'binary':
+ if (false === $key = base64_decode($key, true)) {
+ throw new InvalidArgumentException(\sprintf('Tag "<%s>" with key-type="binary" does not have a valid base64 encoded key in "%s".', $name, $file));
+ }
+ break;
+ case 'constant':
+ try {
+ $key = \constant(trim($key));
+ } catch (\Error) {
+ throw new InvalidArgumentException(\sprintf('The key "%s" is not a valid constant in "%s".', $key, $file));
+ }
+ break;
+ }
+
$trim = $arg->hasAttribute('trim') && XmlUtils::phpize($arg->getAttribute('trim'));
$onInvalid = $arg->getAttribute('on-invalid');
$invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE;
diff --git a/src/Symfony/Component/DependencyInjection/Loader/schema/dic/services/services-1.0.xsd b/src/Symfony/Component/DependencyInjection/Loader/schema/dic/services/services-1.0.xsd
index c071e3466613c..befdb658f38ef 100644
--- a/src/Symfony/Component/DependencyInjection/Loader/schema/dic/services/services-1.0.xsd
+++ b/src/Symfony/Component/DependencyInjection/Loader/schema/dic/services/services-1.0.xsd
@@ -270,6 +270,7 @@
+
@@ -315,6 +316,7 @@
+
@@ -365,6 +367,13 @@
+
+
+
+
+
+
+
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/key_type_argument.xml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/key_type_argument.xml
new file mode 100644
index 0000000000000..f95430eac0d6b
--- /dev/null
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/key_type_argument.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+ Value 1
+ Value 2
+ Value 3
+
+
+
+
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/key_type_incorrect_bin.xml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/key_type_incorrect_bin.xml
new file mode 100644
index 0000000000000..41ba1f0bc8650
--- /dev/null
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/key_type_incorrect_bin.xml
@@ -0,0 +1,8 @@
+
+
+
+
+ Value 3
+
+
+
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/key_type_property.xml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/key_type_property.xml
new file mode 100644
index 0000000000000..597d8e289fce5
--- /dev/null
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/key_type_property.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+ Value 1
+ Value 2
+ Value 3
+
+
+
+
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/key_type_wrong_constant.xml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/key_type_wrong_constant.xml
new file mode 100644
index 0000000000000..34eab6a309a42
--- /dev/null
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/key_type_wrong_constant.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+ Value 1
+
+
+
+
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php b/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php
index 11ac19595d315..e17f1a9d3d11c 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php
@@ -1280,6 +1280,54 @@ public function testStaticConstructorWithFactoryThrows()
$loader->load('static_constructor_and_factory.xml');
}
+ public function testArgumentKeyType()
+ {
+ $container = new ContainerBuilder();
+ $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
+ $loader->load('key_type_argument.xml');
+
+ $definition = $container->getDefinition('foo');
+ $this->assertSame([
+ \PHP_INT_MAX => 'Value 1',
+ 'PHP_INT_MAX' => 'Value 2',
+ "\x01\x02\x03" => 'Value 3',
+ ], $definition->getArgument(0));
+ }
+
+ public function testPropertyKeyType()
+ {
+ $container = new ContainerBuilder();
+ $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
+ $loader->load('key_type_property.xml');
+
+ $definition = $container->getDefinition('foo');
+ $this->assertSame([
+ \PHP_INT_MAX => 'Value 1',
+ 'PHP_INT_MAX' => 'Value 2',
+ "\x01\x02\x03" => 'Value 3',
+ ], $definition->getProperties()['quz']);
+ }
+
+ public function testInvalidBinaryKeyType()
+ {
+ $container = new ContainerBuilder();
+ $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
+
+ $this->expectException(InvalidArgumentException::class);
+ $this->expectExceptionMessage(\sprintf('Tag "" with key-type="binary" does not have a valid base64 encoded key in "%s".', self::$fixturesPath.'/xml/key_type_incorrect_bin.xml'));
+ $loader->load('key_type_incorrect_bin.xml');
+ }
+
+ public function testUnknownConstantAsKey()
+ {
+ $container = new ContainerBuilder();
+ $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
+
+ $this->expectException(InvalidArgumentException::class);
+ $this->expectExceptionMessage(\sprintf('The key "PHP_Unknown_CONST" is not a valid constant in "%s".', self::$fixturesPath.'/xml/key_type_wrong_constant.xml'));
+ $loader->load('key_type_wrong_constant.xml');
+ }
+
/**
* @group legacy
*/