# [RFC][Under Discussion] Add functions array_key_first() and array_key_last()

- Thread: https://externals.io/message/102245
- Original archive: https://news-web.php.net/php.internals/102245
- Started by Enno Woortmann on 2018-06-13T19:26:55+00:00
- Messages: 36
- RFC: array_key_first(), array_key_last() (Implemented (PHP 7.3)) — https://externals.io/rfc/array_key_first_last.md
- Page 1 of 2: messages 1 to 25 (25 per page, add `?page=N` to the URL)
- Next page: https://externals.io/message/102245.md?page=2
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · RFCs at https://externals.io/rfc.md · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #102245 — Enno Woortmann — 2018-06-13T19:26:55+00:00

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

Hello internals,

I've changed the status of the currently introduced RFC to add the 
functions `array_key_first()` and `array_key_last()` to "Under Discussion".

https://wiki.php.net/rfc/array_key_first_last

Regards,

Enno

---

## #102248 — Christoph M. Becker — 2018-06-13T21:10:34+00:00

URL: https://externals.io/message/102245#102248 · In reply to: #102245

> I've changed the status of the currently introduced RFC to add the
> functions `array_key_first()` and `array_key_last()` to "Under Discussion".
> 
> https://wiki.php.net/rfc/array_key_first_last

Thanks for working on this, Enno!

I suggest to address Côme's suggestion[1] on this mailing list and
especially in the RFC (the template[2] offers “Open Issues” and
“Rejected Features” sections).

[1] <https://externals.io/message/102225#102232>

-- 
Christoph M. Becker

---

## #102269 — Enno Woortmann — 2018-06-14T22:27:19+00:00

URL: https://externals.io/message/102245#102269 · In reply to: #102248

Hi,



> I suggest to address Côme's suggestion[1] on this mailing list and
> especially in the RFC (the template[2] offers “Open Issues” and
> “Rejected Features” sections).
>
> [1] <https://externals.io/message/102225#102232>
>

I've added the "Open Issues" section to the RFC and added the idea of Côme and Gabriel to add the corresponding functions for handling the values of the outer elements of an array to provide a complete set of functions.
Currently I see three possibilities to handle the idea. Either extend the scope of the RFC to cover also the handling of the values, which could be implemented rather fast and by reusing a lot of code as the current implementation already gathers the bucket for the first/last element of an array, or move this idea to a future scope which should be covered by a separate RFC. The third alternative would be to skip the implementation of the corresponding functions.

In my opinion it's a good idea to complete the function set by also providing functions for the handling of array values. Both opportunities which would lead to the completed set are practicable in my view.

Any opinions concerning this issue?

Good night (or day, wherever you are ;) ),
Enno

---

## #102279 — niel — 2018-06-15T15:37:20+00:00

URL: https://externals.io/message/102245#102279 · In reply to: #102245

> Hello internals,
> 
> I've changed the status of the currently introduced RFC to add the 
> functions `array_key_first()` and `array_key_last()` to "Under Discussion".
> 
> https://wiki.php.net/rfc/array_key_first_last
> 
> Regards,
> 
> Enno

What is the behaviour if the array does not exist? From the current RFC 
it appears it would return null? Wouldn't it be better to return false 
for this situation?

Niel

---

## #102280 — Enno Woortmann — 2018-06-15T17:58:46+00:00

URL: https://externals.io/message/102245#102280 · In reply to: #102279

Hi niel,


On 15.06.2018 at 17:37 niel wrote:
> What is the behaviour if the array does not exist? From the current 
> RFC it appears it would return null? Wouldn't it be better to return 
> false for this situation?
>

Thanks for the comment. Why do you think false would be a better return 
value?

Currently if the given value isn't an array or no parameter is given a 
warning will be thrown and null will be returned.
In my opinion null exists to show the absence of a defined value. If one 
of the proposed functions is called with a variable which isn't an array 
or an empty array (or even a call with no parameter) there is neither a 
first nor a last key and thus null is the value which is returned.
Compare the tests for the error cases:
https://github.com/php/php-src/pull/3256/files#diff-e00a584724b997f38e851e15f1e20c39

This behavior is also implemented in existing functions like eg. 
 `array_pop()`:
https://github.com/php/php-src/blob/master/ext/standard/tests/array/array_pop_errors.phpt

Enno

---

## #102283 — Alice Wonder — 2018-06-17T20:16:24+00:00

URL: https://externals.io/message/102245#102283 · In reply to: #102279

> 
> > […]
>
> What is the behaviour if the array does not exist? From the current RFC
> it appears it would return null? Wouldn't it be better to return false
> for this situation?
>

I don't like throwing false when something doesn't exist.

apcu does that - returns false instead of null when a record doesn't 
exist, and it is very problematic when the stored value literally is false.

granted a boolean can't be used for an array key, but still, if there 
isn't something to return than null is better than a boolean.

boolean is a value, null is the absence of a value, which is more 
accurate, no?

---

## #102285 — Enno Woortmann — 2018-06-17T22:09:11+00:00

URL: https://externals.io/message/102245#102285 · In reply to: #102283

Hi Alice,


Am 17.06.2018 um 22:16 schrieb Alice Wonder:
> boolean is a value, null is the absence of a value, which is more 
> accurate, no?

In my opinion that's the argument to return null for either parameters 
which aren't an array or empty arrays simply because a first/last key 
isn't present and null is the value to be returned for an undefined state.
I've tested this behavior with other array_* functions which are 
provided in the PHP core and they provide null consistently, eg.:

root@WOL-Soft-DEVVM:/var/www/WOL-Soft# php -r "var_dump(array_keys(1));"
PHP Warning:  `array_keys()` expects parameter 1 to be array, integer 
given in Command line code on line 1
 `NULL` 
root@WOL-Soft-DEVVM:/var/www/WOL-Soft# php -r 
"var_dump(array_values('hello'));"
PHP Warning:  `array_values()` expects parameter 1 to be array, string 
given in Command line code on line 1
 `NULL` 
root@WOL-Soft-DEVVM:/var/www/WOL-Soft# php -r "var_dump(array_flip(null));"
PHP Warning:  `array_flip()` expects parameter 1 to be array, null given 
in Command line code on line 1
 `NULL` 

