Ever thought “Gee, it would be nice if I could store some PHP in a database and execute it at will?”
The syntax for
eval is very simple:
eval ( string $code_str );
Unfortunately, the output of eval does not work like you might expect it to. You can’t, for instance, do this:
$string_awesome = eval(string $code_str)
The string will remain empty and eval will function as though it weren’t at the right hand side of an assignment. This is because of the way eval works. Eval is not intended to deal solely with code that outputs something to the screen. It simply executes the provided code inline with the rest of the code. It can share variables, functions, and anything else with the main body. So the following would work just fine:
$number = 1; eval ("$number = $number + 1"); echo $number;
The preceding would output 2. Notice that it was necessary to escape each dollar sign. Eval requires a pure PHP string. Any normal PHP operations have to be escaped out, including single quotes, double quotes, dollar signs, etc or it will not work properly.
Since eval is not primarily concerned with output, it doesn’t return any. In order to capture the output to a string you have to do something called output buffering. Output buffering simply captures any output of desired PHP statements and allows you to manipulate it before display (or even choose not to display at all). It has many applications beyond the scope of eval. Output buffering uses a variety of functions. We will demonstrate most of them in the following examples.
Back to our original example, let’s assume we have a string of PHP code which we are going to execute via an eval statement and we would like any output to be captured to a string. To do this, we’d simply run:
ob_start(); eval("echo "This is some really fine output.""); $this_string = ob_get_contents(); ob_end_clean();
Simple enough right? With
ob_start, we…start output buffering. We use
ob_get_contents to capture the collected output to a string, and we use
ob_end_clean to exit the whole thing nicely. The value of
$this_string will be “This is some really fine output.”
But what if we had two eval statements to run and wanted two different strings? Well, we could just run the above code twice, but PHP provides a function called ob_get_clean that simplifies the task. The resulting code looks like:
ob_start(); eval("echo "This is some really fine output.""); $this_first_string = ob_get_clean(); eval("echo "This is some more fine output.""); $this_second_string = ob_get_contents(); ob_end_clean();
ob_get_clean for the first part of the capture scrubs the output buffer and allows it to collect more output without restarting the whole process. This results in cleaner code (and I expect faster executions).
There is one more trick in the output buffering bag that may prove useful. If you want to capture the output of an eval to a string but also display it as if it were simply being executed inline, you can simply use one of the flush functions. Flushing sends the output buffer along its merry way, as if it were never captured. It also cleans the output buffer so it is important to run one of the ob_get* functions before we use flush. PHP even provides variations of the core functions using flush:
ob_start(); eval("echo "Some awesome output. ""); $this_string = ob_get_contents(); ob_end_flush();