# Array dereferencing of scalars

- Thread: https://externals.io/message/86510
- Original archive: https://news-web.php.net/php.internals/86510
- Started by Christoph Becker on 2015-06-08T21:11:54+00:00
- Messages: 27
- Page 1 of 2: messages 1 to 25 (25 per page, add `?page=N` to the URL)
- Next page: https://externals.io/message/86510.md?page=2
- 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

---

## #86510 — Christoph Becker — 2015-06-08T21:11:54+00:00

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

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

---

## #86511 — Stanislav Malyshev — 2015-06-08T21:21:53+00:00

URL: https://externals.io/message/86510#86511 · In reply to: #86510

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

---

## #86512 — Yasuo Ohgaki — 2015-06-09T08:51:33+00:00

URL: https://externals.io/message/86510#86512 · In reply to: #86511

Hi all,

On Tue, Jun 9, 2015 at 6:21 AM, Stanislav Malyshev <smalyshev@gmail.com>
wrote:

> > […]
>
> 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

---

## #86513 — Matt Wilmas — 2015-06-09T10:04:46+00:00

URL: https://externals.io/message/86510#86513 · In reply to: #86512

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:
>
> > […]
>
>
>  <?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

---

## #86514 — Yasuo Ohgaki — 2015-06-09T10:44:58+00:00

URL: https://externals.io/message/86510#86514 · In reply to: #86513

Hi Matt,



> Hi all,
>
>
> ----- Original Message -----
> From: "Yasuo Ohgaki"
> Sent: Tuesday, June 09, 2015
>
>  Hi all,
> > […]
>
> 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

---

## #86515 — Christoph Becker — 2015-06-09T11:21:18+00:00

URL: https://externals.io/message/86510#86515 · In reply to: #86514

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

---

## #86516 — Matt Wilmas — 2015-06-09T11:55:12+00:00

URL: https://externals.io/message/86510#86516 · In reply to: #86515

Hi all,

----- Original Message -----
From: "Christoph Becker"
Sent: Tuesday, June 09, 2015

> Yasuo Ohgaki wrote:
>
> > […]
>
> 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.

> > […]
>
> 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

---

## #86517 — Rowan Collins — 2015-06-09T12:28:57+00:00

URL: https://externals.io/message/86510#86517 · In reply to: #86514

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]

---

## #86518 — Christoph Becker — 2015-06-09T12:35:20+00:00

URL: https://externals.io/message/86510#86518 · In reply to: #86516

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

---

## #86519 — Rowan Collins — 2015-06-09T12:38:44+00:00

URL: https://externals.io/message/86510#86519 · In reply to: #86510

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]

---

## #86520 — Rowan Collins — 2015-06-09T12:43:36+00:00

URL: https://externals.io/message/86510#86520 · In reply to: #86518

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

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]

---

## #86522 — Christoph Becker — 2015-06-09T13:09:31+00:00

URL: https://externals.io/message/86510#86522 · In reply to: #86517

Rowan Collins wrote:

> Yasuo Ohgaki wrote on 09/06/2015 11:44:
> > […]
> 
> 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

---

## #86526 — Rowan Collins — 2015-06-09T14:02:53+00:00

URL: https://externals.io/message/86510#86526 · In reply to: #86522

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]

---

## #86532 — Christoph Becker — 2015-06-09T20:16:54+00:00

URL: https://externals.io/message/86510#86532 · In reply to: #86526

Rowan Collins wrote:

> Christoph Becker wrote on 09/06/2015 14:09:
> > […]
> 
> 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:
> 
> > […]

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

---

## #86537 — Stanislav Malyshev — 2015-06-10T06:53:24+00:00

URL: https://externals.io/message/86510#86537 · In reply to: #86514

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

---

## #86540 — Nikita Popov — 2015-06-10T08:30:06+00:00

URL: https://externals.io/message/86510#86540 · In reply to: #86537

On Wed, Jun 10, 2015 at 8:53 AM, Stanislav Malyshev <smalyshev@gmail.com>
wrote:

> Hi!
>
> > […]
>
> 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

---

## #86541 — AllenJB — 2015-06-10T09:16:35+00:00

URL: https://externals.io/message/86510#86541 · In reply to: #86540

On , Nikita Popov wrote:
> On Wed, Jun 10, 2015 at 8:53 AM, Stanislav Malyshev 
> <smalyshev@gmail.com>
> wrote:
> 
> > […]
> 
> 
> 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

---

## #86576 — Yasuo Ohgaki — 2015-06-10T22:22:26+00:00

URL: https://externals.io/message/86510#86576 · In reply to: #86540

Hi Stas and Nikita,



> On Wed, Jun 10, 2015 at 8:53 AM, Stanislav Malyshev <smalyshev@gmail.com>
> wrote:
>
> > […]
>
>
> 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

---

## #86578 — Christoph Becker — 2015-06-10T22:38:23+00:00

URL: https://externals.io/message/86510#86578 · In reply to: #86576

Yasuo Ohgaki wrote:

> 
> 
> > […]
> 
> 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

---

## #86583 — Yasuo Ohgaki — 2015-06-10T23:50:22+00:00

URL: https://externals.io/message/86510#86583 · In reply to: #86576

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

---

## #86591 — Rowan Collins — 2015-06-11T08:59:14+00:00

URL: https://externals.io/message/86510#86591 · In reply to: #86583

Yasuo Ohgaki wrote on 11/06/2015 00:50:
> 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

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]

---

## #86600 — Chris Wright — 2015-06-11T20:22:06+00:00

URL: https://externals.io/message/86510#86600 · In reply to: #86591

> Yasuo Ohgaki wrote on 11/06/2015 00:50:
>
> > […]
>
> 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
> > […]
>
> 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
> > […]
>
> 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]

---

## #86603 — Rowan Collins — 2015-06-11T23:35:46+00:00

URL: https://externals.io/message/86510#86603 · In reply to: #86600

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

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]

---

## #86604 — Chris Wright — 2015-06-12T00:36:26+00:00

URL: https://externals.io/message/86510#86604 · In reply to: #86603

> 
>
> > […]
>
> 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]

---

## #86631 — Yasuo Ohgaki — 2015-06-14T03:33:16+00:00

URL: https://externals.io/message/86510#86631 · In reply to: #86591

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:
>
> > […]
>
> 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
> > […]
>
> 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?


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 raise
> > […]
>
> 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

---

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