diff --git a/src/Symfony/Component/PropertyAccess/PropertyAccessor.php b/src/Symfony/Component/PropertyAccess/PropertyAccessor.php index 990d77b7a5ed0..83f9a225a1569 100644 --- a/src/Symfony/Component/PropertyAccess/PropertyAccessor.php +++ b/src/Symfony/Component/PropertyAccess/PropertyAccessor.php @@ -301,7 +301,7 @@ private function readPropertiesUntil(array $zval, PropertyPathInterface $propert if (($zval[self::VALUE] instanceof \ArrayAccess && !$zval[self::VALUE]->offsetExists($property)) || (\is_array($zval[self::VALUE]) && !isset($zval[self::VALUE][$property]) && !\array_key_exists($property, $zval[self::VALUE])) ) { - if (!$ignoreInvalidIndices) { + if (!$ignoreInvalidIndices && !$isNullSafe) { if (!\is_array($zval[self::VALUE])) { if (!$zval[self::VALUE] instanceof \Traversable) { throw new NoSuchIndexException(sprintf('Cannot read index "%s" while trying to traverse path "%s".', $property, (string) $propertyPath)); diff --git a/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php b/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php index c5ecd79be1bbf..ae773e91d87ec 100644 --- a/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php +++ b/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php @@ -573,12 +573,28 @@ public static function getValidReadPropertyPaths(): iterable yield [(object) ['foo' => null], 'foo?.bar.baz', null]; yield [(object) ['foo' => (object) ['bar' => null]], 'foo?.bar?.baz', null]; yield [(object) ['foo' => (object) ['bar' => null]], 'foo.bar?.baz', null]; + + yield from self::getNullSafeIndexPaths(); + } + + public static function getNullSafeIndexPaths(): iterable + { yield [(object) ['foo' => ['bar' => null]], 'foo[bar?].baz', null]; yield [[], '[foo?]', null]; yield [['foo' => ['firstName' => 'Bernhard']], '[foo][bar?]', null]; yield [['foo' => ['firstName' => 'Bernhard']], '[foo][bar?][baz?]', null]; } + /** + * @dataProvider getNullSafeIndexPaths + */ + public function testNullSafeIndexWithThrowOnInvalidIndex($objectOrArray, $path, $value) + { + $this->propertyAccessor = new PropertyAccessor(PropertyAccessor::DISALLOW_MAGIC_METHODS, PropertyAccessor::THROW_ON_INVALID_INDEX | PropertyAccessor::THROW_ON_INVALID_PROPERTY_PATH); + + $this->assertSame($value, $this->propertyAccessor->getValue($objectOrArray, $path)); + } + public function testTicket5755() { $object = new Ticket5775Object();