PHP魔术方法__invoke,空实例变量


PHP magic method __invoke, empty instance variables

在对象上调用__invoke()时遇到问题。__invoke()方法是否与实例变量无关?由于一些ZF2注入,我需要直接在模板上调用__invoke()来调用$this->getView()->render(…)(否则getView(()返回null),我希望在那里设置实例变量。有什么变通办法吗?

查看我的代码:

namespace Person'Person'View'Helper;

use Zend'View'Helper'AbstractHelper;
class PersonShowWidget extends AbstractHelper
{
    protected $model = null;
    public function __construct(array $options = null)
    {
        $this->parseOptions($options);
    }
    public function __invoke()
    {
        var_dump($this->model); //returns null
        return $this->getView()->render('person/show/show_widget', array(
                'title' => 'Cliente',
                'model' => $this->model,
            )
        );
    }
    public function setOptions(array $options = null)
    {
        $this->parseOptions($options);
    }
    protected function parseOptions(array $options = null)
    {
        if (!is_null($options) && is_array($options)) {
            if (isset($options['model'])) {
                $model = $options['model'];
                if (isset($model['id'])) {
                    $this->model['id'] = $model['id'];
                } else {
                    throw new 'Exception;
                }
                if (isset($model['form'])) {
                    $this->model['form'] = $model['form'];
                } else {
                    throw new 'Exception;
                }
            }
        }
        var_dump($this->model); //returns valid data
    }
}

在调用__invoke()之前,我确实调用了带有一些选项的构造函数或setOptions方法。

谢谢,

您必须使用工厂初始化视图助手。通过这种方式,您可以确保在调用__invoke方法之前调用构造函数。不。__invoke()方法对实例变量不是不可知的。

在Module.php 中

public function getViewHelperConfig()
{
    return array(
        'factories' => array(
            'personShowWidget' => function ($helpers) {
                $array = array();
                $helper = new Person'Person'View'Helper'PersonShowWidget($array);
                return $helper;
            },
        )
    );
}

或者在module.config.php 中

'view_helpers' => array
(
    'factories' => array(
        'personShowWidget' => function ($helpers) {
            $array = array();
            $helper = new Person'Person'View'Helper'PersonShowWidget($array);
            return $helper;
        },
    )
)

就性能而言,您最好创建Factory类,而不是可调用类。更多信息:http://framework.zend.com/manual/2.0/en/modules/zend.module-manager.module-manager.html

编辑:

您似乎错误地使用了ViewHelper。您不必自己创建实例。只需在视图中使用ViewHelper。那么,为什么不把$options作为__invoke方法的参数呢?

public function __invoke(array $options = null)
{
    $this->setOptions($options);
    return $this->getView()->render('person/show/show_widget', array(
            'title' => 'Cliente',
            'model' => $this->model,
        )
    );
}

在控制器中,将选项数组传递到视图:

return array(
    'options' => $options,
);

并在视图中调用ViewHelper:

<?php echo $this->personShowWidget($this->options); ?>

记住:通过这种方式,您不需要Factory来初始化ViewHelper。只需将其添加到可调用项中即可。

module.config.php示例:

'view_helpers' => array(
    'invokables' => array(
        'personShowWidget' => 'Person'Person'View'Helper'PersonShowWidget',
    ),
),