Re: [PHP-DEV] Re: Undefined variables and the array append operator

2022-03-30 Thread Hans Henrik Bergan
> RFC. There are other inconsistencies as well now, depending on how the
undefined variable comes to exist

absolutely, but shouldn't try to do too much in a single rfc, wouldn't want
it to be rejected for the wrong reasons ^^

On Wed, 30 Mar 2022 at 12:17, Björn Larsson via internals <
internals@lists.php.net> wrote:

> Den 2022-03-29 kl. 21:44, skrev Rowan Tommins:
> > Hi all,
> >
> > If $foo is not defined, statements such as $foo += 1 and $foo .= 'blah'
> > raise "undefined variable" Warnings in PHP 8, and will throw Errors in
> > PHP 9. However, the very similar looking $foo[] = 1 succeeds silently.
> >
> > This seems odd to me, as "append to string" and "append to array" seem
> > like very similar operations, with most of the same use cases and
> > possible bugs.
> >
> >
> >  From an *implementation* point of view, this is presumably because they
> > are defined as different Op Codes - ASSIGN_OP for .= and ASSIGN_DIM for
> > []=, I believe. But that doesn't explain *why* ASSIGN_DIM behaves this
> way.
> >
> > A *historical* explanation might relate to Perl's "autovivification"
> > feature. However, PHP does *not* implement the same rules as Perl: for
> > instance, Perl will create array dimensions just by reading them, which
> > PHP does not; and Perl has a completely different type system, with
> > cases like "a scalar becomes a reference to a hash unless already a
> > reference to a list". Note also that I'm *not* talking about
> > multi-dimensional arrays with missing keys here, only undefined local
> > variables, as were the subject of the recent RFC.
> >
> > The *observable behaviour* for most operators in PHP is the same:
> >
> > 1) if the variable is undefined, consider the value to be null
> > 2) coerce the value to the appropriate type; if the value is null, this
> > gives the relevant "empty" value, such as '', 0, or []
> > 3) apply the operator
> >
> > There isn't anything particularly special with $foo[] = 'bar' in this
> > case, except that it's the only operator that doesn't raise a Warning
> > (and planned Error) at step 1. The same goes for all the other uses of
> > the [] syntax I can think of, like $foo['key'] = 'bar', or $ref =&
> $foo[].
> >
> >
> > For example, consider the following simple validation code
> > [https://3v4l.org/pP5CU]:
> >
> > $requiredFields = ['name', 'age', 'hair_colour'];
> >
> > // Note: $errorString is not initialised
> > foreach ( $requiredFields as $field ) {
> >  if ( ! isset($_POST[$field]) ) {
> >  $errorString .= "Missing required field '$field'. ";
> >  }
> > }
> > echo $errorString;
> >
> > This gives an "Undefined variable" Notice / Warning / Error, depending
> > on the version. That's reasonable, as failing to initialise $errorString
> > might cause problems if this code is integrated into a loop or larger
> > function later.
> >
> > However, switch the code from building up a string to building up an
> > array, and the result is identical, but the Notice / Warning / Error
> > goes away [https://3v4l.org/ojZ1O]:
> >
> > // Note: $errorArray is not initialised
> > foreach ( $requiredFields as $field ) {
> >  if ( ! isset($_POST[$field]) ) {
> >  $errorArray[] = "Missing required field '$field'. ";
> >  }
> > }
> > echo implode('', $errorArray);
> >
> >
> > Can anyone give a compelling reason why we should keep this
> > inconsistency, or should I raise an RFC to bring it in line with other
> > undefined variable accesses?
> >
> >
> I think it deserves an RFC. Then we also capture your excellent
> explanation above!
>
> Regards //Björn L
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
>
>


[PHP-DEV] Re: Undefined variables and the array append operator

2022-03-30 Thread Björn Larsson via internals

Den 2022-03-29 kl. 21:44, skrev Rowan Tommins:

Hi all,

If $foo is not defined, statements such as $foo += 1 and $foo .= 'blah' 
raise "undefined variable" Warnings in PHP 8, and will throw Errors in 
PHP 9. However, the very similar looking $foo[] = 1 succeeds silently.


This seems odd to me, as "append to string" and "append to array" seem 
like very similar operations, with most of the same use cases and 
possible bugs.



 From an *implementation* point of view, this is presumably because they 
are defined as different Op Codes - ASSIGN_OP for .= and ASSIGN_DIM for 
[]=, I believe. But that doesn't explain *why* ASSIGN_DIM behaves this way.


A *historical* explanation might relate to Perl's "autovivification" 
feature. However, PHP does *not* implement the same rules as Perl: for 
instance, Perl will create array dimensions just by reading them, which 
PHP does not; and Perl has a completely different type system, with 
cases like "a scalar becomes a reference to a hash unless already a 
reference to a list". Note also that I'm *not* talking about 
multi-dimensional arrays with missing keys here, only undefined local 
variables, as were the subject of the recent RFC.


The *observable behaviour* for most operators in PHP is the same:

1) if the variable is undefined, consider the value to be null
2) coerce the value to the appropriate type; if the value is null, this 
gives the relevant "empty" value, such as '', 0, or []

3) apply the operator

There isn't anything particularly special with $foo[] = 'bar' in this 
case, except that it's the only operator that doesn't raise a Warning 
(and planned Error) at step 1. The same goes for all the other uses of 
the [] syntax I can think of, like $foo['key'] = 'bar', or $ref =& $foo[].



For example, consider the following simple validation code 
[https://3v4l.org/pP5CU]:


$requiredFields = ['name', 'age', 'hair_colour'];

// Note: $errorString is not initialised
foreach ( $requiredFields as $field ) {
     if ( ! isset($_POST[$field]) ) {
     $errorString .= "Missing required field '$field'. ";
     }
}
echo $errorString;

This gives an "Undefined variable" Notice / Warning / Error, depending 
on the version. That's reasonable, as failing to initialise $errorString 
might cause problems if this code is integrated into a loop or larger 
function later.


However, switch the code from building up a string to building up an 
array, and the result is identical, but the Notice / Warning / Error 
goes away [https://3v4l.org/ojZ1O]:


// Note: $errorArray is not initialised
foreach ( $requiredFields as $field ) {
     if ( ! isset($_POST[$field]) ) {
     $errorArray[] = "Missing required field '$field'. ";
     }
}
echo implode('', $errorArray);


Can anyone give a compelling reason why we should keep this 
inconsistency, or should I raise an RFC to bring it in line with other 
undefined variable accesses?



I think it deserves an RFC. Then we also capture your excellent 
explanation above!


Regards //Björn L

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php