简体   繁体   中英

PHP call class variable / property with stored closure

So I am making a Magento module in PHP. I want my logging to be consistent across all classes. My idea was to define a method in the helper class and call it. However being the pre-optimizer that I am, I figure making multiple calls to a class via the Mage::Helper() method to be more expensive than it needs to be, especially since most of my logging in singleton models anyways. So my now my idea is to use closures, define my method in the helper, make one call to the helper and register the method in a class variable.

class Comp_Mod_Helper_Data extends Mage_Core_Helper_Abstract {
    public function getLogger() {
        return function ($obj, $type= Zend_Log::DEBUG) {
             Mage::log($obj, $logType, 'comp-mod.log', true);
        };
    }       
}

Use:

class Comp_Mod__IndexController extends age_Core_Controller_Front_Action {
    private $_log;
    protected function _construct() {
        $this->_log = Mage::Helper('mod')->getLogger();
    }
}

However while it works ... it is not great to use. I'm either stuck doing:

$log = $this->_log;
$log('hello world');
// one awkward liner
($this->_log)('hello world');

While neat that it works is not readable nor standard, ie confusing!. The error that it get when using $this->_log('hello world'); is that the method does not exist. I assume because PHP is looking for a method call when using the syntax $this->method();

I do understand that A) I could just suck it up and use Mage::Helper everywhere, and B) that I could store the helper object in a variable and call like $this->helper->log() , and C) that static variables work, see PHP closure as static class variable

So, is there a way to get a non-static class variable to call the closure instead of looking for a non-existing method?

You could make use of the __call magic method:

class Comp_Mod__IndexController extends age_Core_Controller_Front_Action {

    public function __call($method, array $args)
    {
        switch ($method)
        {
            case '_log':
                return call_user_func_array(Mage::Helper('mod')->getLogger(), $args);
        }

        return null;
    }
}

Then use it like you wanted to:

$this->_log('string to log');

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM