Небольшой урок о том, как написать простой шаблонизатор на php (аналогичный тому что используется в yii).
Для удобства напишем его используя ООП и будем использовать php7. Для начала создадим каркас класса View:
class View
{
    private $path = __DIR__ . '/templates/';
    public $data = [];
    public function setData(array $data) : View
    {
        //
    }
    public function render(string $templateName) : string
    {
        //
    }
}
Здесь $data будет содержать параметры которые будут переданы в шаблон. Единственный метод render() будет компилировать шаблон и возвращать готовый результат. Это позволит, например, рендерить страницу из множества модульных шаблонов:
echo (new View)
    ->setData([
        'cart' => 
            (new View)
            ->setData([...])
            ->render()
    ])
    ->render();
Опишем реалзацию для метода setData(). Он позволит не заменять данные а сливать уже указанные данные с теми что переданы в агрументе:
public function setData(array $data) : View
{
    $this->data = array_merge($this->data, $data);
    return $this;
}
А теперь напишем сам метод рендера. В php для этого есть функции ob_start(), ob_get_clean() для работы с буфером. На самом деле мы будем просто запускать выполнение интерпретатора и писать результат в буфер, а затем очищать буфер и возвращать результат.
public function render(string $templateName) : string
{
    $path = $this->path . $templateName;
    if (!file_exists($path)) {
        throw new Exception('Template file ' . $path . ' does not exists');
    }
    extract($this->data); 
    ob_start(); 
    include($path); 
    return ob_get_clean(); 
}
Логика работы проста: проверим существует ли файл и если он существует, то вызовем функцию extract() и скомпилируем шаблон.
На выходе у нас получается вот такой класс:
class View
{
    private $path = __DIR__ . '/templates/';
    public $data = [];
    public function setData(array $data) : View
    {
        $this->data = array_merge($this->data, $data);
        return $this;
    }
    public function render(string $templateName) : string
    {
        $path = $this->path . $templateName;
        if (!file_exists($path)) {
            throw new Exception('Template file ' . $path . ' does not exists');
        }
        extract($this->data); 
        ob_start(); 
        include($path); 
        return ob_get_clean(); 
    }
}