Hi,
I would like to open the discussion on my proposal to add two small,
focused array functions for retrieving and checking nested array elements
using dot notation.
This is the link to the RFC:
https://wiki.php.net/rfc/array_get_and_array_has
This is the link to the proposed implementation:
https://github.com/php/php-src/pull/21637
Thanks!!
Carlos
From: Barel barel.barelon@gmail.com
Sent: Saturday, April 4, 2026 5:06 PM
To: PHP internals internals@lists.php.net
Subject: [PHP-DEV] [RFC] [Discussion] array_get and array_has functions
Hi,
I would like to open the discussion on my proposal to add two small, focused array functions for retrieving and checking nested array elements using dot notation.
This is the link to the RFC: https://wiki.php.net/rfc/array_get_and_array_has
This is the link to the proposed implementation: https://github.com/php/php-src/pull/21637
Thanks!!
Carlos
Hey,
Very useful functions!
Why did you decide to not handle keys with dots? It would prevent these functions from being used in tools that might sometimes receive something like example.comas the key. The similar userland functions that I’ve seen do at least support the exact dotted key as well, even if not offering a full dotted<->nested equivalence with priority rules, partial nested-dotted and other fun stuff.
I’ve also found it quite useful to have [‘user.name’ => ‘Alice’] be equivalent to [‘user’ => [‘name’ => ‘Alice’]] for testing/mocking more complex structures.
BR,
Juris
Hi Carlos,
This sounds interesting.
A mature solution used in JS is lodash, with the get and has functions:
- https://lodash.com/docs/#get
- https://lodash.com/docs/#has
Also, from what I could search, Laravel array helpers have this
functionality as well: - https://laravel.com/docs/master/helpers#method-array-get
- https://laravel.com/docs/master/helpers#method-array-has
I was curious; did you research both, and maybe also other libraries? If
yes, it would be nice to mention this in the RFC.
They have some options, like allowing the key parameter as a list of
strings as well.
And also escaping the dot in the key in one way or another.
--
Alex
Hi,
I would like to open the discussion on my proposal to add two small,
focused array functions for retrieving and checking nested array elements
using dot notation.This is the link to the RFC:
https://wiki.php.net/rfc/array_get_and_array_hasThis is the link to the proposed implementation:
https://github.com/php/php-src/pull/21637Thanks!!
Carlos
On Sat, 4 Apr 2026 at 18:54, Alexandru Pătrănescu drealecs@gmail.com
wrote:
Hi Carlos,
This sounds interesting.
A mature solution used in JS is lodash, with the get and has functions:
- https://lodash.com/docs/#get
- https://lodash.com/docs/#has
Also, from what I could search, Laravel array helpers have this
functionality as well:- https://laravel.com/docs/master/helpers#method-array-get
- https://laravel.com/docs/master/helpers#method-array-has
I was curious; did you research both, and maybe also other libraries? If
yes, it would be nice to mention this in the RFC.They have some options, like allowing the key parameter as a list of
strings as well.
And also escaping the dot in the key in one way or another.--
Alex
Hi Alex,
Thanks for your comments. I have updated the RFC with references to the
Laravel and Lodash implementations
Allowing the key parameter as a list of strings sounds really interesting,
let me explore that possibility
Several other people mentioned escaping dots as something important, so I
will look into adding that to the implementation
Cheers
Carlos
Hi,
I would like to open the discussion on my proposal to add two small,
focused array functions for retrieving and checking nested array elements
using dot notation.This is the link to the RFC:
https://wiki.php.net/rfc/array_get_and_array_hasThis is the link to the proposed implementation:
https://github.com/php/php-src/pull/21637Thanks!!
Carlos
Hi,
I would like to open the discussion on my proposal to add two small,
focused array functions for retrieving and checking nested array
elements using dot notation.This is the link to the RFC:
https://wiki.php.net/rfc/array_get_and_array_hasThis is the link to the proposed implementation:
https://github.com/php/php-src/pull/21637Thanks!!
Carlos
I echo others comments with regards to looking at / comparing to
existing implementations (particularly Laravel, given its popularity),
and escaping.
I would also suggest that the function names should explicitly indicate
they use dot notation to reduce potential confusion over which array
functions accept dot notation and avoid potential conflicts should
similar non-dot-notation equivalents be desired (for these or any future
dot-notation supporting array_ functions)
Hi,
I would like to open the discussion on my proposal to add two small,
focused array functions for retrieving and checking nested array
elements using dot notation.This is the link to the RFC:
https://wiki.php.net/rfc/array_get_and_array_hasThis is the link to the proposed implementation:
https://github.com/php/php-src/pull/21637Thanks!!
Carlos
I echo others comments with regards to looking at / comparing to
existing implementations (particularly Laravel, given its popularity),
and escaping.I would also suggest that the function names should explicitly indicate
they use dot notation to reduce potential confusion over which array
functions accept dot notation and avoid potential conflicts should
similar non-dot-notation equivalents be desired (for these or any future
dot-notation supporting array_ functions)
Hi,
Thanks for your comments, I modified the RFC to include some references and
to look into escaping
Regarding function names, what would be your suggestion?
Cheers
Carlos
This is the link to the RFC: https://wiki.php.net/rfc/
array_get_and_array_has https://wiki.php.net/rfc/array_get_and_array_has
I'd prefer $key=null case removed. It's not that useful, not on pair
with array_has(), and one would debate what to do with the $default in
this case.
I'm not sure this needs to be stated in the RFC, but I hope they do not
throw a warning when the key does not exist, on any level.
--
Aleksander Machniak
Kolab Groupware Developer [https://kolab.org]
Roundcube Webmail Developer [https://roundcube.net]
PGP: 19359DC1 # Blog: https://kolabian.wordpress.com
This is the link to the RFC: https://wiki.php.net/rfc/
array_get_and_array_has <
https://wiki.php.net/rfc/array_get_and_array_has>
I'd prefer $key=null case removed. It's not that useful, not on pair
with array_has(), and one would debate what to do with the $default in
this case.I'm not sure this needs to be stated in the RFC, but I hope they do not
throw a warning when the key does not exist, on any level.
Thanks for your comments. I would like to hear what other people think
about the null case. I find it useful but if other people think it is
unnecessary, it can be easily removed. In any case, the $default would not
be used in this case
And, no, no warning will be thrown if any part of the path does not exist,
being able to easily support not existing paths is one of the main reasons
for this RFC
Cheers
Carlos
--
Aleksander Machniak
Kolab Groupware Developer [https://kolab.org]
Roundcube Webmail Developer [https://roundcube.net]PGP: 19359DC1 # Blog: https://kolabian.wordpress.com
This is the link to the RFC: https://wiki.php.net/rfc/
array_get_and_array_has <
https://wiki.php.net/rfc/array_get_and_array_has>
I'd prefer $key=null case removed. It's not that useful, not on pair
with array_has(), and one would debate what to do with the $default in
this case.I'm not sure this needs to be stated in the RFC, but I hope they do not
throw a warning when the key does not exist, on any level.Thanks for your comments. I would like to hear what other people think
about thenullcase. I find it useful but if other people think it is
unnecessary, it can be easily removed. In any case, the $default would not
be used in this case
Technically speaking, this scenario does exist; the problem here, if I’m not mistaken, is how to represent or handle it. You originally suggested using the null value for this, which, to my knowledge, is one approach. However, this dilutes the parameter’s meaning, much like it does with “int.” A common and long-established approach is to use only strings for the reference tokens (“keys”).
Since “null” is then the empty string (z-string, empty string, null string), the dot notation in your path can still express this—it would contain neither a dot nor any character—but it would be ambiguous, as it could also mean an empty key for access or just be string zero, just the default string value, e.g. never a name or reference.
JSON Pointer resolves this by prefixing each “key” with the separator; accessing the empty key is then “//” (or “..” in dot-prefix notation for illustration) and accessing the container itself is “/” (or “.” in dot-prefix notation)—the null case discussed here.
For the iterable access discussed (an iterable of reference tokens instead of a string with the dot path), this is then no longer ambiguous, since null, as originally proposed, becomes the empty array and not an array containing the empty string—problem solved. So, if one considers allowing iterables, it becomes possible to avoid the null case and use an empty iterable instead. In this context, the notation [] is probably even more meaningful than null.
I hope these thoughts help you think through the whole thing a bit more carefully. Technically speaking, after removing null, there can only be one other null case: the empty string. Switching from postfix to prefix notation can help with this and also prevents empty strings entirely; and regardless of the discussion about iterables, removing “null” boils down to the fact that if you want to support both cases: access to the holder’s value and access to the holder’s empty key must be resolved into a single case, and you must specify which case that is, since you cannot express two values for a single value, and keys or any other type of reference must be unique, otherwise they will obviously become unusable too quickly. In my opinion, it makes the most sense to resolve the null case first, since all other specification errors related to ambiguity only arise later (e.g., insufficient escaping rules, conditional access to the existence of a key based on fuzzy logic, etc.) and this provides the precision needed for the cases you want to support, whether it’s postfix or prefix notation or whatever.
In practice, it doesn’t take much effort to pass the array via a placeholder when calling the function:
$value = array_get_dot([‘’ => $array], ‘.’);
This serves as an example of the null/placeholder/null key scenario in this context and highlights where there might still be some ambiguity with postfix notation.
A third function that lists all dot paths in an array could be helpful for discussing and testing the RFC:
// The function array_get_dots() returns the array of all dot paths of the array in breadth-first order.
function array_get_dots(array $array): array { ... }
$dots = array_get_dots($array);
With a small test data set, simple property tests could be performed, which could then be used as examples in the RFC to formulate the expectations.
The function names in the two listings are for illustrative purposes only.
And yes, in my view, it makes sense to remove “null” and, furthermore, “int” from the first parameter.
Because of the dot notation as shown, the empty string as a value for the dot path should trigger a value error due to an empty dot path, as removing “null” alone does not fully resolve the ambiguity issue for the null string value.
And, no, no warning will be thrown if any part of the path does not exist,
being able to easily support not existing paths is one of the main reasons
for this RFC
Thank you for the clarification!
This is in my opinion good to clarify in the RFC as well, as it is commonly known as error handling, which includes writing what an error is and what is not an error and which diagnostics are guaranteed by the implementation (for example, no warnings/notices.)
--hakre
Hi,
I would like to open the discussion on my proposal to add two small, focused array functions for retrieving and checking nested array elements using dot notation.
This is the link to the RFC: https://wiki.php.net/rfc/array_get_and_array_has
This is the link to the proposed implementation: https://github.com/php/php-src/pull/21637
Thanks!!
Carlos
Hi Barel,
Interesting! As dot-notation isn't used anywhere else, and I don't see it discussed as part of the RFC, how are developers to prevent injections of dots in user input? With SQL, we have parameters and escaping ... but I don't see any of that here.
As an example:
$user = [ 'data' => [...], 'password' => 'secret' ];
If the path is completely user-controlled (as in the examples given), then they can access sensitive information in the array. Even if it is prefixed, ie., "data.%s" -- an attacker can simply enumerate all possible keys and subkeys.
As it stands, it appears to add a new vulnerability to PHP that will be unfamiliar with PHP developers -- unless they're using a framework that already does this sort of notation.
— Rob
Hi,
I would like to open the discussion on my proposal to add two small, focused array functions for retrieving and checking nested array elements using dot notation.
This is the link to the RFC: https://wiki.php.net/rfc/array_get_and_array_has
This is the link to the proposed implementation: https://github.com/php/php-src/pull/21637
Thanks!!
Carlos
Hi Barel,
Interesting! As dot-notation isn't used anywhere else, and I don't see it discussed as part of the RFC, how are developers to prevent injections of dots in user input? With SQL, we have parameters and escaping ... but I don't see any of that here.
As an example:
$user = [ 'data' => [...], 'password' => 'secret' ];
If the path is completely user-controlled (as in the examples given), then they can access sensitive information in the array. Even if it is prefixed, ie., "data.%s" -- an attacker can simply enumerate all possible keys and subkeys.
As it stands, it appears to add a new vulnerability to PHP that will be unfamiliar with PHP developers -- unless they're using a framework that already does this sort of notation.
I wouldn’t go that far, but I’d like to start by emphasizing that the dot notation described here clearly does not provide a mechanism for escaping the dot. That’s probably a shortcoming, but if any user-supplied string key poses a security risk, then PHP arrays are also affected, and this vulnerability would be nothing new! (Rather, it would be to be expected.)
-- hakre
Hi,
I would like to open the discussion on my proposal to add two small, focused array functions for retrieving and checking nested array elements using dot notation.
This is the link to the RFC: https://wiki.php.net/rfc/array_get_and_array_has
This is the link to the proposed implementation: https://github.com/php/php-src/pull/21637
Thanks!!
Carlos
Hi Barel,
Interesting! As dot-notation isn't used anywhere else, and I don't see it discussed as part of the RFC, how are developers to prevent injections of dots in user input? With SQL, we have parameters and escaping ... but I don't see any of that here.
As an example:
$user = [ 'data' => [...], 'password' => 'secret' ];
If the path is completely user-controlled (as in the examples given), then they can access sensitive information in the array. Even if it is prefixed, ie., "data.%s" -- an attacker can simply enumerate all possible keys and subkeys.
As it stands, it appears to add a new vulnerability to PHP that will be unfamiliar with PHP developers -- unless they're using a framework that already does this sort of notation.
I wouldn’t go that far, but I’d like to start by emphasizing that the dot notation described here clearly does not provide a mechanism for escaping the dot. That’s probably a shortcoming, but if any user-supplied string key poses a security risk, then PHP arrays are also affected, and this vulnerability would be nothing new! (Rather, it would be to be expected.)
-- hakre
My point is that this is different and distinct from regular array vulnerabilities and injections.
$user['data'][$key] !== array_get($user['data'], $key, null);
In the former 'some.key' is a full key; in the latter, it would access ['some']['key'].
Further, the former could be a valid key, but there is no way to access it using the proposed RFC
— Rob
Hi,
I would like to open the discussion on my proposal to add two small, focused array functions for retrieving and checking nested array elements using dot notation.
This is the link to the RFC: https://wiki.php.net/rfc/array_get_and_array_has
This is the link to the proposed implementation: https://github.com/php/php-src/pull/21637
Thanks!!
Carlos
Hi Barel,
Interesting! As dot-notation isn't used anywhere else, and I don't see it discussed as part of the RFC, how are developers to prevent injections of dots in user input? With SQL, we have parameters and escaping ... but I don't see any of that here.
As an example:
$user = [ 'data' => [...], 'password' => 'secret' ];
If the path is completely user-controlled (as in the examples given), then they can access sensitive information in the array. Even if it is prefixed, ie., "data.%s" -- an attacker can simply enumerate all possible keys and subkeys.
As it stands, it appears to add a new vulnerability to PHP that will be unfamiliar with PHP developers -- unless they're using a framework that already does this sort of notation.
I wouldn’t go that far, but I’d like to start by emphasizing that the dot notation described here clearly does not provide a mechanism for escaping the dot. That’s probably a shortcoming, but if any user-supplied string key poses a security risk, then PHP arrays are also affected, and this vulnerability would be nothing new! (Rather, it would be to be expected.)
-- hakre
My point is that this is different and distinct from regular array vulnerabilities and injections.
$user['data'][$key] !== array_get($user['data'], $key, null);
In the former 'some.key' is a full key; in the latter, it would access ['some']['key'].
For the sake of this discussion, it would probably make sense to use $dot_path or $dot_pointer instead of $key in this function; this would make the distinction clearer. If I recall correctly, this was already suggested earlier in the discussion—though in the function name, not the parameter name—but I’d have to look it up to find out the exact details.
However, I don’t see any difference from accessing a standard array, apart from the fact that the first parameter contains a container object in the domain and the standard variable on the left-hand side; I wouldn’t expect that !== must be equal to ===.
Further, the former could be a valid key, but there is no way to access it using the proposed RFC
If I'm not mistaken, this is due to the lack of an escape mechanism, which could very well be intentional—I don't know for sure, but in another thread, Carlos wrote that they want to reconsider this.
And even if it were intentional, without an escape mechanism, it would fall back to the value of the default parameter. Technically speaking, I don’t see a problem here, unless this is unintended or would, in good faith, violate expectations regarding key-value pairs.
Neither of these is a new security issue that you’ve raised—even though, in my opinion, you’ve made good points with your distinctions.
-- hakre
Hi,
I would like to open the discussion on my proposal to add two small,
focused array functions for retrieving and checking nested array elements
using dot notation.This is the link to the RFC:
https://wiki.php.net/rfc/array_get_and_array_hasThis is the link to the proposed implementation:
https://github.com/php/php-src/pull/21637Thanks!!
Carlos
Hi Barel,
Interesting! As dot-notation isn't used anywhere else, and I don't see it
discussed as part of the RFC, how are developers to prevent injections of
dots in user input? With SQL, we have parameters and escaping ... but I
don't see any of that here.As an example:
$user = [ 'data' => [...], 'password' => 'secret' ];
If the path is completely user-controlled (as in the examples given), then
they can access sensitive information in the array. Even if it is prefixed,
ie., "data.%s" -- an attacker can simply enumerate all possible keys and
subkeys.As it stands, it appears to add a new vulnerability to PHP that will be
unfamiliar with PHP developers -- unless they're using a framework that
already does this sort of notation.— Rob
Thanks Rob. Probably user input is not the best use case for these
functions, I just used it in the examples because it is simple. In any
case, if your program allows unrestricted array access using a user defined
path, the vulnerability already exists, these functions just make it easier
to implement the access. If you did not have them and wanted the same
functionality you would use a custom implementation (like the one provided
by Laravel) and you would have the same vulnerability
Cheers
Carlos
__
Hi,
I would like to open the discussion on my proposal to add two small, focused array functions for retrieving and checking nested array elements using dot notation.
This is the link to the RFC: https://wiki.php.net/rfc/array_get_and_array_has
This is the link to the proposed implementation: https://github.com/php/php-src/pull/21637
Thanks!!
Carlos
Hi Barel,
Interesting! As dot-notation isn't used anywhere else, and I don't see it discussed as part of the RFC, how are developers to prevent injections of dots in user input? With SQL, we have parameters and escaping ... but I don't see any of that here.
As an example:
$user = [ 'data' => [...], 'password' => 'secret' ];
If the path is completely user-controlled (as in the examples given), then they can access sensitive information in the array. Even if it is prefixed, ie., "data.%s" -- an attacker can simply enumerate all possible keys and subkeys.
As it stands, it appears to add a new vulnerability to PHP that will be unfamiliar with PHP developers -- unless they're using a framework that already does this sort of notation.
— Rob
Thanks Rob. Probably user input is not the best use case for these functions, I just used it in the examples because it is simple.
And quite dangerous. I’d recommend using realistic examples that showcase the work instead of simple examples that scream “hack me” to anyone who’s written PHP more than a few years.
In any case, if your program allows unrestricted array access using a user defined path, the vulnerability already exists, these functions just make it easier to implement the access.
That’s the rub, right? Array access simply cannot have a user-defined array path today. This feature allows that but as of this reply, the RFC does not disclose the danger of such a thing despite using it in the examples. It’s either irresponsible or naïve.
If you did not have them and wanted the same functionality you would use a custom implementation (like the one provided by Laravel) and you would have the same vulnerability
Cheers
Carlos
Different frameworks and implementations assign different semantics. I’ve seen dots (such as in laravel), slashes, double back-slashes, etc. over the years. I think dots is a fine choice, but it is worth pointing out that, currently, array keys are binary-safe. These simple looking functions completely ignore that. Even if you escape the dots, now you have two variables: $escaped_key (for use in these functions) and $unescaped_key.
I see that wildcards are also being considered in the future. Maybe, instead of adding two thin utility functions to global space, it would be better to create an QueryableArray class … kinda like Linq in C# … to handle this type of stuff? Otherwise, this becomes a slippery slope of assigning semantics to random byte sequences.
If you’re going to add query semantics to arrays, do it properly.
— Rob
Hi,
I would like to open the discussion on my proposal to add two small,
focused array functions for retrieving and checking nested array elements
using dot notation.This is the link to the RFC:
https://wiki.php.net/rfc/array_get_and_array_hasThis is the link to the proposed implementation:
https://github.com/php/php-src/pull/21637Thanks!!
Thank you very much! That’s very interesting, so I have to ask right away: Is there a specific reason to limit this to strings, integers, and null for arrays, rather than also allowing arrays or iterables?
This reminds me of JSON Pointers (RFC 6901), which can usually be easily mapped as an iterable with string keys, which can then be accessed via the holder variable, similar to the foreach example you already describe in your RFC.
If these two functions supported passing an array/iterable with the traversal keys as a second parameter, this would be advantageous, since the JSON pointer would then not need to be recoded into dot notation, but only (if not already done) sliced and passed as an array as the second parameter.
That's why I'm asking.
Interestingly, JSON Pointer solves the “null problem” by prefixing the zero or more reference tokens (keys) with a slash ‘/’, and it supports all seven types of JSON values without limiting itself to just JSON arrays or objects. This is just food for thought: array_... are clearly array functions, so this “restriction” is likely intentional. In PHP, however, I can also imagine iterables that resemble what you’ve already described in your RFC, and from there it’s not far to the holder object we see in JSON and JSON Pointer. So please don’t confuse my “request” regarding arrays/iterables with the first parameter; it’s simply about passing the key as a keys, which is a small improvement over dot notation.
With arrays in PHP, users will likely prefer the non-standard, more custom dot notation, and that’s perfectly fine. I saw many people asking for this in the early days of Stack Overflow, and if Symfony/Laravel have it as well, that’s just another strong indication of such a preference.
Thanks again for your RFC
--hakre
P.S. Work on the RFC documentation for JSON Path finally began in 2020, and it was published in February 2024. The standard has its roots in PHP and JavaScript, and perhaps it’s time for PHP to expand its standard library with such features at the same pace we did with JSON. Your RFC seems well-suited for this purpose. Thanks again.
Hi,
I would like to open the discussion on my proposal to add two small,
focused array functions for retrieving and checking nested array elements
using dot notation.This is the link to the RFC:
https://wiki.php.net/rfc/array_get_and_array_hasThis is the link to the proposed implementation:
https://github.com/php/php-src/pull/21637Thanks!!
Thank you very much! That’s very interesting, so I have to ask right away:
Is there a specific reason to limit this to strings, integers, and null for
arrays, rather than also allowing arrays or iterables?This reminds me of JSON Pointers (RFC 6901), which can usually be easily
mapped as an iterable with string keys, which can then be accessed via the
holder variable, similar to the foreach example you already describe in
your RFC.If these two functions supported passing an array/iterable with the
traversal keys as a second parameter, this would be advantageous, since the
JSON pointer would then not need to be recoded into dot notation, but only
(if not already done) sliced and passed as an array as the second parameter.That's why I'm asking.
Interestingly, JSON Pointer solves the “null problem” by prefixing the
zero or more reference tokens (keys) with a slash ‘/’, and it supports all
seven types of JSON values without limiting itself to just JSON arrays or
objects. This is just food for thought: array_... are clearly array
functions, so this “restriction” is likely intentional. In PHP, however, I
can also imagine iterables that resemble what you’ve already described in
your RFC, and from there it’s not far to the holder object we see in JSON
and JSON Pointer. So please don’t confuse my “request” regarding
arrays/iterables with the first parameter; it’s simply about passing the
key as a keys, which is a small improvement over dot notation.With arrays in PHP, users will likely prefer the non-standard, more custom
dot notation, and that’s perfectly fine. I saw many people asking for this
in the early days of Stack Overflow, and if Symfony/Laravel have it as
well, that’s just another strong indication of such a preference.Thanks again for your RFC
--hakre
P.S. Work on the RFC documentation for JSON Path finally began in 2020,
and it was published in February 2024. The standard has its roots in PHP
and JavaScript, and perhaps it’s time for PHP to expand its standard
library with such features at the same pace we did with JSON. Your RFC
seems well-suited for this purpose. Thanks again.
Thanks for your comments. Someone else already suggested allowing arrays
for the $key parameter and I am considering it, I think it will probably be
a good addition
Cheers
Carlos
Hi,
I would like to open the discussion on my proposal to add two small,
focused array functions for retrieving and checking nested array elements
using dot notation.This is the link to the RFC:
https://wiki.php.net/rfc/array_get_and_array_hasThis is the link to the proposed implementation:
https://github.com/php/php-src/pull/21637Thanks!!
Thank you very much! That’s very interesting, so I have to ask right away:
Is there a specific reason to limit this to strings, integers, and null for
arrays, rather than also allowing arrays or iterables?This reminds me of JSON Pointers (RFC 6901), which can usually be easily
mapped as an iterable with string keys, which can then be accessed via the
holder variable, similar to the foreach example you already describe in
your RFC.If these two functions supported passing an array/iterable with the
traversal keys as a second parameter, this would be advantageous, since the
JSON pointer would then not need to be recoded into dot notation, but only
(if not already done) sliced and passed as an array as the second parameter.That's why I'm asking.
Interestingly, JSON Pointer solves the “null problem” by prefixing the
zero or more reference tokens (keys) with a slash ‘/’, and it supports all
seven types of JSON values without limiting itself to just JSON arrays or
objects. This is just food for thought: array_... are clearly array
functions, so this “restriction” is likely intentional. In PHP, however, I
can also imagine iterables that resemble what you’ve already described in
your RFC, and from there it’s not far to the holder object we see in JSON
and JSON Pointer. So please don’t confuse my “request” regarding
arrays/iterables with the first parameter; it’s simply about passing the
key as a keys, which is a small improvement over dot notation.With arrays in PHP, users will likely prefer the non-standard, more custom
dot notation, and that’s perfectly fine. I saw many people asking for this
in the early days of Stack Overflow, and if Symfony/Laravel have it as
well, that’s just another strong indication of such a preference.Thanks again for your RFC
--hakre
P.S. Work on the RFC documentation for JSON Path finally began in 2020,
and it was published in February 2024. The standard has its roots in PHP
and JavaScript, and perhaps it’s time for PHP to expand its standard
library with such features at the same pace we did with JSON. Your RFC
seems well-suited for this purpose. Thanks again.Thanks for your comments. Someone else already suggested allowing arrays
for the $key parameter and I am considering it, I think it will probably be
a good addition
Yes, I agree, and I suggest we also consider iterable as part of this discussion.
Thank you Carlos as well for your work on these functions.
--hakre
Following some comments from some users I have decided to also allow the
$key parameter to be a list of strings/ints so that this functionality can
also be used without using dot notation. I believe this also removes the
need to add any kind of dot escaping. If your segments can contain dots,
just use the form of the function that accepts an array.
It was suggested that accepting an iterable would be a good addition but
none of the array_ functions accept an iterable so I don't think it would
be good to make an exception here
The proposed implementation in GitHub has also been updated with this change
Cheers
Carlos
Hi,
I would like to open the discussion on my proposal to add two small,
focused array functions for retrieving and checking nested array
elements
using dot notation.This is the link to the RFC:
https://wiki.php.net/rfc/array_get_and_array_hasThis is the link to the proposed implementation:
https://github.com/php/php-src/pull/21637Thanks!!
Thank you very much! That’s very interesting, so I have to ask right
away:
Is there a specific reason to limit this to strings, integers, and
null for
arrays, rather than also allowing arrays or iterables?This reminds me of JSON Pointers (RFC 6901), which can usually be
easily
mapped as an iterable with string keys, which can then be accessed via
the
holder variable, similar to the foreach example you already describe in
your RFC.If these two functions supported passing an array/iterable with the
traversal keys as a second parameter, this would be advantageous,
since the
JSON pointer would then not need to be recoded into dot notation, but
only
(if not already done) sliced and passed as an array as the second
parameter.That's why I'm asking.
Interestingly, JSON Pointer solves the “null problem” by prefixing the
zero or more reference tokens (keys) with a slash ‘/’, and it supports
all
seven types of JSON values without limiting itself to just JSON arrays
or
objects. This is just food for thought: array_... are clearly array
functions, so this “restriction” is likely intentional. In PHP,
however, I
can also imagine iterables that resemble what you’ve already described
in
your RFC, and from there it’s not far to the holder object we see in
JSON
and JSON Pointer. So please don’t confuse my “request” regarding
arrays/iterables with the first parameter; it’s simply about passing
the
key as a keys, which is a small improvement over dot notation.With arrays in PHP, users will likely prefer the non-standard, more
custom
dot notation, and that’s perfectly fine. I saw many people asking for
this
in the early days of Stack Overflow, and if Symfony/Laravel have it as
well, that’s just another strong indication of such a preference.Thanks again for your RFC
--hakre
P.S. Work on the RFC documentation for JSON Path finally began in 2020,
and it was published in February 2024. The standard has its roots in
PHP
and JavaScript, and perhaps it’s time for PHP to expand its standard
library with such features at the same pace we did with JSON. Your RFC
seems well-suited for this purpose. Thanks again.Thanks for your comments. Someone else already suggested allowing arrays
for the $key parameter and I am considering it, I think it will probably
be
a good additionYes, I agree, and I suggest we also consider iterable as part of this
discussion.Thank you Carlos as well for your work on these functions.
--hakre
Following some comments from some users I have decided to also allow
the $key parameter to be a list of strings/ints so that this
functionality can also be used without using dot notation. I believe
this also removes the need to add any kind of dot escaping. If your
segments can contain dots, just use the form of the function that
accepts an array.It was suggested that accepting an iterable would be a good addition
but none of the array_ functions accept an iterable so I don't think it
would be good to make an exception hereThe proposed implementation in GitHub has also been updated with this change
Cheers
Carlos
Please remember to bottom post. :-)
It looks like the RFC hasn't been fully updated for array-based "keys" yet. The function signatures in most of the examples still say string|int|null.
Despite my long-standing and public crusade against arrays being used where an object belongs, I'm overall in favor of this direction. However, I would go all-in on the array syntax, not the dotted syntax. There's a few reasons for that.
-
The various notes around escaping. Having a string instruction format that doesn't handle escaping and encoding and other edge cases is asking for trouble, and it's trouble that will be harder to fix in the future. String instructions are always more complicated and nuanced than you expect, so a simple "split on the dot and now it's an array!" approach is just too rudimentary to be trustworthy, for all the reasons mentioned in previous posts.
-
If you're not building the path dynamically, then there is little advantage of it over what we have now.
array_get($array, 'foo.bar.1.baz', null);
$array['foo']['bar'][1]['baz'] ?? null
The second may be slightly slower to type because of the punctuation, but it's perfectly viable today.
Where it becomes interesting is when the path is variable... and if the path is variable, I'll probably want to be building it dynamically rather than just selecting one of a few hard-coded options. And if I'm building it dynamically, then string concatenation is an awful way to do that, for all the escaping reasons mentioned previously. We're back to concatenating SQL strings together, with all the risk that entails.
So I would be in favor of going all the way to
function array_get(array $array, array $path, mixed $default = null) {}
Or, for that matter, that is nearly the same as:
function array_get(array $array, array $path) {}
array_get($arr, $path) ?? null;
Which would allow using a variadic for the $path if desired, instead of an array. I'm not certain that's optimal, but I think it's worth discussing. array_has() would then follow suit.
Then, separately, I would be in favor of a full-on JSON Pointer implementation that can work on both arrays and JSON blobs, potentially (as the two are effectively isomorphic). Skip a custom dot notation. Go straight to the fully robust standard. Do not pass go, do not collect 200 security reports.
--Larry Garfield
Following some comments from some users I have decided to also allow
the $key parameter to be a list of strings/ints so that this
functionality can also be used without using dot notation. I believe
this also removes the need to add any kind of dot escaping. If your
segments can contain dots, just use the form of the function that
accepts an array.It was suggested that accepting an iterable would be a good addition
but none of the array_ functions accept an iterable so I don't think it
would be good to make an exception hereThe proposed implementation in GitHub has also been updated with this
changeCheers
Carlos
Please remember to bottom post. :-)
It looks like the RFC hasn't been fully updated for array-based "keys"
yet. The function signatures in most of the examples still say
string|int|null.Despite my long-standing and public crusade against arrays being used
where an object belongs, I'm overall in favor of this direction. However,
I would go all-in on the array syntax, not the dotted syntax. There's a
few reasons for that.
The various notes around escaping. Having a string instruction format
that doesn't handle escaping and encoding and other edge cases is asking
for trouble, and it's trouble that will be harder to fix in the future.
String instructions are always more complicated and nuanced than you
expect, so a simple "split on the dot and now it's an array!" approach is
just too rudimentary to be trustworthy, for all the reasons mentioned in
previous posts.If you're not building the path dynamically, then there is little
advantage of it over what we have now.array_get($array, 'foo.bar.1.baz', null);
$array['foo']['bar'][1]['baz'] ?? null
The second may be slightly slower to type because of the punctuation, but
it's perfectly viable today.Where it becomes interesting is when the path is variable... and if the
path is variable, I'll probably want to be building it dynamically rather
than just selecting one of a few hard-coded options. And if I'm building
it dynamically, then string concatenation is an awful way to do that, for
all the escaping reasons mentioned previously. We're back to concatenating
SQL strings together, with all the risk that entails.So I would be in favor of going all the way to
function array_get(array $array, array $path, mixed $default = null) {}
Or, for that matter, that is nearly the same as:
function array_get(array $array, array $path) {}
array_get($arr, $path) ?? null;
Which would allow using a variadic for the $path if desired, instead of an
array. I'm not certain that's optimal, but I think it's worth discussing.
array_has() would then follow suit.Then, separately, I would be in favor of a full-on JSON Pointer
implementation that can work on both arrays and JSON blobs, potentially (as
the two are effectively isomorphic). Skip a custom dot notation. Go
straight to the fully robust standard. Do not pass go, do not collect 200
security reports.--Larry Garfield
Larry,
Thanks for pointing out that I had not updated the example code to include
array in the type, this has now been updated
You raise some interesting points in your message. I would like to hear
what other people think about them
Cheers
Carlos
Larry,
[...]
You raise some interesting points in your message. I would like to hear
what other people think about them
For leaving the default value out so that the splat (or was it spread?)
operator can be used also in favour.
About JSON Pointer I already wrote, IMHO it should be referenced in the RFC
prominently, e.g. above the Laravel or other existing implementation
references as it is an actual standard.
-- hakre
Hi Carlos,
The proposal looks simple on the surface, but it implicitly introduces a
non-trivial policy for interpreting array keys, which is problematic at the
language level.
In PHP, array keys are intentionally loose — any string is a valid key,
including ones containing dots or other separators. Introducing
"array_get()" / "array_has()" with dot-notation means that a plain string
key like "'user.name'" is no longer unambiguously a key; it may be
interpreted as a path. That creates a semantic conflict with existing,
perfectly valid data structures.
This is not just a syntactic concern — it’s a shift in the data model. The
function starts encoding assumptions about how keys should be interpreted,
rather than operating on arrays as they are defined by the language.
We can already see that this space is not universally agreed upon:
- Laravel and Symfony both provide similar helpers, but they use different
path semantics. - Questions like escaping, null handling, distinguishing “missing key” vs
“null value”, or supporting ArrayAccess / objects are all policy decisions,
not language primitives.
Because of that, these helpers are inherently convention-driven, not
semantically neutral. Different ecosystems solve them differently, which is
a strong signal that this abstraction belongs in userland, where such
conventions can be chosen explicitly and consistently.
Putting this into core would effectively standardize one arbitrary
interpretation of array paths, while PHP arrays themselves do not have such
a concept.
Additionally, allowing "$key" to accept an "array" further weakens the
conceptual model. A variable named "$key" strongly implies a single scalar
identifier, while an array represents a sequence of path segments —
effectively a different abstraction ("path", "segments", etc.). Mixing
these under a single parameter name blurs the intent and makes the API
harder to reason about.
In short:
"array_get()" with path notation does not operate on PHP arrays as defined
— it operates on a particular convention for interpreting keys. That makes
it better suited for userland libraries than for the core language.
Kind regards,
Michał Marcin Brzuchalski
sob., 4 kwi 2026, 16:07 użytkownik Barel barel.barelon@gmail.com napisał:
Hi,
I would like to open the discussion on my proposal to add two small,
focused array functions for retrieving and checking nested array elements
using dot notation.This is the link to the RFC:
https://wiki.php.net/rfc/array_get_and_array_hasThis is the link to the proposed implementation:
https://github.com/php/php-src/pull/21637Thanks!!
Carlos
On Mon, 6 Apr 2026 at 18:05, Michał Marcin Brzuchalski <
michal.brzuchalski@gmail.com> wrote:
Hi Carlos,
The proposal looks simple on the surface, but it implicitly introduces a
non-trivial policy for interpreting array keys, which is problematic at the
language level.In PHP, array keys are intentionally loose — any string is a valid key,
including ones containing dots or other separators. Introducing
"array_get()" / "array_has()" with dot-notation means that a plain string
key like "'user.name'" is no longer unambiguously a key; it may be
interpreted as a path. That creates a semantic conflict with existing,
perfectly valid data structures.This is not just a syntactic concern — it’s a shift in the data model. The
function starts encoding assumptions about how keys should be interpreted,
rather than operating on arrays as they are defined by the language.We can already see that this space is not universally agreed upon:
- Laravel and Symfony both provide similar helpers, but they use different
path semantics.- Questions like escaping, null handling, distinguishing “missing key” vs
“null value”, or supporting ArrayAccess / objects are all policy decisions,
not language primitives.Because of that, these helpers are inherently convention-driven, not
semantically neutral. Different ecosystems solve them differently, which is
a strong signal that this abstraction belongs in userland, where such
conventions can be chosen explicitly and consistently.Putting this into core would effectively standardize one arbitrary
interpretation of array paths, while PHP arrays themselves do not have such
a concept.Additionally, allowing "$key" to accept an "array" further weakens the
conceptual model. A variable named "$key" strongly implies a single scalar
identifier, while an array represents a sequence of path segments —
effectively a different abstraction ("path", "segments", etc.). Mixing
these under a single parameter name blurs the intent and makes the API
harder to reason about.In short:
"array_get()" with path notation does not operate on PHP arrays as defined
— it operates on a particular convention for interpreting keys. That makes
it better suited for userland libraries than for the core language.Kind regards,
Michał Marcin Brzuchalski
sob., 4 kwi 2026, 16:07 użytkownik Barel barel.barelon@gmail.com
napisał:Hi,
I would like to open the discussion on my proposal to add two small,
focused array functions for retrieving and checking nested array elements
using dot notation.This is the link to the RFC:
https://wiki.php.net/rfc/array_get_and_array_hasThis is the link to the proposed implementation:
https://github.com/php/php-src/pull/21637Thanks!!
Carlos
After the discussion here and after speaking to other developers, I have
decided to drop the dot notation entirely from this RFC and only leave the
option to use an array path. Using dot (or similar) notations can be easily
achieved using a simple explode or more complex code if we need to do more
complex setups like escaping. The main goal of the RFC has always been
being able to handle dynamic paths. The implementation has also been
updated and is now much simpler
Cheers
Carlos
After the discussion here and after speaking to other developers, I
have decided to drop the dot notation entirely from this RFC and only
leave the option to use an array path. Using dot (or similar) notations
can be easily achieved using a simple explode or more complex code if
we need to do more complex setups like escaping. The main goal of the
RFC has always been being able to handle dynamic paths. The
implementation has also been updated and is now much simplerCheers
Carlos
"4) Using dot or similar notations "
This should be bullet point 3, not no 4.
I agree with Tim that an invalid path segment should error in some way, rather than just using the default. If a non-int/string path segment is encountered, it 100% of the time means the developer screwed up in some way so they should know to fix it.
One of the most common uses for structure-unclear arrays I run into is (bad) APIs that have a value that is either a primitive or an array of primitives. Can you include an example showing how these functions would help in that situation?
Eg, this JSON:
{ "state": "IL" }
vs
{"state": ["IL", "CA", "NY"] }
Presumably you also have some real-world cases in mind that you've run into. Can you include versions of those in the examples to get a better sense of what usage would look like in practice?
To Tim's naming point, perhaps array_has_path() / array_get_path()? (Or maybe path first, not sure.)
--Larry Garfield
To Tim's naming point, perhaps
array_has_path()/array_get_path()? (Or maybepathfirst, not sure.)--Larry Garfield
Can we please have array_path_has() and array_path_get()? Brings a whole new world to yoda-conditionals. /s
— Rob
After the discussion here and after speaking to other developers, I
have decided to drop the dot notation entirely from this RFC and only
leave the option to use an array path. Using dot (or similar) notations
can be easily achieved using a simple explode or more complex code if
we need to do more complex setups like escaping. The main goal of the
RFC has always been being able to handle dynamic paths. The
implementation has also been updated and is now much simplerCheers
Carlos
"4) Using dot or similar notations "
This should be bullet point 3, not no 4.
I agree with Tim that an invalid path segment should error in some way,
rather than just using the default. If a non-int/string path segment is
encountered, it 100% of the time means the developer screwed up in some way
so they should know to fix it.One of the most common uses for structure-unclear arrays I run into is
(bad) APIs that have a value that is either a primitive or an array of
primitives. Can you include an example showing how these functions would
help in that situation?Eg, this JSON:
{ "state": "IL" }
vs
{"state": ["IL", "CA", "NY"] }Presumably you also have some real-world cases in mind that you've run
into. Can you include versions of those in the examples to get a better
sense of what usage would look like in practice?To Tim's naming point, perhaps
array_has_path()/array_get_path()?
(Or maybepathfirst, not sure.)--Larry Garfield
Tim, Larry
Many thanks for your thoughtful comments.
- I updated the bullet point number
- I agree that if an invalid path segment is found it is better to throw a
TypeError, this has been updated - I see the point that Tim made about the function names, I have updated
them to array_get_path() and array_has_path() - Regarding the issue of returning the default if an intermediate segment
is not an array, the philosophy of the function is: if the path exists,
return the value, otherwise return the default. This cover uses cases like
this: in yaml configuration many times you set a config option to ~ (null)
and this many times indicates "use the default config". So you may have
something like:
database:
config: ~
Indicating that you want to use the default database config. If you convert
this yaml file to an array an use the array_get_path function to get a
value, for example array_get_path($config, ['database', 'config', 'port'],
7766), you want to get 7766, not an exception or error. Tim points out that
intermediate segments might be objects which implement ArrayAccess, but
allowing this would complicate the code of the function a lot without much
practical gain.
BTW, the URL to the RFC has changed and is now
https://wiki.php.net/rfc/array_get_path_and_array_has_path
Cheers
Carlos
Hi
Am 2026-04-14 19:06, schrieb Barel:
BTW, the URL to the RFC has changed and is now
https://wiki.php.net/rfc/array_get_path_and_array_has_path
Please don't create new RFC documents for the same RFC. This breaks the
version history and is super confusing, because the link in the
discussion thread will go to an abandoned version of the RFC. In fact
you forgot to adjust the link in the RFC overview at:
https://wiki.php.net/rfc
Having an outdated name of the feature in the URL is fine - and typos
are as well. The latter happened with my #[\Override] RFC, where I
accidentally dropped the 'd' in 'overridden':
https://wiki.php.net/rfc/marking_overriden_methods. Note how I also
“described” the proposed feature in the RFC and the title - this was to
make it independent of any naming bikeshedding that might happen :-)
Best regards
Tim Düsterhus
Hi
Am 2026-04-14 19:06, schrieb Barel:
BTW, the URL to the RFC has changed and is now
https://wiki.php.net/rfc/array_get_path_and_array_has_pathPlease don't create new RFC documents for the same RFC. This breaks the
version history and is super confusing, because the link in the
discussion thread will go to an abandoned version of the RFC. In fact
you forgot to adjust the link in the RFC overview at:
https://wiki.php.net/rfcHaving an outdated name of the feature in the URL is fine - and typos
are as well. The latter happened with my #[\Override] RFC, where I
accidentally dropped the 'd' in 'overridden':
https://wiki.php.net/rfc/marking_overriden_methods. Note how I also
“described” the proposed feature in the RFC and the title - this was to
make it independent of any naming bikeshedding that might happen :-)Best regards
Tim Düsterhus
Thanks, I have recovered the previous RFC and updated it with the latest
changes
https://wiki.php.net/rfc/array_get_and_array_has
Cheers
Carlos
Hi
Am 2026-04-14 19:06, schrieb Barel:
- I see the point that Tim made about the function names, I have
updated
them to array_get_path() and array_has_path()
Similarly to Rob's tongue in cheek comment, I think I would also prefer
having a common prefix for the functions, since this improves
discoverability. While there are some inconsistencies in the array API
due to its age, I think there is a reasonably similar precedent with the
array_key_*() functions. In fact looking at those, I wonder if the
following pair of names would make sense for your proposed feature:
- array_path()
- array_path_exists()
From what I see, the functions in the array API don't mention “get” as
the default operation, e.g. it's array_first(), not
array_get_first(). And for “existence checks” there's the obvious
precedent with array_key_exists() which is also used in the example
implementation in your RFC.
- Regarding the issue of returning the default if an intermediate
segment
is not an array, the philosophy of the function is: if the path exists,
return the value, otherwise return the default. This cover uses cases
like
this: in yaml configuration many times you set a config option to ~
(null)
and this many times indicates "use the default config". So you may have
something like:database:
config: ~Indicating that you want to use the default database config. If you
convert
this yaml file to an array an use the array_get_path function to get a
value, for example array_get_path($config, ['database', 'config',
'port'],
7766), you want to get 7766, not an exception or error. Tim points out
that
intermediate segments might be objects which implement ArrayAccess, but
allowing this would complicate the code of the function a lot without
much
practical gain.
Perhaps the right solution is using “isset”-like semantics instead:
null is treated as an absent entry (it can be debated if an explicit
null at the end of the path should be treated as null rather than
the default), array allows the traversal to continue and everything else
results in a clear error. This would then allow to extend support to
anything ArrayAccess in the future without a compatibility break.
Generally “throwing an error” is always a safe option.
But saying that array_get_path(['foo' => '???'], ['foo', 'bar'], 'default'); should result in 'default' doesn't make sense to me and -
staying with the config example - might mask configuration errors:
As an example, a user might accidentally configure a "DSN":
database:
connection: "mysql://root@db.example.com"
when in reality the library expects separate components:
database:
connection:
driver: mysql
host: db.example.com
user: root
Now extracting the host with array_get_path($config, ['database', 'connection', 'host'], 'localhost') would erroneously fall back to
default values instead of reporting a clear error.
Best regards
Tim Düsterhus
Hi
Am 2026-04-14 19:06, schrieb Barel:
- I see the point that Tim made about the function names, I have
updated
them to array_get_path() and array_has_path()Similarly to Rob's tongue in cheek comment, I think I would also prefer
having a common prefix for the functions, since this improves
discoverability. While there are some inconsistencies in the array API
due to its age, I think there is a reasonably similar precedent with the
array_key_*()functions. In fact looking at those, I wonder if the
following pair of names would make sense for your proposed feature:
- array_path()
- array_path_exists()
From what I see, the functions in the array API don't mention “get” as
the default operation, e.g. it'sarray_first(), not
array_get_first(). And for “existence checks” there's the obvious
precedent witharray_key_exists()which is also used in the example
implementation in your RFC.
Tim, thanks again for your comments. I did not like using array_path._...
because the function name reads less naturally, but I agree that it
improves discoverability and is more in line with existing functions like
array_key_exists. Also agree that using exists instead of has is
better. So I updated the function names to array_path_get and
array_path_exists. I have preferred to keep get in the function name
because I think that array_path is less clear about what the function
does. RFC and implementation have been updated.
- Regarding the issue of returning the default if an intermediate
segment
is not an array, the philosophy of the function is: if the path exists,
return the value, otherwise return the default. This cover uses cases
like
this: in yaml configuration many times you set a config option to ~
(null)
and this many times indicates "use the default config". So you may have
something like:database:
config: ~Indicating that you want to use the default database config. If you
convert
this yaml file to an array an use the array_get_path function to get a
value, for example array_get_path($config, ['database', 'config',
'port'],
7766), you want to get 7766, not an exception or error. Tim points out
that
intermediate segments might be objects which implement ArrayAccess, but
allowing this would complicate the code of the function a lot without
much
practical gain.Perhaps the right solution is using “isset”-like semantics instead:
nullis treated as an absent entry (it can be debated if an explicit
nullat the end of the path should be treated asnullrather than
the default), array allows the traversal to continue and everything else
results in a clear error. This would then allow to extend support to
anything ArrayAccess in the future without a compatibility break.
Generally “throwing an error” is always a safe option.But saying that
array_get_path(['foo' => '???'], ['foo', 'bar'], 'default');should result in'default'doesn't make sense to me and -
staying with the config example - might mask configuration errors:As an example, a user might accidentally configure a "DSN":
database: connection: "mysql://root@db.example.com"when in reality the library expects separate components:
database: connection: driver: mysql host: db.example.com user: rootNow extracting the host with
array_get_path($config, ['database', 'connection', 'host'], 'localhost')would erroneously fall back to
default values instead of reporting a clear error.I am still unconvinced about this. Your proposal seems to give the
null
a special value and I think that in general the full semantics are less
clear. And I don't really like the function throwing errors for paths, I
think that this function is great for defensive access to values, where you
can be sure that you don't need to be checking the path all the time. The
existing implementations in Laravel and Lodash do not throw any error if an
intermediate value is not an array (or object for Lodash) and instead
return the default, so I think it is best to keep this behaviour
Cheers
Carlos
Hi
Am 2026-04-18 08:06, schrieb Barel:
array_path_exists. I have preferred to keepgetin the function
name
because I think thatarray_pathis less clear about what the function
does. RFC and implementation have been updated.
No strong preference regarding the _get() suffix from my side.
I am still unconvinced about this. Your proposal seems to give the
null
a special value and I think that in general the full semantics are less
null being a value indicating absence is by no means “special” in my
suggestion. As previously mentioned, it's the semantics of isset().
It's also what array_find() and array_find_key() return. It has
special syntax in types with the questionmark in ?Type. It's what you
get when you read a non-existent value.
clear. And I don't really like the function throwing errors for paths,
I
think that this function is great for defensive access to values, where
you
can be sure that you don't need to be checking the path all the time.
The
Defensive access to me also implies throwing errors where appropriate,
namely trying to perform an operation that is not meaningful. Trying to
access an array offset on a string is not meaningful and trying to do
something is not likely what the user intended to do. Similarly users
passing in ArrayAccess objects might reasonably expect them to “just
work”. Returning a default value instead of a clear error will likely
lead to them thinking they found a bug in PHP.
existing implementations in Laravel and Lodash do not throw any error
if an
intermediate value is not an array (or object for Lodash) and instead
return the default, so I think it is best to keep this behaviour
I don't think that lodash is quite comparable here, because JavaScript
is quite different to PHP in that everything is an object. Thus
_.get({"foo": "bar"}, "foo.length.toString") is meaningful (namely it
returns Number.prototype.toString()).
As for the Laravel comparison, from what I see, they do support any
ArrayAccess, so the function is also not comparable.
I've also taken another look at the RFC and have the following
additional comments:
-
The “Invalid array path segments” example is outdated,
stdClassin
the path should throw. -
The types of the path-segments should be pre-validated for consistent
error reporting. Meaning:array_path_get($array, ['foo', 'bar', new stdClass()])
should consistently throw, independent of whether $array is [],
["foo" => []], ["foo" => ["bar" => []] or something else.
- I also wonder if
$pathshould just bestring[]instead of
(int|string)[]. In the context of array keys,"123"is equivalent to
123anyways.
Best regards
Tim Düsterhus
Hi
Am 2026-04-18 08:06, schrieb Barel:
I am still unconvinced about this. Your proposal seems to give the
null
a special value and I think that in general the full semantics are lessnull being a value indicating absence is by no means “special” in my
suggestion. As previously mentioned, it's the semantics ofisset().
It's also whatarray_find()andarray_find_key()return. It has
special syntax in types with the questionmark in?Type. It's what you
get when you read a non-existent value.clear. And I don't really like the function throwing errors for paths,
I
think that this function is great for defensive access to values, where
you
can be sure that you don't need to be checking the path all the time.
TheDefensive access to me also implies throwing errors where appropriate,
namely trying to perform an operation that is not meaningful. Trying to
access an array offset on a string is not meaningful and trying to do
something is not likely what the user intended to do. Similarly users
passing inArrayAccessobjects might reasonably expect them to “just
work”. Returning a default value instead of a clear error will likely
lead to them thinking they found a bug in PHP.
Just to make sure we're talking about the same thing here. Tim, you're suggesting that this:
$a = ['foo' => 'bar'];
$val = array_path_get($a, ['foo', 'bar', 'baz']);
Should error rather than returning null?
If so, then I do not agree. The purpose of these functions, as I see it, is for dealing with inconsistently structured, wonky, arguably stupidly-designed data. (Which is a lot of REST APIs in the wild, sadly.) If the array were clearly, consistently, and properly structured, we could reliably just do $a['foo']['bar'] and move on with life. Or trivially convert it to a properly typed object. These functions are for cases where those are not viable or convenient options, meaning cases where a given value could be a string or an array, because the data model author hates you. (As noted in a previous reply, I have run into such structures where the value of a JSON key is string|string{}. It bloody well sucks.)
So in that sort of case, I'm not sure it's useful to distinguish between "There is no baz key on the array at foo.bar" and "foo.bar is a string, not an array, wat?" If that was a distinction that mattered, I'd be using ?? or converting to an object or whatever else already.
--Larry Garfield
Hi
Am 2026-04-20 17:18, schrieb Larry Garfield:
Just to make sure we're talking about the same thing here. Tim, you're
suggesting that this:$a = ['foo' => 'bar'];
$val = array_path_get($a, ['foo', 'bar', 'baz']);Should error rather than returning null?
Yes.
If the array were clearly, consistently, and properly structured, we
could reliably just do $a['foo']['bar'] and move on with life.
[…]
So in that sort of case, I'm not sure it's useful to distinguish
between "There is no baz key on the array at foo.bar" and "foo.bar is a
string, not an array, wat?" […]
The goal of the RFC is replacing $a['foo']['bar'] where the path is
dynamic. Quoting right from the introduction of the RFC:
When the structure of the array is known in advance and the exact
element to retrieve is hardcoded, existing PHP syntax works well […]
And quoting further from the introduction:
array_path_get() retrieves a value from a deeply nested array and
returns a default value if the path does not exist.
I'm arguing that a “(value at) path does not exist” is something
fundamentally different from “value encountered on path cannot be
traversed further”.
converting to an object
I agree that the correct solution in the general case is “use a proper
object mapper” (such as Valinor) and don't see much personal value in
having the proposed functions. But if they exist, I would want them to
behave as safely as possible and that includes erroring if they cannot
make sense of the data. Emitting a Warning when encountering an
improperly typed value across the path would also work for me, but I
suppose that others won't be in favor of that :-)
Best regards
Tim Düsterhus
Hi
Am 2026-04-04 16:06, schrieb Barel:
This is the link to the RFC:
https://wiki.php.net/rfc/array_get_and_array_has
Thank you for your RFC.
I find it not obvious at all that:
- Non-(string|int) path segments will result in the default value being
returned, rather than a TypeError being thrown or just proceeding with
implicit coercion. - Encountering a non-array value along the path will result in the
default value being returned, rather than an Exception being thrown.
Returning a default value for an existing path element that is not an
array feels like a source of error, particularly when any intermediate
value is an object implementing ArrayAccess.
I would expect the following to hold:
$path = ['foo', 'bar', 'baz'];
array_get($array, $path) === array_get(array_get($array,
array_shift($path), []), $path);
which it will not due to (2).
And the further looking at the examples:
$array = /* … */;
array_has($array, ['product', 'name']);
array_has($array, ['product', 'color']);
Just looking at the code without knowing what the function does, I
probably would have expected it to be either:
-
in_array()operating on multiple values that all need to be there. -
array_key_exists()operating on multiple keys that all need to be
there.
But not a “path through the array”.
Best regards
Tim Düsterhus