There was another remark which wasn't sent to the internals mail list 
but to my personal mail account (mehh :( ) which supported to return false:

"because a lot of functions act the way returning false when things go
wrong even when they normally only would return string/int/array which
should be justification enough: consistency"

An example for this argument was the function strpos which may be 
checked with === or !== against false.
But the real discussion about the return value and the facility of 
comparison against another value is only interesting if we extend the 
scope of this RFC to cover also array_value_(first|last), as null as an 
array key is not supported and will be casted to an empty string. Due to 
this internal handling of array keys, null is for the functions 
array_key(first|last) an unique return value to evaluate failures.

My opinion about this subject supports your argument as null is the 
value which should be returned if the requested value is not defined. If 
a variable which is neither an array nor an array with entries is passed 
neither the first/last key nor the first/last value is a defined value 
and thus null should be the return value.

Especially if we decide to extend the scope of this RFC to cover also 
array_value_(first|last) there is no possibility to provide a return 
value which doesn't collide with a possible array value. If cases occur 
which may resolve into a collision, the usage of functions like 
 `is_array()` and empty()/count() is inevitable as both null and false are 
valid values for an array value. To argument with the semantic of false 
and null the correct return value should be null for each of the 
proposed functions (as well the proposed functions which are currently 
covered by the RFC as the extended version which also covers the methody 
array_value(first|last) ) as null defines an undefined value.

Regards,
Enno

---

## #102288 — niel — 2018-06-17T23:59:29+00:00

URL: https://externals.io/message/102245#102288 · In reply to: #102285

> Hi Alice,
> 
> 
> Am 17.06.2018 um 22:16 schrieb Alice Wonder:
> > […]
> 
> In my opinion that's the argument to return null for either parameters 
> which aren't an array or empty arrays simply because a first/last key 
> isn't present and null is the value to be returned for an undefined state.
> I've tested this behavior with other array_* functions which are 
> provided in the PHP core and they provide null consistently, eg.:
> 
> root@WOL-Soft-DEVVM:/var/www/WOL-Soft# php -r "var_dump(array_keys(1));"
> PHP Warning:  `array_keys()` expects parameter 1 to be array, integer 
> given in Command line code on line 1
> `NULL` 
> root@WOL-Soft-DEVVM:/var/www/WOL-Soft# php -r 
> "var_dump(array_values('hello'));"
> PHP Warning:  `array_values()` expects parameter 1 to be array, string 
> given in Command line code on line 1
> `NULL` 
> root@WOL-Soft-DEVVM:/var/www/WOL-Soft# php -r "var_dump(array_flip(null));"
> PHP Warning:  `array_flip()` expects parameter 1 to be array, null given 
> in Command line code on line 1
> `NULL` 
> 
> There was another remark which wasn't sent to the internals mail list 
> but to my personal mail account (mehh :( ) which supported to return false:
> 
> "because a lot of functions act the way returning false when things go
> wrong even when they normally only would return string/int/array which
> should be justification enough: consistency"
> 
> An example for this argument was the function strpos which may be 
> checked with === or !== against false.
> But the real discussion about the return value and the facility of 
> comparison against another value is only interesting if we extend the 
> scope of this RFC to cover also array_value_(first|last), as null as an 
> array key is not supported and will be casted to an empty string. Due to 
> this internal handling of array keys, null is for the functions 
> array_key(first|last) an unique return value to evaluate failures.
> 
> My opinion about this subject supports your argument as null is the 
> value which should be returned if the requested value is not defined. If 
> a variable which is neither an array nor an array with entries is passed 
> neither the first/last key nor the first/last value is a defined value 
> and thus null should be the return value.
> 
> Especially if we decide to extend the scope of this RFC to cover also 
> array_value_(first|last) there is no possibility to provide a return 
> value which doesn't collide with a possible array value. If cases occur 
> which may resolve into a collision, the usage of functions like 
> `is_array()` and empty()/count() is inevitable as both null and false are 
> valid values for an array value. To argument with the semantic of false 
> and null the correct return value should be null for each of the 
> proposed functions (as well the proposed functions which are currently 
> covered by the RFC as the extended version which also covers the methody 
> array_value(first|last) ) as null defines an undefined value.
> 
> Regards,
> Enno

Hi, I didn't reply to your question as to why I thought false would be a 
better return value for non-array, as I thought Reindl covered my 
feelings completely.

Given the points made by Alice and yourself I've reconsidered 'false' 
being a better choice than 'null', as it might be a valid return value 
from the array.

However my main concern that a non-array variable or a non-existent 
value, are an error and need to be handled appropriately, has not 
changed. IMO, a notice/warning does little to nothing in helping the 
programmer determine the problem and track down the cause. Which leaves 
one having to wrap these functions in 'if (is_array($var) && 
!empty($var)) {...}' to prevent the possibility.

Niel

---

## #102289 — Enno Woortmann — 2018-06-18T00:34:01+00:00

URL: https://externals.io/message/102245#102289 · In reply to: #102288

Hi niel,

Am 18.06.2018 um 01:59 schrieb niel:
> However my main concern that a non-array variable or a non-existent 
> value, are an error and need to be handled appropriately, has not 
> changed. IMO, a notice/warning does little to nothing in helping the 
> programmer determine the problem and track down the cause. Which 
> leaves one having to wrap these functions in 'if (is_array($var) && 
> !empty($var)) {...}' to prevent the possibility.

The current implementation is eqivalent to the other array_* functions 
as shown in the previous mail and can be checked in
https://github.com/php/php-src/pull/3256/commits/ec2332be93272d202a2a5cef841c266f77f64b08#diff-e00a584724b997f38e851e15f1e20c39

I can comprehend your doubts about the return value but currently I 
can't imagine a solution which would suite the case better than null 
especially if we think about extending the scope to 
array_value_(first|last).
Do you/anyone have an idea how we can provide better information towards 
the programmer to determine the issue?

Enno

---

## #102293 — Christoph M. Becker — 2018-06-18T09:25:27+00:00

