| Extract Variables Posted by: John in PHP, ionManager on Aug 01, 2008 |
A few months ago, in one of the php articles / books I was reading I stumbled across something called variable variables. Essentially, it lets you create a variable whose name is defined by another variable. I thought to myself “where the hell would this be useful?” A few days after Jordan bloged about variable variables I actually found a use for them:
ionManager (a framework and CMS built myself), uses the MVC enterprise pattern. The model querys the database and generates/manipulates any necessary data; the view is responsible for displaying the data. Since the models are classes and views are procedural php files, having the model communicate its data with the view was a minor problem. My solution was to use the controller to pass any data generated by the model to the view.
For example I am creating a blog module (not do be confused with model) for ionManager. One of the views associated with the blog is a main view " this view simply shows a 300 word excerpt of the last ten blog entries. In the model, the code is rather elementary:

The controller had a loadView function which accepted a single paramater " a path to the view file which it included. Moreover the controller can interact with the model directly since it is responsible for creating its instance. Therefore my controller code looked like this:

Which is great, however main_view.php knows nothing about $blogs. I therefore chose to pass another parameter to the loadView function which I called $data. My idea was to pass in an assocative array whose index wold become the variable name, and the corrisponding value would become the variables value. Below shows the new controller code after these alterations:
Now main_view.php can use $blogs.
How does this work?
At first I used a fairly swift technique that took advantage of variable variables. For the sake of brevity, I removed several conditionals from the original function. The (now depreciated) function used the following logic:
$foo was the arrays index and $bar was the indexes value. I was fairly satisfied with this method until yesterday when I was reviewing the seventy two array functions and stumbled across extract. extract() produces the same exact result as my code " without a loop! Therefor my final code looks similar to:

Now I am back to my original question " where the hell are variable variables useful?
ionManager (a framework and CMS built myself), uses the MVC enterprise pattern. The model querys the database and generates/manipulates any necessary data; the view is responsible for displaying the data. Since the models are classes and views are procedural php files, having the model communicate its data with the view was a minor problem. My solution was to use the controller to pass any data generated by the model to the view.
For example I am creating a blog module (not do be confused with model) for ionManager. One of the views associated with the blog is a main view " this view simply shows a 300 word excerpt of the last ten blog entries. In the model, the code is rather elementary:

- function getList ()
- {
- $result = $this->db->query("SELECT * FROM `jos_content` "
- . "WHERE `created_by`='110' "
- . "ORDER BY `created` DESC LIMIT 10");
- while ($blog = $this->db->fetch_assoc($result)) {
- $time = strtotime($blog['created']);
- $blog['created'] = date('F j, Y', $time);
- $blog['fulltext'] = $this->cutText($blog['fulltext'], 300);
- $blogs[] = $blog;
- }
- return $blogs;
- }
function getList ()
{
$result = $this->db->query("SELECT * FROM `jos_content` "
. "WHERE `created_by`='110' "
. "ORDER BY `created` DESC LIMIT 10");
while ($blog = $this->db->fetch_assoc($result)) {
$time = strtotime($blog['created']);
$blog['created'] = date('F j, Y', $time);
$blog['fulltext'] = $this->cutText($blog['fulltext'], 300);
$blogs[] = $blog;
}
return $blogs;
}
{
$result = $this->db->query("SELECT * FROM `jos_content` "
. "WHERE `created_by`='110' "
. "ORDER BY `created` DESC LIMIT 10");
while ($blog = $this->db->fetch_assoc($result)) {
$time = strtotime($blog['created']);
$blog['created'] = date('F j, Y', $time);
$blog['fulltext'] = $this->cutText($blog['fulltext'], 300);
$blogs[] = $blog;
}
return $blogs;
}
The controller had a loadView function which accepted a single paramater " a path to the view file which it included. Moreover the controller can interact with the model directly since it is responsible for creating its instance. Therefore my controller code looked like this:

- public function index ()
- {
- $blogs = $this->model->getList();
- $this->loadView("Blog/main_view.php");
- }
public function index ()
{
$blogs = $this->model->getList();
$this->loadView("Blog/main_view.php");
}
{
$blogs = $this->model->getList();
$this->loadView("Blog/main_view.php");
}
Which is great, however main_view.php knows nothing about $blogs. I therefore chose to pass another parameter to the loadView function which I called $data. My idea was to pass in an assocative array whose index wold become the variable name, and the corrisponding value would become the variables value. Below shows the new controller code after these alterations:

- public function index ()
- {
- $blogs = $this->model->getList();
- $data = array('blogs' => $blogs);
- $this->loadView("Blog/main_view.php", $data);
- }
public function index ()
{
$blogs = $this->model->getList();
$data = array('blogs' => $blogs);
$this->loadView("Blog/main_view.php", $data);
}
{
$blogs = $this->model->getList();
$data = array('blogs' => $blogs);
$this->loadView("Blog/main_view.php", $data);
}
How does this work?
At first I used a fairly swift technique that took advantage of variable variables. For the sake of brevity, I removed several conditionals from the original function. The (now depreciated) function used the following logic:

- function loadView($path, $data)
- {
- foreach($data as $foo => $bar) {
- $$foo = $bar;
- }
- include($path);
- }
function loadView($path, $data)
{
foreach($data as $foo => $bar) {
$$foo = $bar;
}
include($path);
}
{
foreach($data as $foo => $bar) {
$$foo = $bar;
}
include($path);
}

- function loadView($path, $data)
- {
- extract($data);
- include($path);
- }
function loadView($path, $data)
{
extract($data);
include($path);
}
{
extract($data);
include($path);
}
Now I am back to my original question " where the hell are variable variables useful?