__callStatic(): instantiating objects from static context?
__callStatic()
provides developers with possibility to react on static
method calls even if that methods don't exist or aren't accessible from outside of the class ( being protected
). This is useful for dynamic, generic code generation.
Example: You have this class:
class Test {
protected static function myProtected($test) {
var_dump(__METHOD__, $test);
}
public static function __callStatic($method, $args) {
switch($method) {
case 'foo' :
echo 'You have called foo()';
var_dump($args);
break;
case 'helloWorld':
echo 'Hello ' . $args[0];
break;
case 'myProtected':
return call_user_func_array(
array(get_called_class(), 'myProtected'),
$args
);
break;
}
}
}
Try to call:
// these ones does not *really* exist
Test::foo('bar');
Test::helloWorld('hek2mgl');
// this one wouldn't be accessible
Test::myProtected('foo');
Why was it done?
This is an existential question, but I think that the answer is "because you can". PHP is a dynamic language and these constructs __call
and __callStatic()
show off its power, and this power can be useful in some situations.
Can you do anything like this elsewhere, like C++ or Java?
No. They have no similar magic methods.
I am looking for short & concise, but informative explanation on static and dynamic functions in languages
Static functions encapsulate code. They exist even when no class has been instantiated. You can call them using scope resolution operator. Dynamic functions are well, dynamic
.. does __callStatic() violate or conform to the big picture of Language constructs. Or is it a new language construct entirely.
It is a construct of a dynamic language. Not sure if this functionality exists in all dynamic languages, but it does in PHP. It does not violate anything, just introduces new paradigm of fall-through catch-all functions when the function you do call does not exist/not accessible in current scope.
I'm not entirely sure why __callStatic() is relevant here?
I don't quite see the difference between:
class Foo {
static function bar() {
$obj = new Foo();
$obj->quux();
}
function quux() {
return "whatever";
}
}
and your example? In both scenarios you're calling a static method which is calling another method on an object of the same class.
Yeah, that's possible. Actually doing it suggests you might want to refactor your code though. In the example you're instantiating an object with its default state, executing a method on it and then throwing the object away. This suggests whatever the method is doing doesn't actually need the objects state. That means it either doesn't belong in this class or could simply be rewritten to be a static method itself.
And are you aware of __call? It does the same thing as __callStatic but for objects rather than classes. E.g. $foo->myMissingMethod(); would go to __call if such a method exists for the class of which $foo is an instance.