Writing an overloadable helper

Published on and tagged with cakephp  helper

You probably know the magic functions provided by the model like findAllByName(). How can you provide such magic functions in your own helper?

If you are using PHP5 and your helper should only work with PHP5, it is an easy task. You have to add a __call() function to your helper class, and that’s it. This __call() function is automatically called whenever you try to call a function not explicitly defined in your class.

class TestHelper extends Helper
{
    function __call($method, $params) 
    {
        // do something
    }

    // add helper functions
}

If you want to make sure your helper works with both PHP4 and PHP5, a bit more work is needed, because the function signature of the __call() function is different in PHP4 and PHP5. There exists an Overloadable construct in CakePHP 1.2 which would solve that problem, but unfortunately we cannot extend this Overloadable class as our helper should extend the Helper class. But we can use some ideas from there. And with a little trick (thanks to Miguel Ros for that trick) we get the following solution:

class TestBase extends Helper
{
    function __call__($method, $params) 
    {
        // do something
    }

    // add helper functions
}

if (phpversion() >= 5)
{
    eval('class TestHelper extends TestBase { 
        function __call($method, $params) {
            return $this->__call__($method, $params);
        }
    }');
}
else
{
    eval('class TestHelper extends TestBase {
        function __call($method, $params, &$return) {
            $return = $this->__call__($method, $params);
            return true;
        }
    }

    overload("TestHelper")');
}

I am not sure if it really works with PHP4, because I don’t have a PHP4 environment to test it. So feedback is welcome :)

2 comments baked

  • KesheR

    Damn, I always forget to use findAllByName :(

  • cakebaker » New Selenium helper

    […] Some days ago I wrote about writing an overloadable helper. If you want to see a real-world helper which uses that approach, check out the new Selenium helper for Selenium 0.8. It uses that approach because I am too lazy to define all the assert, assertNot, verify, verifyNot, waitFor and waitForNot functions ;-) And it makes the helper more “compact” (with still more than 60 functions). […]

Bake a comment




(for code please use <code>...</code> [no escaping necessary])

© daniel hofstetter. Licensed under a Creative Commons License