Implicit Evaluation with PHP

8 February 2007

Managing Variable Scopes While Using Templates

PHP’s variable scoping might be considered defective. By default, only variables created in a local scope are visible. Variables can be made part of the global scope by using them outside of functions or by explicitly calling global $variablename;. But there’s no way to make a variable part of the permanent global scope (like $_POST). Further, if you have a function calling another function, nothing in the calling function is accessible to the callee.

This is one of the principle defect that products like Smarty strive to fix. Although PHP is a tempting language (something that Rasmus clings to) maintaining any kind of complex template borders impossible without an extra layer to aid you.

There are three principle ways to pump data into a template.

  1. Keep the template in the same scope as the data-collection routines. This is the easiest solution, but the least flexible. It prevents you from using any kind of automatic layout templates and instead force you to include top and bottom files on each page.
  2. Make one global array or object, and ensure it is visible in every possible scope. This is a reasonable solution for most scenarios. It is easy to attach data to one variable and adding one line of code to each scope to ensure its visibility is not unreasonable. Its only real disadvantage is the quantity of output code. CakePHP uses this setup with it’s $data array.
  3. Fortitude, Prado and Smarty completely change the output language. By abstracting PHP out of the code, it is easy to ensure that regardless of complexity, everything falls into a single scope.

Fortitude and Prado each implement a .net-like language with special XML tags. Speaking only for Fortitude’s implementation, there are numerous classes to generate HTML (some simple, like <input />, while others complex, like interactive tree structures). When a tag is encountered with a name recognized by Fortitude, the appropriate class in invoked to generate code. When possible, values are implied (or obtained through introspection) so properties like “name” are managed automatically and need not be duplicated four times.

Smarty is different. It actually combines strategies 2 and 3. The $smarty object collects data needing published to the template, but still has its own templating language. There is good reason for this, and that is by discarding the easy availability of PHP functions, programmers are more strongly encouraged to keep there domain logic and presentation logic separate. Smarty does provide several programming constructs, like loops, and convenience functions for presentation in its templating language.

In reality, Smarty and Fortitude/Prado are not so different. In either case, the two heavier frameworks could adopt Smarty internally and while the templates would change, the logic’s interaction would remain largely the same. Their behavior is near identical. Smarty is simply intended to be added onto projects, while in Fortitude or Prado, the templating is more “built-in.” That’s not to say its better, however the tighter integration enables shortcuts impossible in Smarty.

I am certainly not the world’s foremost advocate of object-oriented programming. However, decisions in PHP have made objects a much more convenient way to pass data. Without a good debugger, global variables become beyond difficult to maintain and without real closures, objects become the best option for storing data. And while I don’t generally use getters and setters in my classes, they can make debugging much easier still by providing useful hooks for capturing assignments and lookups.

Regardless of how your application is layered, objects can apply to any successful template layer. There is a high probability they will make it easier to adopt a different template scheme in the future. Just using objects will make other benefits more obvious.

No Comments currently posted.

Post a comment on this entry: