7

In PHP 5.3.6, I've noticed that the following won't work:

class Foo{
    public static $class = 'Bar';
}

class Bar{
    public static function sayHello(){
        echo 'Hello World';
    }
}

Foo::$class::sayHello();

Issuing an unexpected T_PAAMAYIM_NEKUDOTAYIM. Using a temporary variable however, results in the expected:

$class = Foo::$class;
$class::sayHello(); // Hello World

Does anyone know if this is by design, or an unintended result of how the scope resolution operator is tokenized or something? Any cleaner workarounds than the latter, temporary variable example?

Dan Lugg
  • 20,192
  • 19
  • 110
  • 174
  • Might want to try a curly syntax vector on this. `{${Foo::$class}}::sayHello();` Something like that might work. I don't have a PHP parser in front of me tho. – Mark Tomlin Jul 08 '11 at 02:59
  • Thanks @Mark Tomlin - Unfortunately no go, I've probably tried every combination possible. It always ends up looking for `$Foo` or `$Bar` – Dan Lugg Jul 08 '11 at 03:09
  • If I remember about this question, I'll give it a go when I get home from work. Did the code work before 5.3.6? – Mark Tomlin Jul 08 '11 at 03:10
  • @Mark Tomlin - No, it hasn't worked as far as I've ever known. It would just make sense that with the introduction of dynamic class names for static calls in PHP 5.x, that this would be supported also, of course barring the likelihood of an oversight. – Dan Lugg Jul 08 '11 at 03:12
  • It's like a really odd version of [late static bindings](http://php.net/manual/en/language.oop5.late-static-bindings.php) that the PHP devs did not consider. – Mark Tomlin Jul 08 '11 at 03:15

1 Answers1

2

Unfortunately there is no way to do it in one line. I thought you might be able to do it with call_user_func(), but no go:

call_user_func(Foo::$class.'::sayHello()');
// Warning: call_user_func() expects parameter 1 to be a valid callback, class 'Bar' does not have a method 'sayHello()'

Also, why would you want to do something like this in the first place? I'm sure there must be a better way to do what you're trying to do - there usually is if you're using variable variables or class names.

Mike
  • 23,542
  • 14
  • 76
  • 87
  • Thanks @Mike - I understand there are limited uses for it, but "*static chaining*" has uses in some dynamic loaders I was working on. Of course there are alternatives, but this syntax would be a sugary benefit for helper loading. – Dan Lugg Jul 08 '11 at 16:57
  • 1
    Also @Mike - Your attempt does work with a minor change; `call_user_func(array(Foo::$class, 'sayHello'));` – Dan Lugg Jul 08 '11 at 17:01