# array_reduce callback key

- Thread: https://externals.io/message/124450
- Original archive: https://news-web.php.net/php.internals/124450
- Started by Bilge on 2024-07-16T23:14:41+00:00
- Messages: 9
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #124450 — Bilge — 2024-07-16T23:14:41+00:00

URL: https://externals.io/message/124450#124450

Hi Internals,

I just ran into a case where I needed the array key in an `array_reduce()` 
callback, but I can't access it :(

So I wrote a PR to fix it: https://github.com/php/php-src/pull/14986

What do you think? Does this need an RFC?

Cheers,
Bilge

---

## #124451 — mickmackusa — 2024-07-17T00:29:34+00:00

URL: https://externals.io/message/124450#124451 · In reply to: #124450

This is not the first time that a developer needs access to the input
array's keys within the callback of `array_reduce()`.
It is untrue that you "can't access it"; you just need to use an array of
keys as the input array.

Some frameworks already have the feature of key access built into their
methods/functions.
https://laravel.com/docs/11.x/collections#method-reduce

Examples of passing array_keys to array_reduce (some of which are more than
a decade old):
https://stackoverflow.com/a/10196070/2943403
https://stackoverflow.com/a/27419768/2943403
https://stackoverflow.com/a/27809675/2943403
https://stackoverflow.com/a/32226816/2943403
https://stackoverflow.com/a/33372066/2943403
https://stackoverflow.com/a/37728665/2943403
https://stackoverflow.com/a/39322532/2943403
https://stackoverflow.com/a/45508817/2943403
https://stackoverflow.com/a/48664250/2943403
https://stackoverflow.com/a/49035053/2943403
https://stackoverflow.com/a/57966850/2943403
https://stackoverflow.com/a/58997848/2943403
https://stackoverflow.com/a/73726419/2943403
https://stackoverflow.com/a/76196482/2943403

mickmackusa




> Hi Internals,
>
> I just ran into a case where I needed the array key in an `array_reduce()`
> callback, but I can't access it :(
>
> So I wrote a PR to fix it: https://github.com/php/php-src/pull/14986
>
> What do you think? Does this need an RFC?
>
> Cheers,
> Bilge

---

## #124452 — Bilge — 2024-07-17T00:35:31+00:00

URL: https://externals.io/message/124450#124452 · In reply to: #124451

> It is untrue that you "can't access it"; you just need to use an array of
> keys as the input array.
>
> > […]
doesn't work at all when you also need the value.

Cheers,
Bilge

---

## #124453 — Levi Morrison — 2024-07-17T00:41:06+00:00

URL: https://externals.io/message/124450#124453 · In reply to: #124450

>
> Hi Internals,
>
> I just ran into a case where I needed the array key in an `array_reduce()`
> callback, but I can't access it :(
>
> So I wrote a PR to fix it: https://github.com/php/php-src/pull/14986
>
> What do you think? Does this need an RFC?
>
> Cheers,
> Bilge

I don't think it's reasonable to cover every use-case "nicely" in the
standard library. You didn't give a real example. You might consider
using array_walk or iterator_apply, or a foreach loop depending on
what you need.

I am curious what your real use-case is. It may be worth adding
something. It might not. Hard to tell. Adding arguments to a function
can mess up internal callbacks, btw, so I don't like modifying the
existing function.

---

## #124454 — Lily Bergonzat — 2024-07-17T07:55:20+00:00

URL: https://externals.io/message/124450#124454 · In reply to: #124452

While it *is* indeed a workaround, you can very easily
access the values of the array from the keys, since that
literally is what the keys are for.

While I also think it's weird that not all php array functions
with callbacks do pass the key as an argument, and while
I also stumbled upon that problem in the past myself
multiple times, I also think it is worth taking the time to
consider what other people from this mailing list are
bringing up. If it could indeed break internal callbacks,
then I think using the workaround could be a better idea
than potentially breaking other things.


>
> 
> > […]
>
> It is absolutely true and your workaround is just that; a workaround that doesn't work at all when you also need the value.
>
> Cheers,
> Bilge

---

## #124455 — Rob Landers — 2024-07-17T08:07:52+00:00

URL: https://externals.io/message/124450#124455 · In reply to: #124454

> While it *is* indeed a workaround, you can very easily
> access the values of the array from the keys, since that
> literally is what the keys are for.
> 
> While I also think it's weird that not all php array functions
> with callbacks do pass the key as an argument, and while
> I also stumbled upon that problem in the past myself
> multiple times, I also think it is worth taking the time to
> consider what other people from this mailing list are
> bringing up. If it could indeed break internal callbacks,
> then I think using the workaround could be a better idea
> than potentially breaking other things.
> 
> 
> > […]
> 

If it can be the last argument, then PHP doesn't care if you call a function with extra arguments ... at least, it usually doesn't.

— Rob

---

## #124456 — Lily Bergonzat — 2024-07-17T08:20:01+00:00

URL: https://externals.io/message/124450#124456 · In reply to: #124455

It would make sense for it to be the last argument. My first thought was also
that PHP doesn't usually care if you add extra arguments, but "internal
callbacks" made me think they were C callbacks, and in that case I don't
really know.


>
> 
>
> While it *is* indeed a workaround, you can very easily
> access the values of the array from the keys, since that
> literally is what the keys are for.
>
> While I also think it's weird that not all php array functions
> with callbacks do pass the key as an argument, and while
> I also stumbled upon that problem in the past myself
> multiple times, I also think it is worth taking the time to
> consider what other people from this mailing list are
> bringing up. If it could indeed break internal callbacks,
> then I think using the workaround could be a better idea
> than potentially breaking other things.
>
> 
> > […]
>
>
> If it can be the last argument, then PHP doesn't care if you call a function with extra arguments ... at least, it usually doesn't.
>
> — Rob

---

## #124457 — Bilge — 2024-07-17T09:01:33+00:00

URL: https://externals.io/message/124450#124457 · In reply to: #124453

> Adding arguments to a function can mess up internal callbacks, btw, so I don't like modifying the
> existing function.

Which internal callbacks can be messed up by this change? They clearly 
aren't tested, as the build is passing.

Cheers,
Bilge

---

## #124458 — Larry Garfield — 2024-07-17T14:01:55+00:00

URL: https://externals.io/message/124450#124458 · In reply to: #124457

> 
> > […]
> Which internal callbacks can be messed up by this change? They clearly 
> aren't tested, as the build is passing.
>
> Cheers,
> Bilge

There's a number of issues here.

PHP-defined functions ignore excess arguments.

C-defined functions error on excess arguments.

A function with an optional second argument... may break if it gets passed an optional argument that isn't aligned with its expectation.  `intval()` is the usual example (https://www.php.net/intval), but it would also impact something like `trim()`.  If someone is using a function with one param and one optional param as a callback right now, suddenly passing the key as the second argument could cause all sorts of weirdness.

Similarly, if someone is using a single-param C-defined function as a callback right now, and `array_reduce()` starts passing a second argument, it will fatal.

I ran into this issue while building Crell/fp, and my only solution (after swearing a lot) was to just make two separate versions of every operation: One that passes the key and one that doesn't.  (cf: https://github.com/Crell/fp/blob/master/src/array.php)  The user has to pick the right one.  That is, sadly, the only reliable solution, even if done in the stdlib.

(Of course, the real solution is to introduce a separate map/dict type that has its own dedicated API for map/filter/reduce, but now we're well out of scope...  Using the same structure for lists and maps is PHP's original sin.)

--Larry Garfield
