[PropertyAccess] Fix handling property names with a .#58110
Conversation
|
Shouldn't the dot be escaped in the property path instead? |
|
For the minimal reproducer, yes, but it doesn't help with the original issue where the author uses Serializer and doesn't have the hand on the underlying property paths. Inevitably, this is closely linked to stdClass, hence the hard check in the code to make sure you're dealing with stdClass. |
|
Can this not be fixed inside the Serializer component? |
|
Actually, escaping the dot seems only to work with array accesses. The following code breaks: $stdclass = (object) ['bankAccount.iban' => 'NL16TEST0436169118', 'bankSummary' => ''];
$accessor = PropertyAccess::createPropertyAccessor();
dump($accessor->getValue($stdclass, 'bankAccount\.iban')); // throws NoSuchPropertyExceptionOr maybe I'm using the wrong syntax? |
| ]; | ||
|
|
||
| if (\is_object($objectOrArray) && false === strpbrk((string) $propertyPath, '.[')) { | ||
| if (\is_object($objectOrArray) && (false === strpbrk((string) $propertyPath, '.[') || property_exists($objectOrArray, $propertyPath))) { |
There was a problem hiding this comment.
let's make this specific to stdClass?
this can be true for any object with dynamic properties but I don't think we need to support that, esp. if that costs too much, CPU-wise. Can you check this aspect.
There was a problem hiding this comment.
I've made it specific to stdClass. Here a quick benchmark, testing both accessing stdClass and other objects:
<?php
use Symfony\Component\PropertyAccess\PropertyAccess;
require 'vendor/autoload.php';
class Foo
{
public $iban = 'NL16TEST0436169118';
public $bankSummary = '';
}
$stdclass = (object) ['iban' => 'NL16TEST0436169118', 'bankSummary' => ''];
$accessor = PropertyAccess::createPropertyAccessor();
dump("Testing with stdClass");
foreach (range(1, 5) as $i) {
$start = microtime(true);
for ($j = 0; $j < 100000; $j++) {
$accessor->setValue($stdclass, 'iban', 'value');
$accessor->getValue($stdclass, 'iban');
}
$end = microtime(true);
dump('Elapsed time: ' . ($end - $start) . ' seconds');
}
dump("\nTesting with Foo");
$foo = new Foo();
foreach (range(1, 5) as $i) {
$start = microtime(true);
for ($j = 0; $j < 100000; $j++) {
$accessor->setValue($foo, 'iban', 'value');
$accessor->getValue($foo, 'iban');
}
$end = microtime(true);
dump('Elapsed time: ' . ($end - $start) . ' seconds');
}Above is with the patch, below it 5.4 as is:
The difference is low for 100 000 iterations. After running the script several times, the time differences are explained more by external tasks that take up some CPU during execution.
c0e415c to
84ac73b
Compare
84ac73b to
d939a16
Compare
|
Thank you @alexandre-daubois. |

If the property path contains a dot, it is considered to be an access to an underlying property. However, some edge cases allow to have dots in property names, especially with
stdClass.Minimal reproducer: