Is it intentional that the DOUBLE_COLON operator can be used on a
variable that contains a reference to an object?
<?php
class C
{
public function m()
{
print '*';
}
}
$c = new C;
$c::m();
Until yesterday I thought that only the OBJECT_OPERATOR (->) can be used
on a variable that contains an object. https://3v4l.org/59Xap proved me
wrong.
As the deprecation / strict standards notices suggest, though, $c::m()
does not invoke the method m() on the object referenced by $c. It
invokes the method statically on C (the class of the object referenced
by $c): https://3v4l.org/19taB
I think that using :: on a variable that contains an object should not
"fall back" to a static access on the object's class. Instead the
runtime should error out.
What do you think?
Is it intentional that the DOUBLE_COLON operator can be used on a
variable that contains a reference to an object?<?php
class C
{
public function m()
{
print '*';
}
}$c = new C;
$c::m();Until yesterday I thought that only the OBJECT_OPERATOR (->) can be
used
on a variable that contains an object. https://3v4l.org/59Xap proved mewrong.
As the deprecation / strict standards notices suggest, though, $c::m()
does not invoke the method m() on the object referenced by $c. It
invokes the method statically on C (the class of the object referenced
by $c): https://3v4l.org/19taBI think that using :: on a variable that contains an object should not
"fall back" to a static access on the object's class. Instead the
runtime should error out.What do you think?
Hi Sebastian,
Firstly, I'm not sure where you got the names you've put in ALL_CAPS from, but they're not the official names of the operators anywhere I've seen. The double-colon is technically the "Scope Resolution Operator", or internally T_PAAMAYIM_NEKUDOTAYIM
(which does mean double-colon). It's described in the manual here: http://php.net/manual/en/language.oop5.paamayim-nekudotayim.php
I too was slightly surprised when I first learned it could be used against an instance as well as a class name, but there are situations where this is useful. For instance, accessing a class constant associated to some object when interacting with that object, e.g. "$foo->doThing($foo::MODE_X)".
If we could only use it on class names, we'd have to use the "::class" operator to go from one to the other, like "$foo::class::MODE_X"; or perhaps we'd change that operator too and write "$foo->class::MODE_X". That's not awful, I suppose, but it doesn't feel like a big gain.
We'd also need to consider the consistency of "parent::", which resolves the scope but doesn't force a static access, because you need to be able to call an inherited non-static member.
Like most established languages and frameworks, we don't have the luxury of going back and changing old design decisions, we have to look at if and how we should evolve from where we are now. I think removing this behaviour, even if we found something nicer to replace legitimate uses with, would be a huge compatibility break, for very little gain, so is unlikely to get anywhere.
Regards,
--
Rowan Collins
[IMSoP]
Firstly, I'm not sure where you got the names you've put in
ALL_CAPS from, but they're not the official names of the operators
anywhere I've seen. The double-colon is technically the "Scope
Resolution Operator", or internallyT_PAAMAYIM_NEKUDOTAYIM
(which
does mean double-colon). It's described in the manual here: http://p
hp.net/manual/en/language.oop5.paamayim-nekudotayim.php
We use T_DOUBLE_COLON
in reflection:
ext/tokenizer/tokenizer_data.c: REGISTER_LONG_CONSTANT("T_DOUBLE
_COLON", T_PAAMAYIM_NEKUDOTAYIM, CONST_CS | CONST_PERSISTENT);
ext/tokenizer/tokenizer_data.c: case
T_PAAMAYIM_NEKUDOTAYIM: return "T_DOUBLE_COLON";
and I believe it appears/appeared in other places, too.
johannes
Firstly, I'm not sure where you got the names you've put in
ALL_CAPS from, but they're not the official names of the operators
anywhere I've seen. The double-colon is technically the "Scope
Resolution Operator", or internallyT_PAAMAYIM_NEKUDOTAYIM
(which
does mean double-colon). It's described in the manual here: http://p
hp.net/manual/en/language.oop5.paamayim-nekudotayim.phpWe use
T_DOUBLE_COLON
in reflection:ext/tokenizer/tokenizer_data.c: REGISTER_LONG_CONSTANT("T_DOUBLE
_COLON", T_PAAMAYIM_NEKUDOTAYIM, CONST_CS | CONST_PERSISTENT);
ext/tokenizer/tokenizer_data.c: case
T_PAAMAYIM_NEKUDOTAYIM: return "T_DOUBLE_COLON";and I believe it appears/appeared in other places, too.
Ah, OK, I stand corrected.
Regards,
--
Rowan Collins
[IMSoP]
On 5 July 2017 13:28:29 BST, "Johannes Schlüter"
johannes@schlueters.de wrote:Firstly, I'm not sure where you got the names you've put in
ALL_CAPS from, but they're not the official names of the operators
anywhere I've seen. The double-colon is technically the "Scope
Resolution Operator", or internallyT_PAAMAYIM_NEKUDOTAYIM
(which
does mean double-colon). It's described in the manual here: http://p
hp.net/manual/en/language.oop5.paamayim-nekudotayim.phpWe use
T_DOUBLE_COLON
in reflection:ext/tokenizer/tokenizer_data.c: REGISTER_LONG_CONSTANT("T_DOUBLE
_COLON", T_PAAMAYIM_NEKUDOTAYIM, CONST_CS | CONST_PERSISTENT);
ext/tokenizer/tokenizer_data.c: case
T_PAAMAYIM_NEKUDOTAYIM: return "T_DOUBLE_COLON";and I believe it appears/appeared in other places, too.
Ah, OK, I stand corrected.
Regards,
I'm just wondering if T_PAAMAYIM_NEKUDOTAYIM
could finally be changed to
T_DOUBLE_COLON
in, say, PHP 8?
Sorry about hijacking this. :)
--
Lauri Kenttä
As the deprecation / strict standards notices suggest,
What do you think?
It's been deprecated for years.
An RFC to remove it would be appropriate to target PHP 8. I think
nobody remembered to propose it for PHP 7.
cheers
Dan
Hi Sebastian,
Sebastian Bergmann wrote:
Is it intentional that the DOUBLE_COLON operator can be used on a
variable that contains a reference to an object?
I assume so. It wouldn't be the only place that accepts either a class
name or an object of that class.
I think that using :: on a variable that contains an object should not
"fall back" to a static access on the object's class. Instead the
runtime should error out.What do you think?
I would oppose this; I think it would make PHP less consistent, and as
Rowan noted, it's useful for accessing constants of the appropriate
class associated to an object.
Thanks!
Andrea Faulds
https://ajf.me/
Hi Andrea, Sebastian
2017-07-06 1:12 GMT+02:00 Andrea Faulds ajf@ajf.me:
Hi Sebastian,
Sebastian Bergmann wrote:
Is it intentional that the DOUBLE_COLON operator can be used on a
variable that contains a reference to an object?I assume so. It wouldn't be the only place that accepts either a class name
or an object of that class.
Thinking about it, couldn't this have been a side effect of the
"Dynamic access to static methods", available as of PHP 5.3:
<?php
class C {
public static $foo = 123;
}
$a = "C";
echo $a::$foo;
?>
--
regards,
Kalle Sommer Nielsen
kalle@php.net
Hi!
I think that using :: on a variable that contains an object should not
"fall back" to a static access on the object's class. Instead the
runtime should error out.
Why should it not do what it does now? What would it achieve? I don't
see any improvement in changing that - it may break code that is using
this facility, and it won't make anything better. True, this is an
exotic and non-obvious feature, but many languages have such features,
which are used only by people that need them. If we proposed to add such
feature, true, it may be too exotic to be added on its own merits, but
since it is already there (and, probably, used in some code somewhere) -
why bother messing with it? I don't see how just leaving it be hurts
anything.
--
Stas Malyshev
smalyshev@gmail.com
Le 06/07/2017 16:46, Stanislav Malyshev a écrit :
Hi!
I think that using :: on a variable that contains an object should not
"fall back" to a static access on the object's class. Instead the
runtime should error out.Why should it not do what it does now? What would it achieve? I don't
see any improvement in changing that - it may break code that is using
this facility, and it won't make anything better. True, this is an
exotic and non-obvious feature, but many languages have such features,
which are used only by people that need them. If we proposed to add
such
feature, true, it may be too exotic to be added on its own merits, but
since it is already there (and, probably, used in some code somewhere)why bother messing with it? I don't see how just leaving it be hurts
anything.
True.
I'm using that feature all the time to access static variables and
constants, it's just more convenient to use the variable referencing the
object than having to remember and type the name of the class (plus it's
more obvious when reading the code back).
Though I very rarely use it for accessing static methods, I don't see
why this should throw an error, this feature makes sense as '::' is
always for accessing static stuff, it is quite logic in the end:
:: for static (constants, static variables, static methods)
-> for the rest
I think this feature is documented somewhere in the doc, that's where I
learnt it from if I remember correctly.