Since you can no longer assign to $this in PHP5, how would one call a method defined in a particular ancestor class that has been overridden by the current class or a more recent ancestor? In PHP4 doing this was hackish, but worked.
For example: class A { function foo() { echo "A::foo"; // Do stuff with $this (not a static method) } } class B extends A { function foo() { echo "B::foo"; } } class C extends B { function bar() { // Inside C, i should be able to do the following since $this is an instance of A: A::foo(); } } class D { function bar() { $c = new C; // I'd like to call the A::foo method of C here... // In PHP4, I could do something like: $othis = &$this; $this = &$c; A::foo(); $this = &$othis; } } How would one emulate the same sort of functionality as in D::bar with PHP5? The best I've been able to figure out is to build the appropriate code in a method and eval it: (add the following method to class A) function call_user_method_array($method, $args = null) { if (is_array($method)) $method = $method[0] .'::'. $method[1]; else $method = '$this->'. $method; $code = 'return '. $method .'('; if (isset($args)) { $n = count($args); if ($n >= 1) { $code .= '$args[0]'; for ($i = 1; $i < $n; ++$i) { $code .= ',$args['.$i.']'; } } } $code .= ');'; return eval($code); } Then D::bar would be more like: function bar() { $c = new C; $c->call_user_method_array("A::foo"); } I'd assume this has big performance penalties compared to the old PHP4 way. It would be nice if call_user_func/call_user_func_array could be used instead of an eval, but doing so results in $this not being set in the called method. For example, the following does not work as I'd expect it to when $method is given as Array(ancestor_class_name, method_name) since it seems to treat it as a static method call ($this is not set within the called method): function call_user_method_array($method, $args = null) { if (!is_array($method)) $method = Array(&$this, $method); return call_user_func_array($method, $args); } Also, it is not possible to do something like the following because PHP5 dies on the assignment to $this during parsing, and not execution: function call_user_method_array($method, $args = null) { if (preg_match('/^4/', PHP_VERSION)) { $othis = &$this; $this = &$c; A::foo(); $this = &$othis; } else { ... PHP 5 code with eval here ... } } The only way to make the above example work is to eval the PHP4 version (or perhaps include it?), thus incurring a performance penalty yet again. Any suggestions how this could be more efficient? Personally, I'd like to see syntax directly in the engine to support this: $c = new C; $c->A::foo(); Though the static version "C::A::foo()" looks a little wierd.... -Brad Fisher -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php