Implicit Evaluation with PHP

6 December 2005

What is Implicit Evaluation

This article covers implicit PHP evaluation. There is also an article on traditional PHP evaluation (dynamic evaluation using eval) if you’d prefer.

Evaluation is a technique, which, simply refers to evaluating code at runtime. Microsoft Excel does this when a formula is entered in a cell. Many programming languages offer this functionality through various avenues: Mozilla-based browsers, for instance, interpret and display XUL and HTML. Mozilla itself is largely written in C++. But it still offers an interpretive environment in the form of a JavaScript interpreter, C++ functions exposed through the compiled binary and XPCOM to glue them together.

In the case of both Excel and Mozilla, a binary application offers a library of functionality, and an interpreter which can execute syntactically correct code at run time. In this highly abstract sense, there are few differences from bundling a compiler with an application and hiding calls to it in source.

Evaluation in an interpreted language is conceptually the same. It does offer additional functionality beyond a self-built intrepretter: Any evaluated code has access to the same interpreter/virtual machine (VM) functionality as the container code itself. It is perhaps easiest to compare statements to functions in a compiled language to highlight the difference. Excel’s parser recognizes MAX as a function in a user-entered formula. Ignoring the details of matching parameters, Excel’s interpreter needs to do little more than call C’s MAX() function to get this functionality. However, Excel’s IF function cannot rely on C’s underlying if statement because C’s if is not a function. Beyond the logic necessary to glue underlying functions to Excel’s environment, it needs a whole new implementation of “if” and whatever other statements or flow control it needs to offer.

In an interpreted language, the interpreter/VM already holds the logic to map MAX in a source file to its implementation of max. It also, however, holds the logic to handle statements and flow control. Any code that a developer writes can also be written and executed at runtime.

Many interpreted languages offer this functionality. VM based code tends to frown on the concept but frequently supports some or all of it as well, frequently through concepts called introspection and reflection. Actual compiled, native code rarely has this as the interpreter typically must be written before it exists.

In most interpreted languages that support it (like JavaScript, Scheme, Perl or PHP) there is a function called “eval” or “evaluate” that operates on a string containing code in that language. PHP, for instance, can do:

eval (“print(\”hello, world!\”);”);

There is clearly no advantage to doing this over calling “print” directly. But the ability to execute the contents of a string is a powerful ability indeed. A very common activity is to print the value of a string. In C, this could be accomplished by calling:

printf(“String Value: %s\n”, variable);

C++ slightly improved this:

cout

Java promoted Strings to a more first-class data type, and allowed

System.out.println(“String Value: “ + variable);

PHP offers both the C and Java style functions (though, requires using a period in place of Java’s plus operator). It however, offers a third possibility through implicit evaluation.

echo “String Value: $variable\n”;

It is simpler and shorter than any of the previous examples. In processing the string, PHP recognized the embedded variable and replaced it with the value. $ must be escaped in PHP to surpress this behavior, much as % must be escaped in C. PHP extends this behavior to all variables, including objects and arrays.

echo “String value: {$record->field[“pk”]}\n”;

The curly braces explicitly mark an object or associative array for evaluation inside a double quoted string. But the code is still pretty explicitly evaluated.

Variable Assignment

Most times variables get assigned inside a call to eval, the data model has been poorly architected. A program’s scope is butchered when assignment happens in an eval – as a developer, its unclear if eval’s happen in their own scope, in the global scope or in the current scope. In PHP, they do happen in the current scope, but that is not obvious. A much more clear construct is using two dollar signs. Should you write:

$color = “red”;
$$color = “#ff0000”;
echo $red; // outputs #ff0000

This is functionally equivalent to

$color = “red”;
Eval(“\$” . $color . “=\”#ff0000\”;”);

But is much more clear.

PHP allows more than just assigning variables. It also does function pointers.

$debug = 1;
if ($debug) {
$fnOutput = “debug”;
} else {
$fnOutput = “print”;
}
$fnOutput (“Hello world”);

Experience shows you can use variables anywhere you can use constants.

$strControlType = “htmlinputcheckbox”;
$cbxEmployed = new $strControlType();
$cbxEmployed->checked = true;

This ability to dynamically specify any aspect of the language is what I call “implicit evaluation.” Entire object-oriented, subclassed frameworks can be written without eval() hacks. Most code sees no benefit from implicit evaluation. Code segments with eval calls or heavy awkward use of named associative arrays can be greatly simplified with this technique. Stub bootloader scripts can offer the structure of a .net or Spring application with the flexibility of PHP syntax. There are numerous benefits with no major deficits afforded by implicit evaluation. It is perhaps the most compelling case for PHP in web development.

No Comments currently posted.

Post a comment on this entry: