[PHP-DEV] [RFC] [Discussion] array_get and array_has functions

On Mon, Apr 6, 2026, at 10:01 AM, Barel wrote:

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

Please remember to bottom post. :slight_smile:

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.

1. 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.

2. 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

On Mon, 6 Apr 2026 at 18:12, Larry Garfield <larry@garfieldtech.com> wrote:

On Mon, Apr 6, 2026, at 10:01 AM, Barel wrote:

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

Please remember to bottom post. :slight_smile:

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.

  1. 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.

  2. 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

On Monday 06 April 2026 18:21:20 (+02:00), Barel wrote:

> 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

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_has

This is the link to the proposed implementation: https://github.com/php/php-src/pull/21637

Thanks!!

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