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).
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)
You can use extract()
:
public function display()
{
extract($this->variables);
include($this->template);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With