Hi all,
Well I might not be one to speak, but I feel strongly about this, so
will do it anyway.
Personally I like the dynamic constructs, I use it all the time and
would be devastated if it would disappear. This is for instance a piece
of code of a project where I'm working on right now:
$val = $this->bpl->{$setting}[$uid];
With the reflection api I would need to do:
$refl = new ReflectionProperty(get_class($this->bpl), $setting);
$arr = $refl->getValue($this->bpl);
$val = $arr[$uid];
unset($refl, $val);
... right.
I'm not sure which use cases ware contemplated, but all my projects have
got a lot of these structures. Sure, you can use the reflection API or
call_user_func() in many cases, but I think that it makes my code
unreadable and bloated. And in some cases, since PHP doesn't require
defining properties and methods in classes (__get()/__set()/__call(),
ArrayObject, or just $obj->newprop=1), using the reflection API won't
even work. For instance (also a real world example):
$prop = (string)($sxml->$setting); // $sxml is a SimpleXmlElement.
Anyway, isn't PHP about freedom? Anyone is free to use the reflection
class if they think it is cleaner or in another way the right path.
Having only one correct to do things way sounds more like Java to me,
and actually the main reason why I don't write Java anymore.
So personally I would love to see this patch included. I know already
quite some places where it would make my code a lot simpler.
Best regards,
Arnold
Andi Gutmans wrote:
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:[EMAIL PROTECTED]
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,
On Mon, 2007-07-30 at 22:27 +0200, Etienne Kneuss wrote:
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?marku
p (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
--
PHP Internals - PHP Runtime Development Mailing List To
unsubscribe,
visit: http://www.php.net/unsub.php
--
PHP Internals - PHP Runtime Development Mailing List To
unsubscribe, visit: http://www.php.net/unsub.php