URL: https://externals.io/message/102245#102293 · In reply to: #102285

> In my opinion that's the argument to return null for either parameters
> which aren't an array or empty arrays simply because a first/last key
> isn't present and null is the value to be returned for an undefined state.
> I've tested this behavior with other array_* functions which are
> provided in the PHP core and they provide null consistently, eg.:
> 
> root@WOL-Soft-DEVVM:/var/www/WOL-Soft# php -r "var_dump(array_keys(1));"
> PHP Warning:  `array_keys()` expects parameter 1 to be array, integer
> given in Command line code on line 1
> `NULL` 
> root@WOL-Soft-DEVVM:/var/www/WOL-Soft# php -r
> "var_dump(array_values('hello'));"
> PHP Warning:  `array_values()` expects parameter 1 to be array, string
> given in Command line code on line 1
> `NULL` 
> root@WOL-Soft-DEVVM:/var/www/WOL-Soft# php -r "var_dump(array_flip(null));"
> PHP Warning:  `array_flip()` expects parameter 1 to be array, null given
> in Command line code on line 1
> `NULL` 

These return values are due to zend_parse_parameters() failures (i.e.
the given types don't match the expected types), and it's customary to
return `NULL` in this case (under strict typing an exception would be
thrown instead).  However, most functions signal other failures by
returning FALSE, for instance:

  var_dump(array_search('foo', [])); // => bool(false)

I would prefer, if these other functions would return NULL, though, but
we can't change that for BC reasons.

-- 
Christoph M. Becker

---

## #102297 — Larry Garfield — 2018-06-18T15:32:38+00:00

URL: https://externals.io/message/102245#102297 · In reply to: #102293

> 
> > […]
> 
> These return values are due to zend_parse_parameters() failures (i.e.
> the given types don't match the expected types), and it's customary to
> return `NULL` in this case (under strict typing an exception would be
> thrown instead).  However, most functions signal other failures by
> returning FALSE, for instance:
> 
>   var_dump(array_search('foo', [])); // => bool(false)
> 
> I would prefer, if these other functions would return NULL, though, but
> we can't change that for BC reasons.

Returning false for "not found" rather than "null" is a big middle-finger to 
users. :-)  Besides the reasons here, the violation of type constraints 
totally screws up the surrounding code.  Especially with null-coalesce.  For 
instance, this thing of beauty:

$secret = getenv('APP_SECRET') 
  ?? $_SERVER['APP_SECRET'] 
  ?? getenv('DEFAULT_SECRET')
;

doesn't actually work, because `getenv()` returns false instead of null.  
Instead you have to do this mess:

$secret = (getenv('APP_SECRET') ?: null)
        ?? $_SERVER['APP_SECRET']
        ?? (getenv('DEFAULT_SECRET') ?: null)
    ;

See also:

https://www.garfieldtech.com/blog/empty-return-values

Can we please never return false for error/not-found, ever, period, forever 
more?  It's a fundamentally broken idiom that needs to die.

--Larry Garfield

---

## #102298 — Christoph M. Becker — 2018-06-18T17:05:48+00:00

URL: https://externals.io/message/102245#102298 · In reply to: #102297

> Can we please never return false for error/not-found, ever, period, forever 
> more?  It's a fundamentally broken idiom that needs to die.

“But wait!” some cry.  “What about consistency with existing functions?”

-- 
Christoph M. Becker

---

## #102301 — Woortmann — 2018-06-19T12:00:57+00:00

URL: https://externals.io/message/102245#102301 · In reply to: #102269

Hello internals,

> I've added the "Open Issues" section to the RFC and added the idea of 
> Côme and Gabriel to add the corresponding functions for handling the 
> values of the outer elements of an array to provide a complete set of 
> functions.
> Currently I see three possibilities to handle the idea. Either extend 
> the scope of the RFC to cover also the handling of the values, which 
> could be implemented rather fast and by reusing a lot of code as the 
> current implementation already gathers the bucket for the first/last 
> element of an array, or move this idea to a future scope which should 
> be covered by a separate RFC. The third alternative would be to skip 
> the implementation of the corresponding functions.
>
> In my opinion it's a good idea to complete the function set by also 
> providing functions for the handling of array values. Both 
> opportunities which would lead to the completed set are practicable in 
> my view.

I've extended the scope of the RFC to cover additionally the functions 
array_value_first($array) and array_value_last($array).
The updated RFC is still available at 
https://wiki.php.net/rfc/array_key_first_last 
<https://deref-web-02.de/mail/client/3lM0ZbRqSMo/dereferrer/?redirectUrl=https%3A%2F%2Fwiki.php.net%2Frfc%2Farray_key_first_last>
I've added a commit to the pull request located at 
https://github.com/php/php-src/pull/3256 
<https://deref-web-02.de/mail/client/bEY-xQctqjI/dereferrer/?redirectUrl=https%3A%2F%2Fgithub.com%2Fphp%2Fphp-src%2Fpull%2F3256> to 
add the implementation and the tests for the extended scope.
Regards,
Enno

---

## #102314 — Levi Morrison — 2018-06-20T02:47:01+00:00

URL: https://externals.io/message/102245#102314 · In reply to: #102297

I don't think I'm getting all the mail I am supposed to. I hope this gets seen.

I propose 2 functions *only* which I believe covers the use-cases that
all 4 of these do and more, with shorter names, and the ability to
discern whether the call succeeded or not.

    list($key, $value) = array_first($input);
    // $key will be null if the call failed

    list($key, $value) = array_last($input);
    // $key will be null if the call failed

I have tested it with user-land functions and seems to work as
intended in all success and failure conditions. Verification that it
works as intended with internal functions is necessary but this seems
a much better proposal to me.

---

## #102317 — Woortmann — 2018-06-20T09:17:39+00:00

URL: https://externals.io/message/102245#102317 · In reply to: #102314

Hi Levi,


Am 20.06.2018 um 04:47 schrieb Levi Morrison:
>      list($key, $value) = array_first($input);
>      // $key will be null if the call failed
>
>      list($key, $value) = array_last($input);
>      // $key will be null if the call failed

Your proposed functions would be implementable with the internal 
functions but I think this approach doesn't provide a clean function 
interface as it forces the user to evaluate the wanted value from the 
returned array structure by using either the list() construct or 
something like $key = array_first($input)[0];

I believe two functions with this interface will be confusing and less 
intuitive for the developer.
If I use a function I expect it to give me a return value which I can 
use without any further post processing $wantedValue = 
fancyFunction($someInput);

Enno

---

## #102320 — Gabriel Caruso — 2018-06-20T12:20:24+00:00

URL: https://externals.io/message/102245#102320 · In reply to: #102314

>
>  don't think I'm getting all the mail I am supposed to. I hope this gets
> seen.
>
> I propose 2 functions *only* which I believe covers the use-cases that
> all 4 of these do and more, with shorter names, and the ability to
> discern whether the call succeeded or not.
>
>     list($key, $value) = array_first($input);
>     // $key will be null if the call failed
>
>     list($key, $value) = array_last($input);
>     // $key will be null if the call failed
>
> I have tested it with user-land functions and seems to work as
> intended in all success and failure conditions. Verification that it
> works as intended with internal functions is necessary but this seems
> a much better proposal to me.
>
> --
> 
> 


Hi Levi.

I have plans to bring an `array_find_first` and `array_find_last` to the
next PHP 7.x. It will basically work:

    $firstUserWithUsername = array_find_first(function (User $user): bool {
        return $user->username !== null;
    }, $users);

Just wanted to point that to alert that someone is working on that :)
-- 
Gabriel Caruso

