Re: [RFC] [Discussion] array_get and array_has functions

From: Date: Sat, 18 Apr 2026 06:06:54 +0000
Subject: Re: [RFC] [Discussion] array_get and array_has functions
References: 1 2 3 4 5 6  Groups: php.internals 
Request: Send a blank email to internals+get-130664@lists.php.net to get a copy of this message
On Wed, 15 Apr 2026 at 20:18, Tim Düsterhus <tim@bastelstu.be> wrote: > 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. > 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: > 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. > > 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

« previous php.internals (#130664) next »