PHP - templating with custom tags - is this a legit use of eval?

99封情书 提交于 2019-11-30 21:56:31

Let me advocate a different approach. Instead of generating PHP code dynamically and then trying to figure out how to execute it safely, execute it directly as you encounter the tags. You can process the entire block of HTML in one pass and handle each tag as you encounter it immediately.

Write a loop that looks for tags. Its basic structure will look like this:

  1. Look for a custom tag, which you find at position n.
  2. Everything before position n must be simple HTML, so either save it off for processing or output it immediately (if you have no tags on your $tags stack you probably don't need to save it anywhere).
  3. Execute the appropriate code for the tag. Instead of generating code that calls $tags->push, just call $tags->push directly.
  4. Go back to step 1.

With this approach you only call PHP functions directly, you never build PHP code on the fly and then execute it later. The need for eval is gone.

You'll basically have two cases for step #3. When you encounter an opening tag you will do an immediate push. Then later when you hit the closing tag you can do a pop and then handle the tag in the appropriate manner, now that you've processed the entire contents of the custom element.

It is also more efficient to process the HTML this way. Doing multiple search and replaces on a long HTML string is inefficient as each search and each replacement is O(n) on the length of the string. Meaning you're repeatedly scanning the string over and over, and each time you do a replacement you have to generate whole new strings of similar length. If you have 20KB of HTML then each replacement involves searching through that 20KB and then creating a new 20KB string afterwards.

I posted another answer because it's radically different from the first, which might also be valuable.

Essentially, this question is asking how to execute PHP code with regex. It may not seem that obvious, but this is what the eval is intending to accomplish.

With that said, instead of doing a pass of preg_replace and then doing an eval, you could just use PHP's preg_replace_callback function to execute a piece of code when matched.

See here for how the function works: http://us.php.net/manual/en/function.preg-replace-callback.php

Yes, instead of eval, you can do what zend and other major frameworks do, use output buffering:

ob_start();
include($template_file); //has some HTML and output generating PHP
$result = ob_get_contents();
ob_end_clean();
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!