Class names as variables in PHP

Warning: Hard Core Dorkage ahead!
php_elephant I ran into a snag implementing a general callback strategy. The issue is that you can’t use a class name as a variable and then call one of its methods. Here is the backdrop, the boo-boo, and the workaround.

Academic bogus minimal cases:

In PHP it is perfectly fine to do the following:

class Foo
{
    public function query($params)
    {
        echo 'in query'; print_r($params);
    }
}

$foo = new Foo;
$method='query';
$stuff = array('bar'=>'baz', 'voo'=>'param');
$foo->$method($stuff);

However suppose query was a static method and you wanted to call it statically as in

Foo::query($stuff);

When you use a variable for the class or method name and try something such as below

$class='Foo';
$method='query';
$class::$method($stuff);

it gives you a syntax error. Well, crap!

Don’t take no for an answer!

Does this mean you have to take NO for an answer and restrict your callback functions to instance methods of an instantiated object only? Static methods are sometimes preferable. Surely there has to be some sneaky way to do this!!

After some surfing and experimenting, I discovered the following paradigm that works:

class Foo
{
     public static function query($stuff) {
         echo "in query"; print_r($stuff);
     }
}

$class = 'Foo';
$method = 'query';
$stuff = array('bar'=>'baz', 'voo'=>'param');
call_user_func(array($class, $method), $stuff) . "\n";

Gettin’ More Real

In real life you would of course want to fortify this code with tests to make sure that the classes, methods, objects and so forth actually exist and are callable. As the php manual states, simply doing method_exists test will return true even for private methods so it’s better to test is_callable.

Why I want to do this

Maybe this sounds to you like one of those tortured academic examples they come up with in C.S. classes to test the edge cases of a language. Let me assure you that my reason for doing this is very “real world.” I’m building a general statically called retrieve from memcached function using callbacks. If we don’t get a cache hit then we have to call an “expensive query” as a callback. We want to be able to call procedural functions, as well as methods of an instantiated object and static methods. If we can have

$data = Caching::retrieve($key, array('ns'=>$co, 'method'=>$method),  $stuff);

where $co can be either a class name or an instantiated object and $stuff is the parameters to the method, we give ourselves maximum flexibility with regard to callbacks.
The goal is encapsulating the logic to test for cache hit within the retrieve method so we don’t have to constantly repeat the the code for the hit test every time we get something out of the memcached. At least that’s the plan for now.

12 comments to Class names as variables in PHP

  • Thanks for the warning. What I just read is a real hardcore dorkage. I couldn’t understand some parts but I got your point here. Developing new stuff to help the old system get better is an admirable quality.

  • A very useful resource for PHP coding guidelines…

  • You’re good! I have been slaving myself for few days to find solution for that one last year in my programming class. I have different solution but your’s were elegant than my code.

  • Hello, I’m searching a solution similar to yours, but for class definition. I need to define the classname from outside the file where it’s defined.

    Something like:

    $classname = ‘Foo’;

    class $classname{
    public function query($params){
    echo ‘in query’; print_r($params);
    }
    }

    Do you know if it can be done?

  • admin

    Hikari, what happens when you try this?
    Can you make a use case for it? Cuz it seems to pervert the idea of a class to my way of thinking. Just as a guess, I think you might do better with an abstract class and various classes that implement it.

  • coucou,Efficace site s’avère à être tout simplement génial merci bcp Le protocole post. J’apprecie vraiment intensément ce qui m’a vraiment aidé, je recommanderai votre site aux gens que je connais. a bientot.

  • Very high honor and privilege to landlord’s blog, the article I was very moved.

  • Hi, i must say fantastic website you have, i stumbled across it in Yahoo. Does you get much traffic? sbbhs2011

  • Hi everyone, Can someone visit my site vimax 3-4 Dot Com, and tell me if im on the right track? if you guys think i should change it. ill start a fresh on my site again. i need feedback thanks!

  • Thanks for this well writed post….love your blog!

  • Hi there, You’ve done a great job. I’ll certainly digg it and personally recommend to my friends. I am sure they will be benefited from this website.

A sample text widget

Etiam pulvinar consectetur dolor sed malesuada. Ut convallis euismod dolor nec pretium. Nunc ut tristique massa.

Nam sodales mi vitae dolor ullamcorper et vulputate enim accumsan. Morbi orci magna, tincidunt vitae molestie nec, molestie at mi. Nulla nulla lorem, suscipit in posuere in, interdum non magna.