---

## #102321 — Levi Morrison — 2018-06-20T13:55:00+00:00

URL: https://externals.io/message/102245#102321 · In reply to: #102317

>
> Hi Levi,
>
>
> Am 20.06.2018 um 04:47 schrieb Levi Morrison:
> > […]
>
> Your proposed functions would be implementable with the internal
> functions but I think this approach doesn't provide a clean function
> interface as it forces the user to evaluate the wanted value from the
> returned array structure by using either the list() construct or
> something like $key = array_first($input)[0];
>
> I believe two functions with this interface will be confusing and less
> intuitive for the developer.
> If I use a function I expect it to give me a return value which I can
> use without any further post processing $wantedValue =
> fancyFunction($someInput);

Your wish cannot be granted for `array_value_last` and
`array_value_first`; you cannot know by itself if there is a failure
condition. As proposed you have to write:

    if (!empty($input)) {
        $value = array_value_last($input)
        // do something
    }

This is not "clean". In contrast here is with my proposal:

    if ([$key, $value] = array_last($input) {
        // do something
    }

If I need the last/first key and value (which is a real use-case and
why I thought of this in the first place) then in your proposal I have
to do:

    if (!empty($input)) {
        $key = array_key_last($input);
        $value = array_value_last($input);
   }

Or use the key to get the value; roughly the same amount of code.
Either way is not as clean as:

    if ([$key, $value] = array_last($input) {
        // do something
    }

Hopefully I have shown that for various use-cases the proposed
interface is cleaner and that you cannot argue against it on those
grounds.

Adding 4 functions which cover 4 use-cases, with ugly names, and 2 of
them having poor failure semantics is not a good direction. Adding
only 2 functions which cover 6 use-cases, with nice names, and good
failure conditions is better. Please reconsider.

---

## #102322 — Nicolas Grekas — 2018-06-20T14:06:46+00:00

URL: https://externals.io/message/102245#102322 · In reply to: #102321

>     if ([$key, $value] = array_last($input) {
>

+1 for this proposal, I would even go one step further and suggest a single
function, with an index as second argument:

`if ([$key, $value] = array_index($input, $index) {`

when `0 === $index` => returns the first, `-1 === $index` returns the last,
etc.

---

## #102323 — Rowan Collins — 2018-06-20T14:09:21+00:00

URL: https://externals.io/message/102245#102323 · In reply to: #102321

>
>     if ([$key, $value] = array_last($input) {
>         // do something
>     }
>
>

Unfortunately, this won't work. I didn't know list() could even be used as
an expression, but apparently if it is, it evaluates to the whole array on
its right-hand side, which makes sense.

So, if array_last([]) returns [null, null], then [$key,
$value]=array_last([]) will also evaluate to [null, null]. Since that's not
an empty array (it has two elements in it), it will evaluate to true.
https://3v4l.org/lIEa1

If, on the other hand, array_last([]) returned something empty, like [],
the list() assignment would throw Notices for the implicit access to
elements [0] and [1] of the empty array. https://3v4l.org/qhq5R

Regards,
-- 
Rowan Collins
[IMSoP]

---

## #102324 — Levi Morrison — 2018-06-20T14:10:44+00:00

URL: https://externals.io/message/102245#102324 · In reply to: #102323

>
> 
> > […]
>
>
> Unfortunately, this won't work. I didn't know list() could even be used as an expression, but apparently if it is, it evaluates to the whole array on its right-hand side, which makes sense.
>
> So, if array_last([]) returns [null, null], then [$key, $value]=array_last([]) will also evaluate to [null, null]. Since that's not an empty array (it has two elements in it), it will evaluate to true. https://3v4l.org/lIEa1
>
> If, on the other hand, array_last([]) returned something empty, like [], the list() assignment would throw Notices for the implicit access to elements [0] and [1] of the empty array. https://3v4l.org/qhq5R

It returns `?array`. So either `null` or `[$key, $value]`. There are
no notices; sorry for the lack of detail.

---

## #102325 — Nicolas Grekas — 2018-06-20T14:12:40+00:00

URL: https://externals.io/message/102245#102325 · In reply to: #102324

> It returns `?array`. So either `null` or `[$key, $value]`. There are
> no notices; sorry for the lack of detail.
>

See https://3v4l.org/2hX3Y for example

---

## #102326 — Rowan Collins — 2018-06-20T14:24:34+00:00

URL: https://externals.io/message/102245#102326 · In reply to: #102324

> On Wed, Jun 20, 2018 at 8:09 AM Rowan Collins <rowan.collins@gmail.com>
> wrote:
> > […]
> as an expression, but apparently if it is, it evaluates to the whole array
> on its right-hand side, which makes sense.
> > […]
> $value]=array_last([]) will also evaluate to [null, null]. Since that's not
> an empty array (it has two elements in it), it will evaluate to true.
> https://3v4l.org/lIEa1
> > […]
> the list() assignment would throw Notices for the implicit access to
> elements [0] and [1] of the empty array. https://3v4l.org/qhq5R
>
> It returns `?array`. So either `null` or `[$key, $value]`. There are
> no notices; sorry for the lack of detail.
>


Ah, OK, you learn something every day! For anyone else like me who was
unaware of this, list() apparently silently accepts any non-array value on
the right of the assignment, assigns all variables in the list() to null,
and evaluates to the assigned (but otherwise unused) value. So
$x=list($a,$b)=42; will set $a and $b to NULL, and $x to 42, without any
notices.

I don't think I would ever have expected that behaviour, but apparently
it's been that way forever, so I guess it's fine to exploit it.

Incidentally, there's no mention of this on the manual page, which is also
missing information on the short-hand syntax and key-based destructuring
introduced in PHP 7.1: http://php.net/list

Regards,
-- 
Rowan Collins
[IMSoP]

---

## #102327 — Levi Morrison — 2018-06-20T14:29:42+00:00

URL: https://externals.io/message/102245#102327 · In reply to: #102326

> Ah, OK, you learn something every day! For anyone else like me who was unaware of this, list() apparently silently accepts any non-array value on the right of the assignment, assigns all variables in the list() to null, and evaluates to the assigned (but otherwise unused) value. So $x=list($a,$b)=42; will set $a and $b to NULL, and $x to 42, without any notices.

This is changing as per this RFC:
https://wiki.php.net/rfc/notice-for-non-valid-array-container. The
`null` case is kept.

---

## #102328 — Rowan Collins — 2018-06-20T16:01:33+00:00

URL: https://externals.io/message/102245#102328 · In reply to: #102327

> > […]
> unaware of this, list() apparently silently accepts any non-array value on
> the right of the assignment, assigns all variables in the list() to null,
> and evaluates to the assigned (but otherwise unused) value. So
> $x=list($a,$b)=42; will set $a and $b to NULL, and $x to 42, without any
> notices.
>
> This is changing as per this RFC:
> https://wiki.php.net/rfc/notice-for-non-valid-array-container. The
> `null` case is kept.
>


Not according to the RFC:

> Per discussion on the PR
<https://github.com/php/php-src/pull/2031#issuecomment-238366706> I have
limited this RFC to not raise warnings when setting any value by use of
list().

It says nothing about treating `NULL` specially, it just implies list() will
be out of scope of the RFC completely.

Regards,
-- 
Rowan Collins
[IMSoP]

---

## #102329 — Woortmann — 2018-06-20T16:02:59+00:00

URL: https://externals.io/message/102245#102329 · In reply to: #102321

Am 20.06.2018 um 15:55 schrieb Levi Morrison:
> Your wish cannot be granted for `array_value_last` and
> `array_value_first`; you cannot know by itself if there is a failure
> condition.

I can comprehend your issue with the lack of distinctness between the 
error case and the 'real' array value null without further checks.
But in my opinion the required additional checking of the $input is a 
learned behaviour from existing functions which handle single value 
elements from an array as `reset()`, `current()` and `end()` will return false 
for empty arrays or null for invalid data types which are both also 
valid element values.
 `array_pop()` and `array_shift()` also behave in a comparable way as they 
return null as well for empty arrays as for non array input.
> This is not "clean". In contrast here is with my proposal:
>
>      if ([$key, $value] = array_last($input) {
>          // do something
>      }
I still think that this proposed syntax is unintuitive and hard to 
comprehend for the user of the function.
I don't think many PHP developers out there know that the condition 
inside the if will evaluate to null if array_last returns null.

Additionally I don't know about any other function where a construct 
like this has to be used to extract two or more different semantic 
entities, in this case the key and the value, out of a PHP core function 
return value.

Enno

---

Next page: https://externals.io/message/102245.md?page=2
