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

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

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to