Skip to content

Commit 9a5887a

Browse files
committed
bug #4704 Fix accessing arrays with stringable objects as key (nicolas-grekas)
This PR was merged into the 3.x branch. Discussion ---------- Fix accessing arrays with stringable objects as key Fix #4701 Commits ------- 9ae75d3 Fix accessing arrays with stringable objects as key
2 parents d26e8f2 + 9ae75d3 commit 9a5887a

File tree

3 files changed

+29
-4
lines changed

3 files changed

+29
-4
lines changed

src/Extension/CoreExtension.php

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1694,7 +1694,7 @@ public static function getAttribute(Environment $env, Source $source, $object, $
16941694
}
16951695

16961696
if (match (true) {
1697-
\is_array($object) => \array_key_exists($arrayItem, $object),
1697+
\is_array($object) => \array_key_exists($arrayItem = (string) $arrayItem, $object),
16981698
$object instanceof \ArrayAccess => $object->offsetExists($arrayItem),
16991699
default => false,
17001700
}) {
@@ -1715,9 +1715,13 @@ public static function getAttribute(Environment $env, Source $source, $object, $
17151715
}
17161716

17171717
if ($object instanceof \ArrayAccess) {
1718-
$message = \sprintf('Key "%s" in object with ArrayAccess of class "%s" does not exist.', $arrayItem, $object::class);
1718+
if (\is_object($arrayItem) || \is_array($arrayItem)) {
1719+
$message = \sprintf('Key of type "%s" does not exist in ArrayAccess-able object of class "%s".', get_debug_type($arrayItem), get_debug_type($object));
1720+
} else {
1721+
$message = \sprintf('Key "%s" does not exist in ArrayAccess-able object of class "%s".', $arrayItem, get_debug_type($object));
1722+
}
17191723
} elseif (\is_object($object)) {
1720-
$message = \sprintf('Impossible to access a key "%s" on an object of class "%s" that does not implement ArrayAccess interface.', $item, $object::class);
1724+
$message = \sprintf('Impossible to access a key "%s" on an object of class "%s" that does not implement ArrayAccess interface.', $item, get_debug_type($object));
17211725
} elseif (\is_array($object)) {
17221726
if (!$object) {
17231727
$message = \sprintf('Key "%s" does not exist as the sequence/mapping is empty.', $arrayItem);
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
--TEST--
2+
#4701 Accessing arrays with stringable objects as key
3+
--TEMPLATE--
4+
{% set hash = {
5+
'foo': 'FOO',
6+
'bar': 'BAR',
7+
} %}
8+
9+
{{ hash[key] }}
10+
--DATA--
11+
class MyObj {
12+
public function __toString() {
13+
return 'foo';
14+
}
15+
}
16+
17+
return [
18+
'key' => new MyObj(),
19+
];
20+
--EXPECT--
21+
FOO

tests/TemplateTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ public static function getAttributeExceptions()
7777
['{{ null["a"] }}', 'Impossible to access a key ("a") on a null variable in "%s" at line 1.'],
7878
['{{ empty_array["a"] }}', 'Key "a" does not exist as the sequence/mapping is empty in "%s" at line 1.'],
7979
['{{ array["a"] }}', 'Key "a" for sequence/mapping with keys "foo" does not exist in "%s" at line 1.'],
80-
['{{ array_access["a"] }}', 'Key "a" in object with ArrayAccess of class "Twig\Tests\TemplateArrayAccessObject" does not exist in "%s" at line 1.'],
80+
['{{ array_access["a"] }}', 'Key "a" does not exist in ArrayAccess-able object of class "Twig\Tests\TemplateArrayAccessObject" in "%s" at line 1.'],
8181
['{{ string.a }}', 'Impossible to access an attribute ("a") on a string variable ("foo") in "%s" at line 1.'],
8282
['{{ string.a() }}', 'Impossible to invoke a method ("a") on a string variable ("foo") in "%s" at line 1.'],
8383
['{{ null.a }}', 'Impossible to access an attribute ("a") on a null variable in "%s" at line 1.'],

0 commit comments

Comments
 (0)