# Fix inconsistencies in OO calls

- Thread: https://externals.io/message/31331
- Original archive: https://news-web.php.net/php.internals/31331
- Started by Etienne Kneuss on 2007-07-30T20:27:31+00:00
- Messages: 11
- 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

---

## #31331 — Etienne Kneuss — 2007-07-30T20:27:31+00:00

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

Hello,

Currently, those are allowed:

new $classname;
classname::$methodname();

but those aren't:

$classname::foo();
$classname::CONST;
$classname::$member;

Here is a patch for head that fixes those inconsistencies by extending 
the language parser to support such syntax:

http://patches.colder.ch/Zend/dynamic_static_calls.patch?markup (patch 
also attached)

Regards

-- 
Etienne Kneuss
http://www.colder.ch

Men never do evil so completely and cheerfully as 
when they do it from a religious conviction.
-- Pascal

---

## #31338 — johannes@php.net — 2007-07-31T11:57:15+00:00

URL: https://externals.io/message/31331#31338 · In reply to: #31331

Hi Etienne,


> Hello,
> 
> Currently, those are allowed:
> 
> new $classname;
> classname::$methodname();
> 
> but those aren't:
> 
> $classname::foo();
> $classname::CONST;
> $classname::$member;
> 
> Here is a patch for head that fixes those inconsistencies by extending 
> the language parser to support such syntax:

thanks for this fix.
Ilia, do you mind MFHing this fix before the next 5.2 release? Then I'd
commit it within the next days.

johannes

