<p dir="auto"><strong>Bug description</strong>: when using the built-in PropertyAccessor service, accessing an array property containing <code class="notranslate">/</code> in its key throws an error.</p>
<p dir="auto"><strong>Example</strong></p>
<ul dir="auto">
<li>in a standalone <code class="notranslate">bin/test.php</code> file, in a working Symfony instance</li>
</ul>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="&lt;?php
$loader = require __DIR__.'/../vendor/autoload.php';

$kernel = new AppKernel('dev', true);
$kernel-&gt;boot();

var_dump($kernel-&gt;getContainer()-&gt;get('property_accessor')-&gt;getValue(['a/b' =&gt; 'ok'], '[a/b]'));"><pre class="notranslate"><code class="notranslate">&lt;?php
$loader = require __DIR__.'/../vendor/autoload.php';

$kernel = new AppKernel('dev', true);
$kernel-&gt;boot();

var_dump($kernel-&gt;getContainer()-&gt;get('property_accessor')-&gt;getValue(['a/b' =&gt; 'ok'], '[a/b]'));
</code></pre></div>
<ul dir="auto">
<li>execution and stack</li>
</ul>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="$ php bin/test.php
PHP Fatal error:  Uncaught Symfony\Component\Cache\Exception\InvalidArgumentException: Cache key &quot;p[a/b]&quot; contains reserved characters {}()/\@: in /var/www/current/vendor/symfony/symfony/src/Symfony/Component/Cache/CacheItem.php:162
Stack trace:
#0 /var/www/current/vendor/symfony/symfony/src/Symfony/Component/Cache/Traits/ArrayTrait.php(45): Symfony\Component\Cache\CacheItem::validateKey('p[a/b]')
#1 /var/www/current/vendor/symfony/symfony/src/Symfony/Component/Cache/Adapter/ArrayAdapter.php(56): Symfony\Component\Cache\Adapter\ArrayAdapter-&gt;hasItem('p[a/b]')
#2 /var/www/current/vendor/symfony/symfony/src/Symfony/Component/PropertyAccess/PropertyAccessor.php(875): Symfony\Component\Cache\Adapter\ArrayAdapter-&gt;getItem('p[a/b]')
#3 /var/www/current/vendor/symfony/symfony/src/Symfony/Component/PropertyAccess/PropertyAccessor.php(160): Symfony\Component\PropertyAccess\PropertyAccessor-&gt;getPropertyPath('[a/b]')
#4 /var/www/current/bin/test.php(8): Symfony\Component\PropertyAccess\PropertyAccessor-&gt;getValue(Array, '[a/b]')
#5 {main} in /var/www/current/vendor/symfony/symfony/src/Symfony/Component/Cache/CacheItem.php on line 162"><pre class="notranslate"><code class="notranslate">$ php bin/test.php
PHP Fatal error:  Uncaught Symfony\Component\Cache\Exception\InvalidArgumentException: Cache key "p[a/b]" contains reserved characters {}()/\@: in /var/www/current/vendor/symfony/symfony/src/Symfony/Component/Cache/CacheItem.php:162
Stack trace:
#0 /var/www/current/vendor/symfony/symfony/src/Symfony/Component/Cache/Traits/ArrayTrait.php(45): Symfony\Component\Cache\CacheItem::validateKey('p[a/b]')
#1 /var/www/current/vendor/symfony/symfony/src/Symfony/Component/Cache/Adapter/ArrayAdapter.php(56): Symfony\Component\Cache\Adapter\ArrayAdapter-&gt;hasItem('p[a/b]')
#2 /var/www/current/vendor/symfony/symfony/src/Symfony/Component/PropertyAccess/PropertyAccessor.php(875): Symfony\Component\Cache\Adapter\ArrayAdapter-&gt;getItem('p[a/b]')
#3 /var/www/current/vendor/symfony/symfony/src/Symfony/Component/PropertyAccess/PropertyAccessor.php(160): Symfony\Component\PropertyAccess\PropertyAccessor-&gt;getPropertyPath('[a/b]')
#4 /var/www/current/bin/test.php(8): Symfony\Component\PropertyAccess\PropertyAccessor-&gt;getValue(Array, '[a/b]')
#5 {main} in /var/www/current/vendor/symfony/symfony/src/Symfony/Component/Cache/CacheItem.php on line 162
</code></pre></div>
<p dir="auto"><strong>Analysis</strong><br>
The PropertyAccessor component uses a standard PSR6 cache to increase it's performance, but the key is validated by <code class="notranslate">Symfony\Component\Cache\CacheItem::validateKey</code>, and some characters are forbidden. The problem is that any of those characters are allowed as an array key (<a href="http://php.net/manual/en/language.types.array.php" rel="nofollow">source</a>). It means some properties can never be accessed through the property accessor.</p>
<p dir="auto">As a quick workaround, we will disable the cache.</p>
<p dir="auto">Side note: an empty array key is also not reachable (even if it's certainly a bad practice...)</p>
<p dir="auto"><strong>Resolution proposals</strong></p>
<ul dir="auto">
<li>Hash the key (but should it be protected against collisions with a mapping ?)</li>
<li>Catch the cache component error, add a warning and skip caching for those property (not ideal, but a quick and safe solution...)</li>
<li>Find a way to escape those characters</li>
</ul>
<p dir="auto"><strong>Context</strong></p>
<ul dir="auto">
<li>Symfony 3.4</li>
<li>PHP 7.2</li>
</ul>
<p dir="auto"><strong>Symfony version(s) affected</strong>: 4.1.7, 4.1.5 (Serializer Component)</p>
<p dir="auto"><strong>Description</strong></p>
<p dir="auto">CacheItem throws an Error: <code class="notranslate">Cache key "p@triggers" contains reserved characters {}()/\@:</code> when using the Serializer Services <code class="notranslate">deserialize</code> Method in combination with ObjectNormalizer and XmlEncoder (by passing an XML File and an Object to normalize, see Reproducer below)</p>
<p dir="auto">This seems to happen when attributes are set on the xml "root" node.</p>
<p dir="auto"><strong>How to reproduce</strong></p>
<ul dir="auto">
<li>Checkout: <a href="https://github.com/e3n-internetagentur/bug-reproducer-symfony-xmlencoder-objectnormalizer-arrayadapter-cacheitem">https://github.com/e3n-internetagentur/bug-reproducer-symfony-xmlencoder-objectnormalizer-arrayadapter-cacheitem</a></li>
<li>execute <code class="notranslate">composer install</code> to load deps</li>
<li>execute the following commands
<ol dir="auto">
<li><code class="notranslate">bin/console app:xml norootattributes.xml</code></li>
<li><code class="notranslate">bin/console app:xml rootattributes.xml</code></li>
</ol>
</li>
</ul>
<p dir="auto">Command 1. just outputs some data.</p>
<p dir="auto">Command 2. Fails with <code class="notranslate">Cache key "p@triggers" contains reserved characters {}()/\@:</code></p>
<p dir="auto">You can work around the issue by replacing <code class="notranslate">$this-&gt;serializer = $serializer;</code> in <code class="notranslate">\App\Command\XmlCommand</code> with <code class="notranslate">$this-&gt;serializer =  new Serializer([new ObjectNormalizer()], [new XmlEncoder()]);</code></p>
<p dir="auto">The reason this works is probably because no "Caching" happens for the deserialize process, at least not in a way that it triggers the CacheItem.</p>
<p dir="auto"><strong>Additional context</strong></p>
<p dir="auto">You can open the public folder where both test files reside, the only difference between them is that the root node in <code class="notranslate">rootattributes.xml</code> has an attribute.</p>
<p dir="auto">There has been another ticket with a similar error message, but I think the cause there was different altogether (<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="300155645" data-permission-text="Title is private" data-url="https://github.com/symfony/symfony/issues/26313" data-hovercard-type="issue" data-hovercard-url="/symfony/symfony/issues/26313/hovercard" href="https://github.com/symfony/symfony/issues/26313">#26313</a>)</p>