【问题标题】:How to derive public object interface from $this?如何从 $this 派生公共对象接口?
【发布时间】:2014-02-18 13:12:52
【问题描述】:

这是我的模板类的精简版,专注于在受限范围内执行文件$env

class Template {
    /**
     * Defines new scope for template execution using $evn variables and
     * executes the template script in an output buffer.
     *
     * @param string $file File name (excluding file extension) relavite to the template directory.
     * @param array $env Variables populated in the template scope.
     * @return string Template output.
     */
    public function render ($file, array $env = []) {
        $env['template'] = $this;

        return self::render($file, $env);
    }

    /**
     * The additional static render method is used to prevent
     * exposing $this and other Template properties to the template scope.
     * Two variables (file and env) are captured using func_get_arg for
     * the same reason of not exposing them to the template scope.
     *
     * @return string Template output.
     */
    static private function render () {
        extract(func_get_arg(1), \EXTR_REFS);

        ob_start();
        require func_get_arg(0);
        return ob_get_clean();
    }

    private function test () { /* I do not want $template to have access to this */ }
}

在模板本身中,我想公开用于执行脚本的 Template 类的实例。这可以做到,例如

$template = new Template();
$template->render('foo', ['template' => $template]);

但是,这需要在构造 Template 对象时显式捕获并传递 $template 实例。

但是,如果我在 render 方法中执行此操作:

$env['template'] = $this;

然后$template 可以访问私有模板方法,例如test.

有没有办法从$this 只能访问公共方法的对象实例派生?

【问题讨论】:

  • 您可以使用模板类将继承的私有方法创建类。这样私有方法将通过父类访问,而不是模板。

标签: php oop


【解决方案1】:

您可以创建一个完全独立的类的渲染上下文;以下是它如何更改 Template::render() 函数:

public function render ($file, array $env = []) {
    return RenderContext::run($file, $this, $env);
}

这是 shell 类:

class RenderContext
{
    static function run($file, $template, $env)
    {
        extract($env);

        ob_start();
        require $file;

        return ob_get_clean();
    }
}

【讨论】:

  • 您仍在将$this 传递给run 方法,因此$template 将允许访问私有方法。
  • 不允许访问 Template 的私有属性或方法。
  • 你是对的,它不会。 3v4l.org/0tUXF 但是,我很疑惑为什么?毕竟,您将$this 传递给方法。
猜你喜欢
  • 1970-01-01
  • 2012-09-06
  • 2011-01-30
  • 2014-08-30
  • 1970-01-01
  • 1970-01-01
  • 2012-09-17
  • 2011-07-29
  • 2018-05-19
相关资源
最近更新 更多