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