I agree that allowing $a->bar() with a static method is too confusing, and should not be allowed. However, the ability to call a static method of an object (variable class name, in other words), is invaluable. What if PHP simply allowed $object::staticMethod() syntax?
I did some playing around, and although I wouldn't know how to disable $a->staticMethod(), this patch enables $a::staticMethod(). It also has another side effect
<?php class foo { static function bar() { echo 'hello'; } }
$bar = 'hello'; $a = new foo; $a->bar(); // this could be disabled to error out easily $a::bar(); // my patch now allows this to print "hello" $a::$bar(); // this also works $a::{'bar'}(); // even this works ?>
If someone could get the patch to work with a T_STRING instead of an object_property, then it would disable the $a::$bar() and $a::{expression}() syntax.
This is my first attempt at a patch of the core, please be gentle if it sucks. :)
Thanks, Greg
John Coggeshall wrote:
http://bugs.php.net/bug.php?id=27304
Marcus says he's brought this up before, and i think it really needs to
be addressed before PHP 5 so I'm bringing it up again. I am told that
currently we are allowing static methods to be called from an object
context because of a performance hit if we check every call, but
currently because $this is undefined regardless of context there is no
way even for the developer to check if the method was called properly.
John
Index: Zend/zend_language_parser.y =================================================================== RCS file: /repository/ZendEngine2/zend_language_parser.y,v retrieving revision 1.138 diff -u -r1.138 zend_language_parser.y --- Zend/zend_language_parser.y 11 Feb 2004 22:13:39 -0000 1.138 +++ Zend/zend_language_parser.y 19 Feb 2004 00:29:07 -0000 @@ -737,6 +737,7 @@ object_property { zend_do_push_object(&$4 TSRMLS_CC); } method_or_not variable_properties { zend_do_pop_object(&$$ TSRMLS_CC); $$.u.EA.type = $1.u.EA.type | ($7.u.EA.type ? $7.u.EA.type : $6.u.EA.type); } | base_variable_with_function_calls { $$ = $1; } + | static_call { $$ = $1; } ; variable_properties: @@ -901,6 +902,19 @@ fully_qualified_class_name T_PAAMAYIM_NEKUDOTAYIM T_STRING { zend_do_fetch_constant(&$$, &$1, &$3, ZEND_RT TSRMLS_CC); } ; +static_call: + variable T_PAAMAYIM_NEKUDOTAYIM { zend_do_push_object(&$1 TSRMLS_CC); } + object_property { zend_do_push_object(&$4 TSRMLS_CC); } static_method variable_properties + { zend_do_pop_object(&$$ TSRMLS_CC); $$.u.EA.type = $1.u.EA.type | ($7.u.EA.type ? $7.u.EA.type : $6.u.EA.type); } +; + +static_method: + '(' { zend_do_pop_object(&$1 TSRMLS_CC); zend_do_begin_method_call(&$1 TSRMLS_CC); } + function_call_parameter_list ')' + { zend_do_end_function_call(&$1, &$$, &$3, 1, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C); + zend_do_push_object(&$$ TSRMLS_CC); $$.u.EA.type = ZEND_PARSED_METHOD_CALL; } +; + %% /*
-- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php