4

Approach 1 would work, but Approach 2 would not - it whould result in a fatal error (Function name must be a string in...)

# Approach 1
$function = self::$function and $function();

# Approach 2
self::$function and self::$function();

Isn't this a bit strange? I hope someone could explain.


Edit: To give some context, here's a whole class:

class Example
{
    static $function;

    static function method()
    {
        self::$function();
    }
}

function callback() {}

Example::$function = 'callback';
Example::method();
20
  • I need to see your class In order to help you. Commented Mar 2, 2013 at 22:01
  • @aguyfromhere, What do you want to see? It could be an empty class with a static method and a static variable - $function. Commented Mar 2, 2013 at 22:02
  • I agree with @aguyfromhere, can you provide 2 complete examples? I am not sure I understand what you are doing. Commented Mar 2, 2013 at 22:04
  • It can't be an empty class if you're going to call the function using () at the end there. Commented Mar 2, 2013 at 22:06
  • 1
    No, there's a variable self::$function. There's no variable $function. Commented Mar 2, 2013 at 22:35

3 Answers 3

1

If you don't want to get into technical details of precedence and ambiguity, the short explanation is that self::$function() works according to the same logic as $obj->$method(); it tries to call the variable function $function() of self.

Sign up to request clarification or add additional context in comments.

1 Comment

It either ignores self:: or it thinks of self as of the scope of the current function.
1

The syntax seems ambigous to me. Probably it is for PHP too. It would be more clean, and functional to either save the function name in a local variable:

static function method()
  $method = self::$function;
  $method();
}

Or use call_user_func():

static function method()
  call_user_func(self::$function);
}

4 Comments

What is the ambiguity here, in what other way could it be interpreted and why wouldn't the error message say something about it.
p.s. I'm not interested in how to make it work. I know how. The question says it. I'm only interested in why.
The ambiguity is the scope. Are you applying th function () on $function? self::$function(). So the answer to why is: because it's ambigous. If you are really interested in technical reasons, read PHP source.
@MathieuImbert: It's not exactly that ambiguity -- you cannot apply () to $function, because the only sane result would be for the expression as a whole to evaluate to the value of a static property whose name is the result of evaluating $function(). But if that were allowed, then Foo::bar() should also be a candidate for "the value of the static property of Foo whose name is the result of evaluating a call to the free function bar". The madness would never end.
1

Why approach #1 works

It's an artifact of PHP's operator precedence.

$function = self::$function and $function();

is equivalent to

($function = self::$function) and $function();

which is of course equivalent to

$function = self::$function;
if ($function) $function();

The last line works fine because that's the syntax for variable functions.

Why approach #2 does not work

Because there's ambiguity, which the compiler resolves "the wrong way".

Consider this:

self::$function();

Does this mean that PHP should invoke a callback stored in the static property $function, or that it should invoke a static method whose name is the value of the variable $function?

PHP goes with the latter but there's no variable $function in scope, resulting first in a notice and then in an error ($function evaluates to null, which is not a string).

6 Comments

Just self::$function();, as you suggest, would result in the same error. The issue has nothing to do with comparison operators. The only reason I used them in the question is to express the fact that the variable is not NULL.
@EmanuilRusev: Sorry, I didn't get that at all. Are you referring to #1 or to #2? What comparison operators?
Sorry, I meant logical operators.
@EmanuilRusev: So my explanation of #1 tells you nothing that you didn't already have in mind? I 'm having trouble understanding what exactly it is you object to.
Yes. It's not about the logical operators. I'm sorry if the question doesn't makes it clear. The last comment of deceze has the answer.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.