> http://patches.colder.ch/Zend/dynamic_static_calls.patch?markup (patch 
> also attached)
> 
> Regards
> 
> plain text document attachment (dynamic_static_calls.patch)
> Index: Zend/zend_language_parser.y
> ===================================================================
> RCS file: /repository/ZendEngine2/zend_language_parser.y,v
> retrieving revision 1.186
> diff -u -p -r1.186 zend_language_parser.y
> --- Zend/zend_language_parser.y	27 Jul 2007 09:04:12 -0000	1.186
> +++ Zend/zend_language_parser.y	30 Jul 2007 20:28:41 -0000
> @@ -649,6 +649,12 @@ function_call:
>  	|	fully_qualified_class_name `T_PAAMAYIM_NEKUDOTAYIM` T_STRING '(' { zend_do_begin_class_member_function_call(&$1, &$3 TSRMLS_CC); }
>  			function_call_parameter_list
>  			')' { zend_do_end_function_call(NULL, &$$, &$6, 1, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}
> +	|	variable_class_name `T_PAAMAYIM_NEKUDOTAYIM` T_STRING '(' { zend_do_begin_class_member_function_call(&$1, &$3 TSRMLS_CC); }
> +			function_call_parameter_list
> +			')' { zend_do_end_function_call(NULL, &$$, &$6, 1, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}
> +	|	variable_class_name `T_PAAMAYIM_NEKUDOTAYIM` variable_without_objects '(' { zend_do_end_variable_parse(BP_VAR_R, 0 TSRMLS_CC); zend_do_begin_class_member_function_call(&$1, &$3 TSRMLS_CC); }
> +			function_call_parameter_list
> +			')' { zend_do_end_function_call(NULL, &$$, &$6, 1, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}
>  	|	fully_qualified_class_name `T_PAAMAYIM_NEKUDOTAYIM` variable_without_objects '(' { zend_do_end_variable_parse(BP_VAR_R, 0 TSRMLS_CC); zend_do_begin_class_member_function_call(&$1, &$3 TSRMLS_CC); }
>  			function_call_parameter_list
>  			')' { zend_do_end_function_call(NULL, &$$, &$6, 1, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}
> @@ -809,6 +815,11 @@ variable_without_objects:
>  
>  static_member:
>  		fully_qualified_class_name `T_PAAMAYIM_NEKUDOTAYIM` variable_without_objects { $$ = $3; zend_do_fetch_static_member(&$$, &$1 TSRMLS_CC); }
> +	|	variable_class_name `T_PAAMAYIM_NEKUDOTAYIM` variable_without_objects { $$ = $3; zend_do_fetch_static_member(&$$, &$1 TSRMLS_CC); }
> +;
> +
> +variable_class_name:
> +	reference_variable { zend_do_end_variable_parse(BP_VAR_R, 0 TSRMLS_CC); $$=$1;}
>  ;
>  
> 
> @@ -935,6 +946,7 @@ isset_variables:
>  
>  class_constant:
>  		fully_qualified_class_name `T_PAAMAYIM_NEKUDOTAYIM` T_STRING { zend_do_fetch_constant(&$$, &$1, &$3, ZEND_RT TSRMLS_CC); }
> +	|	variable_class_name `T_PAAMAYIM_NEKUDOTAYIM` T_STRING { zend_do_fetch_constant(&$$, &$1, &$3, ZEND_RT TSRMLS_CC); }
>  ;
>  
>  %%
> Index: tests/lang/041.phpt
> ===================================================================
> RCS file: tests/lang/041.phpt
> diff -N tests/lang/041.phpt
> --- /dev/null	1 Jan 1970 00:00:00 -0000
> +++ tests/lang/041.phpt	30 Jul 2007 20:28:41 -0000
> @@ -0,0 +1,23 @@
> +--TEST--
> +Dynamic access of static members
> +--FILE--
> +<?php
> +class A {
> +    public    static $b = 'foo';
> +}
> +
> +$classname       =  'A';
> +$binaryClassname = b'A';
> +$wrongClassname  =  'B';
> +
> +echo $classname::$b."\n";
> +echo $binaryClassname::$b."\n";
> +echo $wrongClassname::$b."\n";
> +
> +?> 
> +===DONE===
> +--EXPECTF--
> +foo
> +foo
> +
> +Fatal error: Class 'B' not found in %s041.php on line %d
> Index: tests/lang/042.phpt
> ===================================================================
> RCS file: tests/lang/042.phpt
> diff -N tests/lang/042.phpt
> --- /dev/null	1 Jan 1970 00:00:00 -0000
> +++ tests/lang/042.phpt	30 Jul 2007 20:28:41 -0000
> @@ -0,0 +1,22 @@
> +--TEST--
> +Dynamic access of constants
> +--FILE--
> +<?php
> +class A {
> +    const B = 'foo';
> +}
> +
> +$classname       =  'A';
> +$binaryClassname = b'A';
> +$wrongClassname  =  'B';
> +
> +echo $classname::B."\n";
> +echo $binaryClassname::B."\n";
> +echo $wrongClassname::B."\n";
> +?> 
> +===DONE===
> +--EXPECTF--
> +foo
> +foo
> +
> +Fatal error: Class 'B' not found in %s042.php on line %d
> Index: tests/lang/043.phpt
> ===================================================================
> RCS file: tests/lang/043.phpt
> diff -N tests/lang/043.phpt
> --- /dev/null	1 Jan 1970 00:00:00 -0000
> +++ tests/lang/043.phpt	30 Jul 2007 20:28:41 -0000
> @@ -0,0 +1,22 @@
> +--TEST--
> +Dynamic call for static methods
> +--FILE--
> +<?php
> +class A {
> +    static function foo() { return 'foo'; }
> +}
> +
> +$classname       =  'A';
> +$binaryClassname = b'A';
> +$wrongClassname  =  'B';
> +
> +echo $classname::foo()."\n";
> +echo $binaryClassname::foo()."\n";
> +echo $wrongClassname::foo()."\n";
> +?> 
> +===DONE===
> +--EXPECTF--
> +foo
> +foo
> +
> +Fatal error: Class 'B' not found in %s043.php on line %d
> Index: tests/lang/044.phpt
> ===================================================================
> RCS file: tests/lang/044.phpt
> diff -N tests/lang/044.phpt
> --- /dev/null	1 Jan 1970 00:00:00 -0000
> +++ tests/lang/044.phpt	30 Jul 2007 20:28:41 -0000
> @@ -0,0 +1,30 @@
> +--TEST--
> +Dynamic call for static methods dynamically named
> +--FILE--
> +<?php
> +class A {
> +    static function foo() { return 'foo'; }
> +}
> +$classname        =  'A';
> +$binaryClassname  = b'A';
> +$wrongClassname   =  'B';
> +
> +$methodname       =  'foo';
> +$binaryMethodname = b'foo';
> +
> +echo $classname::$methodname()."\n";
> +echo $classname::$binaryMethodname()."\n";
> +
> +echo $binaryClassname::$methodname()."\n";
> +echo $binaryClassname::$binaryMethodname()."\n";
> +
> +echo $wrongClassname::$binaryMethodname()."\n";
> +?> 
> +===DONE===
> +--EXPECTF--
> +foo
> +foo
> +foo
> +foo
> +
> +Fatal error: Class 'B' not found in %s044.php on line %d

---

## #31358 — Andi Gutmans — 2007-08-01T23:59:28+00:00

URL: https://externals.io/message/31331#31358 · In reply to: #31338

This is not really a fix.
When we worked on PHP 5 we deliberately decided to relax on all the weird dynamic constructs which didn't provide a lot of value for the majority of use-cases. Of course the Reflection API was going to be the way to do these dynamic things in future. It would also simplify the engine's code. The reason why those first constructs work were for BC reasons. We didn't want to break existing code but wanted to not add on top of this.

While it may feel inconsistent I still prefer the existing path. Maybe for PHP 6 we can even make an `E_STRICT` message for the old way which refers you to the Reflection API?

Andi 

> -----Original Message-----
> From: Johannes Schlüter [mailto:johannes@php.net] 
> Sent: Tuesday, July 31, 2007 4:57 AM
> To: Etienne Kneuss
> Cc: internals@lists.php.net; Ilia Alshanetsky
> Subject: Re: [PHP-DEV] Fix inconsistencies in OO calls
> 
> Hi Etienne,
> 
> 
> > […]
> by extending 
> > […]
> 
> thanks for this fix.
> Ilia, do you mind MFHing this fix before the next 5.2 
> release? Then I'd commit it within the next days.
> 
> johannes
> 
> > […]
> http://patches.colder.ch/Zend/dynamic_static_calls.patch?marku
p (patch 
> > […]
> -0000	1.186
> > […]
> `T_PAAMAYIM_NEKUDOTAYIM` T_STRING '(' { 
> zend_do_begin_class_member_function_call(&$1, &$3 TSRMLS_CC); }
> > […]
> &$$, &$6, 1, 1 TSRMLS_CC); 
> > […]
> `T_STRING` '(' { zend_do_begin_class_member_function_call(&$1, 
> &$3 TSRMLS_CC); }
> > […]
> &$$, &$6, 1, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}
> > […]
> variable_without_objects '(' { 
> zend_do_end_variable_parse(BP_VAR_R, 0 TSRMLS_CC); 
> zend_do_begin_class_member_function_call(&$1, &$3 TSRMLS_CC); }
> > […]
> &$$, &$6, 1, 1 TSRMLS_CC); 
> > […]
> `T_PAAMAYIM_NEKUDOTAYIM` variable_without_objects '(' { 
> zend_do_end_variable_parse(BP_VAR_R, 0 TSRMLS_CC); 
> zend_do_begin_class_member_function_call(&$1, &$3 TSRMLS_CC); }
> > […]
> &$$, &$6, 1, 1 TSRMLS_CC); 
> > […]
> zend_do_fetch_static_member(&$$, 
> > […]
> variable_without_objects { $$ = $3; 
> zend_do_fetch_static_member(&$$, &$1 TSRMLS_CC); }
> > […]
> `T_PAAMAYIM_NEKUDOTAYIM` T_STRING { 
> > […]
> `T_STRING` { zend_do_fetch_constant(&$$, &$1, &$3, ZEND_RT TSRMLS_CC); }
> > […]
> unsubscribe, 
> > […]
> 
> --
>  To 
> unsubscribe, visit: http://www.php.net/unsub.php

---

## #31364 — Derick Rethans — 2007-08-02T07:15:16+00:00

URL: https://externals.io/message/31331#31364 · In reply to: #31358

> This is not really a fix. When we worked on PHP 5 we deliberately 
> decided to relax on all the weird dynamic constructs which didn't 
> provide a lot of value for the majority of use-cases. Of course the 
> Reflection API was going to be the way to do these dynamic things in 
> future. It would also simplify the engine's code. The reason why those 
> first constructs work were for BC reasons. We didn't want to break 
> existing code but wanted to not add on top of this.
> 
> While it may feel inconsistent I still prefer the existing path. Maybe 
> for PHP 6 we can even make an `E_STRICT` message for the old way which 
> refers you to the Reflection API?

I think that'd be a bad idea. I don't see a problem with this patch at 
all, and why should people use reflection here? As you're always so much 
for BC, I find it strange that you're suggesting to remove something 
totally harmless and instead want people to force to use the 
slow Reflection API which is meant for introspection...

Derick

-- 
Derick Rethans
http://derickrethans.nl | http://ez.no | http://xdebug.org

---

## #31365 — Lukas Kahwe Smith — 2007-08-02T07:48:17+00:00

URL: https://externals.io/message/31331#31365 · In reply to: #31364

Derick Rethans wrote:
> 
> 
> > […]
> 
> I think that'd be a bad idea. I don't see a problem with this patch at 
> all, and why should people use reflection here? As you're always so much 
> for BC, I find it strange that you're suggesting to remove something 
> totally harmless and instead want people to force to use the 
> slow Reflection API which is meant for introspection...

I agree its harmless and easy to learn. Moreover I do not see the 
benefit of using the Reflection API instead.

@Andi: Could you explain to us why you think that this sort of thing 
should best be done through the Reflection API?

regards,
Lukas

---

## #31367 — Vesselin Kenashkov — 2007-08-02T09:30:22+00:00

URL: https://externals.io/message/31331#31367 · In reply to: #31365

I agree with Derick and Lukas. I find the ways this patch proviedes to be
much more "natural" and easy to learn (I personally was in a desparate need
for $classname::everything and also was wondering why it is not implemented,
and then I found the Reflection).
I'm just php developer, and I do not have experiance with other languages,
but still I think the way it is implemented in the patch is the "natural"
way to do it. And if Reflection is slower and meant for introspection why to
use it for this.
Is there any specific consideration for using Reflection for this? Or was
there a discussion about this topic earlier (can somebody point me to it)?

+1 for the patch.

Vesselin Kenashkov


>
> Derick Rethans wrote:
> > […]
>
> I agree its harmless and easy to learn. Moreover I do not see the
> benefit of using the Reflection API instead.
>
> @Andi: Could you explain to us why you think that this sort of thing
> should best be done through the Reflection API?
>
> regards,
> Lukas

---

## #31369 — Sebastian Bergmann — 2007-08-02T09:36:54+00:00

URL: https://externals.io/message/31331#31369 · In reply to: #31364

Derick Rethans schrieb:
> I think that'd be a bad idea. I don't see a problem with this patch at 
> all, and why should people use reflection here? As you're always so much 
> for BC, I find it strange that you're suggesting to remove something 
> totally harmless and instead want people to force to use the 
> slow Reflection API which is meant for introspection.

 I agree. The Reflection API is the "right tool for the job" when you
 are meta-programming (developing tools such as PHPUnit, for instance)
 but not when you are programming.

-- 
Sebastian Bergmann                          http://sebastian-bergmann.de/
GnuPG Key: 0xB85B5D69 / 27A7 2B14 09E4 98CD 6277 0E5B 6867 C514 B85B 5D69

---

## #31370 — dz@bitxtender.com — 2007-08-02T09:39:29+00:00

URL: https://externals.io/message/31331#31370 · In reply to: #31369

ACK.

David



Am 02.08.2007 um 11:36 schrieb Sebastian Bergmann:

> Derick Rethans schrieb:
> > […]
>
>  I agree. The Reflection API is the "right tool for the job" when you
>  are meta-programming (developing tools such as PHPUnit, for instance)
>  but not when you are programming.
>
> -- 
> Sebastian Bergmann                          http://sebastian- 
> bergmann.de/
> GnuPG Key: 0xB85B5D69 / 27A7 2B14 09E4 98CD 6277 0E5B 6867 C514  
> B85B 5D69

---

## #31373 — Marcus Boerger — 2007-08-02T11:32:53+00:00

URL: https://externals.io/message/31331#31373 · In reply to: #31369

Hello Sebastian,

  yep, you and Derick are right here. This is definitively a fix that should
go in. Chinstrap just commit the stuff please.

marcus

Thursday, August 2, 2007, 11:36:54 AM, you wrote:

> Derick Rethans schrieb:
> > […]

>  I agree. The Reflection API is the "right tool for the job" when you
>  are meta-programming (developing tools such as PHPUnit, for instance)
>  but not when you are programming.

> -- 
> Sebastian Bergmann                          http://sebastian-bergmann.de/
> GnuPG Key: 0xB85B5D69 / 27A7 2B14 09E4 98CD 6277 0E5B 6867 C514 B85B 5D69




Best regards,
 Marcus

---

## #31385 — Andi Gutmans — 2007-08-02T22:12:49+00:00

URL: https://externals.io/message/31331#31385 · In reply to: #31373

Marcus,

It'd be kind if you gave me chance to reply before you tell people to
"just commit stuff".
I'm just about to hop on a plane and will look at the patch again
tomorrow. If people feel so strongly about it and the patch is decent
(doesn't screw up common case and maintainability) I'm OK with it. It's
not a big deal but being a bit more courteous wouldn't hurt you.

Andi 

> -----Original Message-----
> From: Marcus Boerger [mailto:helly@php.net] 
> Sent: Thursday, August 02, 2007 4:33 AM
> To: Sebastian Bergmann
> Cc: internals@lists.php.net
> Subject: Re: [PHP-DEV] Fix inconsistencies in OO calls
> 
> Hello Sebastian,
> 
>   yep, you and Derick are right here. This is definitively a 
> fix that should go in. Chinstrap just commit the stuff please.
> 
> marcus
> 
> Thursday, August 2, 2007, 11:36:54 AM, you wrote:
> 
> > […]
> this patch 
> > […]
> you're always 
> > […]
> 
> > […]
> job" when you  
> > […]
> instance)  
> > […]
> 
> > […]
> http://sebastian-bergmann.de/
> > […]
> C514 B85B 
> > […]
> 
> 
> 
> 
> Best regards,
>  Marcus
> 
> --
>  To 
> unsubscribe, visit: http://www.php.net/unsub.php

---

## #31460 — Richard Lynch — 2007-08-05T03:37:39+00:00

URL: https://externals.io/message/31331#31460 · In reply to: #31364

I'll just chime in and say that I also find the current
variable-substitution idiom more "natural" than using a Reflection
class to look up a bunch of stuff...

If it's gonna kill youse guys to keep it in there with some kind of
code-maintenance nightmare, fine, kill it.

But if not, having two ways to do the same thing is not necessarily a
Bad Thing, and I think it's a Fine Thing in this case to have both OOP
Reflection and a more "natural" way to do it.

imho
ymmv
etc

-- 
Some people have a "gift" link here.
Know what I want?
I want you to buy a CD from some indie artist.
http://cdbaby.com/browse/from/lynch
Yeah, I get a buck. So?
