The behavior of dereferencing scalars as if they were arrays or strings
is arguable:
<?php
$foo = 42;
$foo['bar']; // => NULL
This happens without notice or warning, whereas the array dereferencing
of objects results in a fatal error:
<?php
$foo = new stdClass;
$foo['bar']; // Fatal error: Cannot use object of type stdClass as array
There are several bug reports and feature requests regarding this
behavior, the most interesting being #54556[1] and #64194[2]. The
former has a patch attached, for the latter there is a PR[3].
Would throwing a notice or a warning on array deferencing scalars
be acceptable for PHP 7.0, or does this need an RFC?
[1] https://bugs.php.net/bug.php?id=54556
[2] https://bugs.php.net/bug.php?id=64194
[3] https://github.com/php/php-src/pull/1269
--
Christoph M. Becker
Hi!
Would throwing a notice or a warning on array deferencing scalars
be acceptable for PHP 7.0, or does this need an RFC?
I think this does need an RFC, and for 7.0, pretty much no new language
changes are acceptable anymore, since we're past the timeframe.
Stas Malyshev
smalyshev@gmail.com
Hi all,
On Tue, Jun 9, 2015 at 6:21 AM, Stanislav Malyshev smalyshev@gmail.com
wrote:
Would throwing a notice or a warning on array deferencing scalars
be acceptable for PHP 7.0, or does this need an RFC?I think this does need an RFC, and for 7.0, pretty much no new language
changes are acceptable anymore, since we're past the timeframe.
<?php
$foo = 42;
$foo['bar']; // => NULL
This code cannot be right.
How about fix this as a simple bug?
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi all,
----- Original Message -----
From: "Yasuo Ohgaki"
Sent: Tuesday, June 09, 2015
Hi all,
On Tue, Jun 9, 2015 at 6:21 AM, Stanislav Malyshev smalyshev@gmail.com
wrote:Would throwing a notice or a warning on array deferencing scalars
be acceptable for PHP 7.0, or does this need an RFC?I think this does need an RFC, and for 7.0, pretty much no new language
changes are acceptable anymore, since we're past the timeframe.<?php
$foo = 42;
$foo['bar']; // =>NULL
This code cannot be right.
How about fix this as a simple bug?
I just realized this behavior a couple months ago, after being annoyed by
"needing" to use isset() to avoid a Notice in rare cases. (I've always
hate, hate, hated the isset() mess just trying to assign stuff -- I wanted a
value-returning IFset() instead! Now we have ??, but still can't do
var_dump($var ??).)
Anyway, I realized after checking the code that this is actually intentional
and always has been, it seems. Really glad that I could rely on this and it
makes things simpler and cleaner! :-)
Note that I'm referring to accessing NULL
as an array (that I'd like to rely
on). The other bool/int scalar without-a-notice case did/does seem a bit
odd.
So if there's a change, how about only changing it for non-NULL values?
Otherwise, this:
$v = NULL; $v[0][1][2][3][4][5][6][7][8][9];
is supposed to give 10 Notices?! That's dumb, and ugly, and looks like what
the Pull Request is doing with the updated tests. Even worse in the case
where the variable is undefined...
Regards,
--
Yasuo Ohgaki
Thanks,
Matt
Hi Matt,
Hi all,
----- Original Message -----
From: "Yasuo Ohgaki"
Sent: Tuesday, June 09, 2015Hi all,
On Tue, Jun 9, 2015 at 6:21 AM, Stanislav Malyshev smalyshev@gmail.com
wrote:Would throwing a notice or a warning on array deferencing scalars
be acceptable for PHP 7.0, or does this need an RFC?
I think this does need an RFC, and for 7.0, pretty much no new language
changes are acceptable anymore, since we're past the timeframe.<?php
$foo = 42;
$foo['bar']; // =>NULL
This code cannot be right.
How about fix this as a simple bug?I just realized this behavior a couple months ago, after being annoyed by
"needing" to use isset() to avoid a Notice in rare cases. (I've always
hate, hate, hated the isset() mess just trying to assign stuff -- I wanted
a value-returning IFset() instead! Now we have ??, but still can't do
var_dump($var ??).)Anyway, I realized after checking the code that this is actually
intentional and always has been, it seems. Really glad that I could rely
on this and it makes things simpler and cleaner! :-)Note that I'm referring to accessing
NULL
as an array (that I'd like to
rely on). The other bool/int scalar without-a-notice case did/does seem a
bit odd.So if there's a change, how about only changing it for non-NULL values?
Otherwise, this:$v = NULL; $v[0][1][2][3][4][5][6][7][8][9];
is supposed to give 10 Notices?! That's dumb, and ugly, and looks like
what the Pull Request is doing with the updated tests. Even worse in the
case where the variable is undefined...
I fully agree that current behavior could be used meaningful ways. However,
<?php
$foo = 42;
$foo['bar']; // => NULL
$v = NULL;
$v[0][1][2][3][4][5][6][7][8][9]; // NULL
this code is semantically wrong and I would like to have error/exception
for such
erroneous codes. It's inconsistent with array object, too.
Raising exception/error is correct behavior for types that aren't array.
To avoid errors, users should use isset()/is_array()/etc.
Since we have debate for this PR, this PR would be good for RFC targeting
PHP 7.1.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Yasuo Ohgaki wrote:
I fully agree that current behavior could be used meaningful ways. However,
<?php
$foo = 42;
$foo['bar']; // =>NULL
$v = NULL;
$v[0][1][2][3][4][5][6][7][8][9]; //NULL
this code is semantically wrong and I would like to have error/exception
for such
erroneous codes. It's inconsistent with array object, too.Raising exception/error is correct behavior for types that aren't array.
To avoid errors, users should use isset()/is_array()/etc.
I agree that the code is not clean, and that an isset check is
appropriate, particularly as one could do:
$v = NULL;
$v[0][1][2][3][4][5][6][7][8][9] ?? NULL; // NULL
Since we have debate for this PR, this PR would be good for RFC targeting
PHP 7.1.
It seems to me that raising an exception or throwing an error (instead
of a notice) could be too much of a BC break for a minor version.
--
Christoph M. Becker
Hi all,
----- Original Message -----
From: "Christoph Becker"
Sent: Tuesday, June 09, 2015
Yasuo Ohgaki wrote:
I fully agree that current behavior could be used meaningful ways.
However,<?php
$foo = 42;
$foo['bar']; // =>NULL
$v = NULL;
$v[0][1][2][3][4][5][6][7][8][9]; //NULL
this code is semantically wrong and I would like to have error/exception
for such
erroneous codes. It's inconsistent with array object, too.Raising exception/error is correct behavior for types that aren't array.
To avoid errors, users should use isset()/is_array()/etc.I agree that the code is not clean, and that an isset check is
appropriate, particularly as one could do:$v = NULL;
$v[0][1][2][3][4][5][6][7][8][9] ?? NULL; //NULL
Forgetting the NULL
case for a sec... With:
$v = [];
$v[0][1][2][3][4][5][6][7][8][9];
How/why are we going from 1 Notice to 10?!
With:
unset($v);
$v[0];
Why from 1 Notice about the undefined variable, to 2? That's totally new,
and it really doesn't make sense to make any more noise after you've already
been told about the variable. (Same after the first undefined array offset,
too, but this makes the point more obvious.)
That's why I'm saying, you can only really change it for non-NULL scalars
that have an actual value, to keep this other stuff the same, and sane.
I don't really see a semantic issue with the NULL
case, either, unlike other
scalar types.
Since we have debate for this PR, this PR would be good for RFC targeting
PHP 7.1.It seems to me that raising an exception or throwing an error (instead
of a notice) could be too much of a BC break for a minor version.
Just wondering, in the exception case, does that mean 10 exceptions also
(one for each dimension)...?
--
Christoph M. Becker
- Matt
Matt Wilmas wrote:
Forgetting the
NULL
case for a sec... With:$v = [];
$v[0][1][2][3][4][5][6][7][8][9];How/why are we going from 1 Notice to 10?!
With:
unset($v);
$v[0];Why from 1 Notice about the undefined variable, to 2? That's totally
new, and it really doesn't make sense to make any more noise after
you've already been told about the variable. (Same after the first
undefined array offset, too, but this makes the point more obvious.)That's why I'm saying, you can only really change it for non-NULL
scalars that have an actual value, to keep this other stuff the same,
and sane.I don't really see a semantic issue with the
NULL
case, either, unlike
other scalar types.
Current behavior:
<?php
$v = NULL;
echo $v->foo->bar;
?>
Notice: Trying to get property of non-object in %s on line %d
Notice: Trying to get property of non-object in %s on line %d
So trying to access a property on NULL
gives a notice, but trying to
access an element of NULL
shouldn't? Also note, that chained property
access raises multiple notices.
--
Christoph M. Becker
Christoph Becker wrote on 09/06/2015 13:35:
Current behavior:
<?php
$v = NULL;
echo $v->foo->bar;
?>
Notice: Trying to get property of non-object in %s on line %d
Notice: Trying to get property of non-object in %s on line %dSo trying to access a property on
NULL
gives a notice, but trying to
access an element ofNULL
shouldn't? Also note, that chained property
access raises multiple notices.
Again, assignment works differently here:
$v = NULL;
$v->foo->bar = 42;
// Warning: Creating default object from empty value
Interestingly, only one Warning is issued for this case, even though the
inner value must also be created. This seems like a more useful
behaviour, because it doesn't clutter the log/output with repeated
notices about a single line.
Regards,
Rowan Collins
[IMSoP]
Yasuo Ohgaki wrote on 09/06/2015 11:44:
$v = NULL;
$v[0][1][2][3][4][5][6][7][8][9]; //NULL
this code is semantically wrong and I would like to have error/exception
for such
erroneous codes.
PHP considers an uninitialised variable to have the value NULL, and a
NULL
value to be coercable to any type, so this breaks down (logically,
not necessarily literally) as follows:
- coerce $v to array()
- instantiate $v[0] as
NULL
- coerce $v[0] to array()
- instantiate $v[0][1] as
NULL
- and so on...
Raising a notice whenever the type is coerced would be inconsistent with
other coercions (e.g. $foo = null; echo $foo + 1;). Raising a notice
whenever the coerced array is actually accessed would result in a notice
for every dimension, which would be very noisy.
Ideally, it would give a single notice, as in the below, but I'm not
sure how that would be implemented:
$v = array();
var_dump($v[0][1][2][3][4][5][6][7][8][9]);
// Notice: Undefined index: 0
// NULL
Note that this is all rather different from the original case, which was
about values which cannot be coerced to array.
Regards,
Rowan Collins
[IMSoP]
Rowan Collins wrote:
Yasuo Ohgaki wrote on 09/06/2015 11:44:
$v = NULL;
$v[0][1][2][3][4][5][6][7][8][9]; //NULL
this code is semantically wrong and I would like to have error/exception
for such
erroneous codes.PHP considers an uninitialised variable to have the value NULL, and a
NULL
value to be coercable to any type, so this breaks down (logically,
not necessarily literally) as follows:
- coerce $v to array()
- instantiate $v[0] as
NULL
- coerce $v[0] to array()
- instantiate $v[0][1] as
NULL
- and so on...
Raising a notice whenever the type is coerced would be inconsistent with
other coercions (e.g. $foo = null; echo $foo + 1;). Raising a notice
whenever the coerced array is actually accessed would result in a notice
for every dimension, which would be very noisy.Ideally, it would give a single notice, as in the below, but I'm not
sure how that would be implemented:$v = array();
var_dump($v[0][1][2][3][4][5][6][7][8][9]);
// Notice: Undefined index: 0
//NULL
Note that this is all rather different from the original case, which was
about values which cannot be coerced to array.
I wonder where these coercion rules are described. The manual has a
section about "Converting to array"[1] which actually describes casting,
and is obviously not what is happening when the subscript operator (as
the langspec calls it[2]) is applied to non-null scalars.
The section "Accessing array elements with square bracket syntax"[3]
doesn't describe the behavior of accessing elements of non-arrays at all.
The language specification specifies as constraint:
| If subscript-expression is used in a non-lvalue context, the element
| being designated must exist.
Finally, it is not even clear why a value should be coerced to array
when the subscript operator is applied – it might be coerced to string
as well.
[1]
http://php.net/manual/en/language.types.array.php#language.types.array.casting
[2]
https://github.com/php/php-langspec/blob/master/spec/10-expressions.md#subscript-operator
[3]
http://php.net/manual/en/language.types.array.php#language.types.array.syntax.accessing
--
Christoph M. Becker
Christoph Becker wrote on 09/06/2015 14:09:
I wonder where these coercion rules are described. The manual has a
section about "Converting to array"[1] which actually describes casting,
and is obviously not what is happening when the subscript operator (as
the langspec calls it[2]) is applied to non-null scalars.
There's a manual page on "Type Juggling" which is probably more
relevant: http://php.net/manual/en/language.types.type-juggling.php
Interestingly, it notes that:
The behaviour of an automatic conversion to array is currently undefined.
So, at least as far as that reference point is concerned, any change in
behaviour could be justified (if agreed by RFC) as defining what was
previously undefined.
Regards,
Rowan Collins
[IMSoP]
Rowan Collins wrote:
Christoph Becker wrote on 09/06/2015 14:09:
I wonder where these coercion rules are described. The manual has a
section about "Converting to array"[1] which actually describes casting,
and is obviously not what is happening when the subscript operator (as
the langspec calls it[2]) is applied to non-null scalars.There's a manual page on "Type Juggling" which is probably more
relevant: http://php.net/manual/en/language.types.type-juggling.phpInterestingly, it notes that:
The behaviour of an automatic conversion to array is currently undefined.
Thanks. I've missed that. It explains the current behavior.
So, at least as far as that reference point is concerned, any change in
behaviour could be justified (if agreed by RFC) as defining what was
previously undefined.
I would welcome that. In my opinion, undefined behavior is better
avoided in a language specification.
--
Christoph M. Becker
Hi!
<?php
$foo = 42;
$foo['bar']; // =>NULL
$v = NULL;
$v[0][1][2][3][4][5][6][7][8][9]; //NULL
this code is semantically wrong and I would like to have error/exception
for such
erroneous codes. It's inconsistent with array object, too.
Why it's wrong? You try to get that's something not there, you get NULL.
I don't see anything wrong. Adding fatal error about every little thing
that isn't as expected never was how PHP worked.
--
Stas Malyshev
smalyshev@gmail.com
On Wed, Jun 10, 2015 at 8:53 AM, Stanislav Malyshev smalyshev@gmail.com
wrote:
Hi!
<?php
$foo = 42;
$foo['bar']; // =>NULL
$v = NULL;
$v[0][1][2][3][4][5][6][7][8][9]; //NULL
this code is semantically wrong and I would like to have error/exception
for such
erroneous codes. It's inconsistent with array object, too.Why it's wrong? You try to get that's something not there, you get NULL.
I don't see anything wrong. Adding fatal error about every little thing
that isn't as expected never was how PHP worked.
I agree with what other people have said here: We should keep the behavior
for NULL, but drop the nonsense for other types - (42)[24] not throwing a
notice is quite ridiculous, that seems like a pretty obvious bug to me.
Nikita
On , Nikita Popov wrote:
On Wed, Jun 10, 2015 at 8:53 AM, Stanislav Malyshev
smalyshev@gmail.com
wrote:Hi!
<?php
$foo = 42;
$foo['bar']; // =>NULL
$v = NULL;
$v[0][1][2][3][4][5][6][7][8][9]; //NULL
this code is semantically wrong and I would like to have error/exception
for such
erroneous codes. It's inconsistent with array object, too.Why it's wrong? You try to get that's something not there, you get
NULL.
I don't see anything wrong. Adding fatal error about every little
thing
that isn't as expected never was how PHP worked.I agree with what other people have said here: We should keep the
behavior
for NULL, but drop the nonsense for other types - (42)[24] not throwing
a
notice is quite ridiculous, that seems like a pretty obvious bug to me.Nikita
PHP raises a notice when attempting to access properties on null. Surely
it should be consistent and also raise a notice for array access on
null? Array access on null is still a potential bug in the developers
code.
In addition to trying to avoid breaking existing code, I chose a notice
for my PR ( https://github.com/php/php-src/pull/1269 ) because it's
consistent with the behaviour of property access on non-objects, and
also allows developers who wish to use a looser style to simply disable
notices.
I personally don't believe raising an error or EngineException in this
case would fit with the way people expect PHP to work (in addition to
causing an unnecessary BC break). If an EngineException is introduced
for this, I believe a notice / deprecation must be issued first (even if
current behaviour is undefined) to allow developers time and adequate
notification to change their code.
To answer an earlier query, my PR does raise multiple notices for
deep-access (as in the last example given above). This is consistent
with the behaviour on deep-property access on scalars/null.
AllenJB
Hi Stas and Nikita,
On Wed, Jun 10, 2015 at 8:53 AM, Stanislav Malyshev smalyshev@gmail.com
wrote:Hi!
<?php
$foo = 42;
$foo['bar']; // =>NULL
$v = NULL;
$v[0][1][2][3][4][5][6][7][8][9]; //NULL
this code is semantically wrong and I would like to have error/exception
for such
erroneous codes. It's inconsistent with array object, too.Why it's wrong? You try to get that's something not there, you get NULL.
I don't see anything wrong. Adding fatal error about every little thing
that isn't as expected never was how PHP worked.I agree with what other people have said here: We should keep the behavior
for NULL, but drop the nonsense for other types - (42)[24] not throwing a
notice is quite ridiculous, that seems like a pretty obvious bug to me.
I agree that NULL
is debatable. In PHP, NULL
is treated as 0/false by its
context.
It's simpler if we get rid of the behavior altogether. IMO.
Anyway, removing undefined behavior from other types may be good enough so
I don't insist.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Yasuo Ohgaki wrote:
On Wed, Jun 10, 2015 at 8:53 AM, Stanislav Malyshev smalyshev@gmail.com
wrote:<?php
$foo = 42;
$foo['bar']; // =>NULL
$v = NULL;
$v[0][1][2][3][4][5][6][7][8][9]; //NULL
this code is semantically wrong and I would like to have error/exception
for such
erroneous codes. It's inconsistent with array object, too.Why it's wrong? You try to get that's something not there, you get NULL.
I don't see anything wrong. Adding fatal error about every little thing
that isn't as expected never was how PHP worked.I agree with what other people have said here: We should keep the behavior
for NULL, but drop the nonsense for other types - (42)[24] not throwing a
notice is quite ridiculous, that seems like a pretty obvious bug to me.I agree that
NULL
is debatable. In PHP,NULL
is treated as 0/false by its
context.
It's simpler if we get rid of the behavior altogether. IMO.Anyway, removing undefined behavior from other types may be good enough so
I don't insist.
+1
--
Christoph M. Becker
Hi all,
I agree that
NULL
is debatable. In PHP,NULL
is treated as 0/false by its
context.
It's simpler if we get rid of the behavior altogether. IMO.
If PHP should return NULL
always against NULL
variables, we may be better
to
reconsider these behavior.
[yohgaki@dev Download]$ php
<?php
$v = NULL;
$$v;
PHP Notice: Undefined variable: in - on line 3
[yohgaki@dev Download]$ php
<?php
$v = NULL;
$v();
PHP Fatal error: Uncaught EngineException: Function name must be a string
in -:3
Stack trace:
#0 {main}
thrown in - on line 3
[yohgaki@dev Download]$ php
<?php
$v = NULL;
$v[123]; // NULL
I don't care much whether these yield NULL
always or raise error/exception,
but
there should be consistency.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Yasuo Ohgaki wrote on 11/06/2015 00:50:
If PHP should return
NULL
always againstNULL
variables, we may be better
to
reconsider these behavior.[yohgaki@dev Download]$ php
<?php
$v = NULL;
$$v;PHP Notice: Undefined variable: in - on line 3
This is not complaining that $v is NULL, it is warning you the same as
if you wrote $v = 'some_name_you_never_assigned_to'; $$v;
Somewhat surprisingly, you can actually assign to the variable whose
name is NULL: http://3v4l.org/5pXJg
[yohgaki@dev Download]$ php
<?php
$v = NULL;
$v();PHP Fatal error: Uncaught EngineException: Function name must be a string
in -:3
Stack trace:
#0 {main}
thrown in - on line 3
This one has given a different message because of it being a non-string
value, but would be equally fatal if you tried to call any undefined
function. Would coercing NULL
to an imaginary function which returns
NULL
actually be useful for anything?
I don't care much whether these yield
NULL
always or raise error/exception,
but there should be consistency.
I see no reason why these cases need to be consistent, just because they
both involve NULLs. It's all about the action you invoke, not just the
value something's interpreted as.
--
Rowan Collins
[IMSoP]
Yasuo Ohgaki wrote on 11/06/2015 00:50:
If PHP should return
NULL
always againstNULL
variables, we may be better
to
reconsider these behavior.[yohgaki@dev Download]$ php
<?php
$v = NULL;
$$v;PHP Notice: Undefined variable: in - on line 3
This is not complaining that $v is NULL, it is warning you the same as if
you wrote $v = 'some_name_you_never_assigned_to'; $$v;Somewhat surprisingly, you can actually assign to the variable whose name
is NULL: http://3v4l.org/5pXJg
This is actually just converting $v to a string and using this as the
variable name to look up in the symbol table: http://3v4l.org/Z1fWs
(obvious I suppose, just to clarify)
[yohgaki@dev Download]$ php
<?php
$v = NULL;
$v();PHP Fatal error: Uncaught EngineException: Function name must be a string
in -:3
Stack trace:
#0 {main}
thrown in - on line 3This one has given a different message because of it being a non-string
value, but would be equally fatal if you tried to call any undefined
function. Would coercingNULL
to an imaginary function which returnsNULL
actually be useful for anything?I don't care much whether these yield
NULL
always or raiseerror/exception,
but there should be consistency.I see no reason why these cases need to be consistent, just because they
both involve NULLs. It's all about the action you invoke, not just the
value something's interpreted as.
I think what Yasuo is saying is that the function symbol lookup has a type
check and an early bail-out if the type doesn't make sense - even though in
theory the same string cast behaviour could be applied to dynamic function
calls.
I'm inclined to agree that we should have consistency here, and that the
current behaviour in a function context is the correct one. A couple of
(IMO) good arguments for this:
- The function behaviour gives a more explanatory and useful error message
- This is definitely a programming error, there is no valid reason to use
NULL
as a variable name in this manner. It amounts to what many/most other
languages would consider to be a "null pointer exception" or equivalent,
and the more useful error message may help track down the error quicker
(one might look for a case where the empty string was assigned, instead of
looking for a case where it may be NULL).
--
Rowan Collins
[IMSoP]
I'm inclined to agree that we should have consistency here, and that
the current behaviour in a function context is the correct one. A
couple of (IMO) good arguments for this:
- The function behaviour gives a more explanatory and useful error message
- This is definitely a programming error, there is no valid reason to
useNULL
as a variable name in this manner. It amounts to what
many/most other languages would consider to be a "null pointer
exception" or equivalent, and the more useful error message may help
track down the error quicker (one might look for a case where the
empty string was assigned, instead of looking for a case where it may
be NULL).
Well, if you were to model it precisely on the function case, the
consistent behaviour would be to error on any non-string value (e.g.
$v = 42; $$v;) but not a string which is an illegal variable name ($v =
'42'; $v(); just complains that function 42 doesn't exist, not that it
never could).
A more useful approach would perhaps be to look at what should be a
valid function name, and what should be a valid variable name, and throw
an error if dynamic access is used to by-pass either restriction.
For instance, this doesn't currently complain about the fact that @ is
clearly nonsensical as either a function or a variable:
$foo = '@';
var_dump($$foo);
$foo();
And nor does the empty string, which seems no less obvious a bug than a
NULL:
$foo = '';
var_dump($$foo);
$foo();
--
Rowan Collins
[IMSoP]
I'm inclined to agree that we should have consistency here, and that the
current behaviour in a function context is the correct one. A couple of
(IMO) good arguments for this:
- The function behaviour gives a more explanatory and useful error message
- This is definitely a programming error, there is no valid reason to use
NULL
as a variable name in this manner. It amounts to what many/most other
languages would consider to be a "null pointer exception" or equivalent,
and the more useful error message may help track down the error quicker
(one might look for a case where the empty string was assigned, instead of
looking for a case where it may be NULL).Well, if you were to model it precisely on the function case, the
consistent behaviour would be to error on any non-string value (e.g. $v =
42; $$v;) but not a string which is an illegal variable name ($v = '42';
$v(); just complains that function 42 doesn't exist, not that it never
could).A more useful approach would perhaps be to look at what should be a valid
function name, and what should be a valid variable name, and throw an error
if dynamic access is used to by-pass either restriction.
+1
If anything is to be done, then this should be it - properly abstract the
underlying structures so that the lexical/conventional limitations on
symbol naming are also imposed by mechanisms that let userland directly
manipulate the names of symbols (define(), class_alias()
etc).
For instance, this doesn't currently complain about the fact that @ is
clearly nonsensical as either a function or a variable:$foo = '@';
var_dump($$foo);
$foo();And nor does the empty string, which seems no less obvious a bug than a
NULL:$foo = '';
var_dump($$foo);
$foo();--
Rowan Collins
[IMSoP]
Hi all,
I'm inclined to agree that we should have consistency here, and that the
current behaviour in a function context is the correct one. A couple of
(IMO) good arguments for this:
- The function behaviour gives a more explanatory and useful error
message- This is definitely a programming error, there is no valid reason to
use
NULL
as a variable name in this manner. It amounts to what many/most
other
languages would consider to be a "null pointer exception" or equivalent,
and the more useful error message may help track down the error quicker
(one might look for a case where the empty string was assigned, instead
of
looking for a case where it may be NULL).Well, if you were to model it precisely on the function case, the
consistent behaviour would be to error on any non-string value (e.g.
$v =
42; $$v;) but not a string which is an illegal variable name ($v = '42';
$v(); just complains that function 42 doesn't exist, not that it never
could).A more useful approach would perhaps be to look at what should be a valid
function name, and what should be a valid variable name, and throw an
error
if dynamic access is used to by-pass either restriction.+1
If anything is to be done, then this should be it - properly abstract the
underlying structures so that the lexical/conventional limitations on
symbol naming are also imposed by mechanisms that let userland directly
manipulate the names of symbols (define(),class_alias()
etc).
+1
It sounds good change to spot possible bugs.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi Rowan,
On Thu, Jun 11, 2015 at 5:59 PM, Rowan Collins rowan.collins@gmail.com
wrote:
Yasuo Ohgaki wrote on 11/06/2015 00:50:
If PHP should return
NULL
always againstNULL
variables, we may be better
to
reconsider these behavior.[yohgaki@dev Download]$ php
<?php
$v = NULL;
$$v;PHP Notice: Undefined variable: in - on line 3
This is not complaining that $v is NULL, it is warning you the same as if
you wrote $v = 'some_name_you_never_assigned_to'; $$v;Somewhat surprisingly, you can actually assign to the variable whose name
is NULL: http://3v4l.org/5pXJg
[yohgaki@dev Download]$ php
<?php
$v = NULL;
$v();PHP Fatal error: Uncaught EngineException: Function name must be a string
in -:3
Stack trace:
#0 {main}
thrown in - on line 3This one has given a different message because of it being a non-string
value, but would be equally fatal if you tried to call any undefined
function. Would coercingNULL
to an imaginary function which returnsNULL
actually be useful for anything?
For example, getting NULL
handler as the default.
This is useful like $v=NULL;$v[1][2][3];
I don't care much whether these yield
NULL
always or raiseerror/exception,
but there should be consistency.I see no reason why these cases need to be consistent, just because they
both involve NULLs. It's all about the action you invoke, not just the
value something's interpreted as.
I think those who are familiar with NULL
in RDBMS might make sense
returning NULL
for all.
NULL
is special value and how it should be behaved is debatable.
Raising some kind of error for all would be nicer including
$v=NULL;$v[1][2][3]; IMO.
Less exceptions are better.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi Rowan,
On Thu, Jun 11, 2015 at 5:59 PM, Rowan Collins
rowan.collins@gmail.com
wrote:This one has given a different message because of it being a
non-string
value, but would be equally fatal if you tried to call any undefined
function. Would coercingNULL
to an imaginary function which returns
NULL
actually be useful for anything?For example, getting
NULL
handler as the default.
This is useful like $v=NULL;$v[1][2][3];
I was talking specifically about using NULL
as a function, not an array.
Christoph Becker wrote on 08/06/2015 22:11:
The behavior of dereferencing scalars as if they were arrays or strings
is arguable:<?php
$foo = 42;
$foo['bar']; // =>NULL
A few things to note here:
- accessing a numeric offset of a string is valid (selects a single
character) - accessing a string offset of another string is interpreted as access
to character 0, with a Warning issued - de-referencing this to two levels ($string['key']['key']) and then
attempting to write is a Fatal error - as discussed elsewhere, coercing a
NULL
to an array seems perfectly
reasonable - assigning to an offset of anything other than a string or array
results in a Warning and no change to the variable
While I agree that it's kind of surprising not to get even a Notice in
your example, I'm not 100% sure what the behaviour should be, given how
many different scenarios already have different behaviour. Maybe someone
needs to come up with a generalised rule?
Regards,
Rowan Collins
[IMSoP]