The one with all the static __call methods.
Owh — my — gawd!
I’ve just noticed a very pretty patch by Sara Golemon (I think?) that allows static __call magic function.
If that sounds weird or plain useless then… you are just about right…
The new magic function is currently (php5.3 and php6 CVS HEAD) called __callStatic and you should be aware that it has some issues.
So, what good is this…
It would be a good way to create overloadable static methods that would allow the user to call the same class method with different number of arguments or different argument types and get different results.
Same way overloading works in other programming languages.
very simple example.
users::get(1); //Returns user with id 1
users::get(“email”, “b.gates@microsoft.com”); //Returns user with email address b.gates@…
There should be other cute things that could be done with this, especially if it was backported earlier in php5.x where namespaces didn’t exist.
But since the first version to implement this will probably be 5.3 that will also include namespaces the glory of the static __call method is faded.
To be honest I wasn’t looking for this when I bumped onto it.
I was looking for a way to implement a static __get method.
Since the lovely core developers of php actively deny to let the users define their own custom superglobals (like $_SESSION, $_POST, etc) I’ve been trying to find a way to call some objects from any scope without having to register them as global first or call them through a registry or singleton pattern.
I frequently end up having several global objects that everything in my Php application needs and having to remember to global everything is a pain in my ass.
A registry or a singleton pattern would seem the way to go here but still I don’t quite like either.
object::getInstance()->doSomething(); //Singleton pattern inside the class
singleton::getInstance(“object”)->doSomething(); //Generic registry pattern
Now imagine that you could define $object as a superglobal…
$object::doSomething();
The problem with this is that in order to do this you need to have the runkit extension or custom patch your php but then you have to watch your code portability go down the drain.
So my last hope was using a static __get method that would return the global object using the requested variable. (did this make any sense?)
< ?php
class superglobals
{
public static function __get($var)
{
global ${$var};
return ${$var};
}
}
?>
This is currently wrong for so, sooo many reasons, but wouldn’t it be pretty if it actually worked?
There are no static __get or __set methods not even in the php6 schedule and this saddens me but I’ve got faith in the core php team that they’ll make up for it with namespaces, threadding and native utf support. — And maybe custom superglobals? Pretty please?
Peter Goodman 03:22 on May 29, 2008 Permalink |
This is more of a nifty hack then anything, but I’ve been fooling around with this idea for alternate purposes on my own. Although I do not encourage the use of global variables or singletons, you might find the following piece of code that I wrote interesting: http://codepad.org/aNW13yC9 . In essence, if you can’t make your own superglobals, simply overwrite them ;)
visual 17:29 on October 9, 2008 Permalink |
Ok this is an old post and you have probably forgotten all about it already.
But still I would like to correct some of your misconceptions.
First thing first – __call is not at all meant for overloading a method. The method can easily be coded to accept any number of parameters by means of parameter default values or func_get_args.
What it really is used for is having a single implementation for multiple similar methods, programmatic and dynamic method creation and registration, etc.
Why would we want it to work for static methods? Well, at the very least for completeness. Also it would help to avoid using singletons where now there is no alternative. An example where this can be useful is the SoapServer object and its setClass method – currently it works by creating a single instance of the class and using that for static-like calls.
It can be a useful change. The way it is proposed and implemented currently is bad though – there is no reason to introduce a new magic method __callStatic, just make the existing __call work for static calls. Then it is trivial to check if $this is set to determine if the call was static or not.
And about your side-story adventure with needing a static __get… I agree in principle that php should be changed so __get is invoked also for statically referenced properties, similar to what I want for __call. But I don’t see the need for that in the particular case that you described. Contrary to the code sample that you showed, I imagine that you would not want all globals to be accessible through your superglobals class – but only a small predetermined subset of objects that you use a lot. If so you can simply declare a static property for each of them. Also, perhaps you should consider renaming “superglobals” to something shorter or more relevant… I can see code like “my::$stuff”, or “modulename::$stuff”, but “superglobals::$stuff” borders in inconvenience with “$GLOBALS['stuff']”
Indeed if __get and __set worked for static properties, it would save you the need to pre-declare them. If you insist that pre-declaring them would be too much work, you are stuck with singleton-like approach… Just declare one static property, i.e. “$global” or “$g” and put all your stuff inside it. Yes it complicates the syntax you’d use to access stuff a bit – “my::$g->stuff” instead of just “my::$stuff”, but it is bearable. And now $g could be an instance with any __get and __set magic. It could also fool someone of having the excuse of being self-documenting, if you weren’t too lazy to use something to the tune of “globals::$modulename->stuff” or “modulename::$global->stuff”:P