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
