2014-02-18 2 views
1

Это стрип-версия моего класса шаблона, сосредоточившись на выполнение файла в ограниченном объеме $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 = new Template(); 
$template->render('foo', ['template' => $template]); 

Однако это требует явного захвата и передачи $template экземпляра в момент построения объекта шаблона.

Однако, если я делаю это внутри render метода:

$env['template'] = $this; 

Тогда $template имеет доступ к частным методам шаблона, например test.

Есть ли способ получить от $this экземпляр объекта, который имеет доступ только к общедоступным методам?

+0

Вы можете создать класс с частными методами, Шаблонный класс унаследует от. Таким образом, частные методы будут доступны через родительский класс, но не шаблон. –

ответ

0

Вы можете создать контекст рендеринга, который является отдельным классом в целом; вот как она изменяет функцию Template::render():

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

И это класс оболочки:

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

     ob_start(); 
     require $file; 

     return ob_get_clean(); 
    } 
} 
+0

Вы по-прежнему передаете метод '$ this' для' run', поэтому '$ template' разрешает доступ к приватным методам. – Gajus

+0

Он не разрешает доступ к приватным свойствам или методам шаблона. –

+0

Вы правы, это не так. http://3v4l.org/0tUXF Однако, я озадачен, почему? В конце концов, вы передаете метод '$ this' методу. – Gajus

Смежные вопросы