Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make variables available in the template?

Tags:

php

templates

I have the following class:

abstract class TheView
{
  public $template = NULL;
  public $variables = array();

  public function set($name, $value)
  {
    $this->variables[$name] = $value;
  }
  public function display()
  {
    include($this->template);
  }
}

The template file is a simple PHP file:

<?php
echo $Message;
?>

How can I make all the variables in TheView::$variables available in the template (the key of each item should be the name of the variable).

I've already tried to add all variables to $GLOBALS but that didn't work (and I think it's a bad idea).

like image 264
user897029 Avatar asked Dec 04 '11 16:12

user897029


2 Answers

I always end up doing this:

public function render($path, Array $data = array()){
    return call_user_func(function() use($data){
        extract($data, EXTR_SKIP);
        ob_start();
        include func_get_arg(0);
        return ob_get_clean();
    }, $path);
}

Note the anonymous function and func_get_arg() call; I use them to prevent $this and other variable "pollution" from being passed into the template. You can unset $data before the inclusion too.

If you want $this available though, just extract() and include() directly from the method.

So you can:

$data = array('message' => 'hello world');
$html = $view->render('path/to/view.php', $data);

With path/to/view.php:

<html>
    <head></head>
    <body>
        <p><?php echo $message; ?></p>
    </body>
</html>

If you want the View object passed, but not from the scope of the render() method, alter it as follows:

public function render($path, Array $data = array()){
    return call_user_func(function($view) use($data){
        extract($data, EXTR_SKIP);
        ob_start();
        include func_get_arg(1);
        return ob_get_clean();
    }, $this, $path);
}

$view will be the instance of the View object. It will be available in the template, but will expose only public members, as it is from outside the scope of the render() method (preserving encapsulation of private/protected members)

like image 165
Dan Lugg Avatar answered Sep 21 '22 15:09

Dan Lugg


You can use extract():

public function display()
{
    extract($this->variables);
    include($this->template);
}
like image 24
Tim Cooper Avatar answered Sep 24 '22 15:09

Tim Cooper