3v4l.org

run code in 150+ php & hhvm versions
Bugs & Features
<?php class Template { private $_template = ''; private $_assigns = array(); /** Variables with leading __ are reserved for internal using */ const VALID_VARIABLE = '(?!__)[a-zA-Z0-9_\x7f-\xff]*'; const TAG_SIGN_OPEN = '{'; const TAG_SIGN_CLOSE = '}'; public function __construct($template) { $this->_template = $template; } public function assign($name, $value) { if (!preg_match('/^' . self::VALID_VARIABLE . '$/', $name)) throw new Exception('Invalid name: "' . $name . '"'); if (is_array($value)) foreach ($value as $key_name => $val) if (!preg_match('/^' . self::VALID_VARIABLE . '$/', $key_name)) throw new Exception('Invalid key name: "' . $key_name . '"'); $this->_assigns[$name] = $value; } private function _getToken($string, $sign, $pos, &$token) { $position = strpos($string, $sign, $pos); if ($position === false) { $token = substr($string, $pos); $pos = false; } else { $token = substr($string, $pos, $position - $pos); $pos = $position + strlen($sign); } return $pos; } /** * To avoid the existence of extra variables * and overwriting assigns params * @param type $prepared_code * @param array $assigns * @return type */ private static function _execute($prepared_code, array $assigns) { $__prepared_code = $prepared_code; unset($prepared_code); $__assigns = $assigns; unset($assigns); extract($__assigns); unset($__assigns); ob_start(); eval($__prepared_code); $content = ob_get_contents(); ob_end_clean(); return $content; } public function parse() { $prepared_code = '?' . '>'; $pos = 0; while ($pos !== false) { $pos = $this->_getToken($this->_template, self::TAG_SIGN_OPEN, $pos, $token); $prepared_code .= $token; if ($pos !== false) { $pos = $this->_getToken($this->_template, self::TAG_SIGN_CLOSE, $pos, $token); if ($pos === false) throw new Exception('Template syntax error. Expected "}"'); switch (true) { case preg_match('/^' . self::VALID_VARIABLE . '$/', $token): $prepared_code .= '<?php echo ${\'' . $token . '\'} ?' . '>'; break; case preg_match('/^loop +(' . self::VALID_VARIABLE . ')$/', $token, $match): $prepared_code .= '<?php foreach (${\'' . $match[1] . '\'} as $__index => $__tmp)' . '{extract($__tmp); unset($__tmp); ?' . '>'; break; case preg_match('/^end +loop$/', $token): $prepared_code .= '<?php } ?>'; break; case preg_match('/^\%index\%$/', $token): $prepared_code .= '<?php echo $__index ?' . '>'; break; default: throw new Exception('Template syntax error. Unexpected token "' . $token . '"'); break; } } } echo $prepared_code; return self::_execute($prepared_code, $this->_assigns); } } $templateHtml = <<<END_HTML <div>{my_var}</div> {loop items} <div>{%index%}. {name}</div> {end loop} END_HTML; $template = new Template($templateHtml); $template->assign('my_var', 'test'); $template->assign('items', array( array('name' => 'First'), array('name' => 'Second') )); echo $template->parse();
Output for 5.1.0 - 5.6.28, hhvm-3.10.0 - 3.12.0, 7.0.0 - 7.1.0
?><div><?php echo ${'my_var'} ?></div> <?php foreach (${'items'} as $__index => $__tmp){extract($__tmp); unset($__tmp); ?> <div><?php echo $__index ?>. <?php echo ${'name'} ?></div> <?php } ?><div>test</div> <div>0. First</div> <div>1. Second</div>
Output for 5.0.0 - 5.0.5
Parse error: parse error, unexpected T_ARRAY, expecting '&' or T_VARIABLE in /in/bkpBp on line 55
Process exited with code 255.
Output for 4.4.2 - 4.4.9
Parse error: syntax error, unexpected T_STRING, expecting T_OLD_FUNCTION or T_FUNCTION or T_VAR or '}' in /in/bkpBp on line 5
Process exited with code 255.
Output for 4.3.0 - 4.3.1, 4.3.5 - 4.4.1
Parse error: parse error, unexpected T_STRING, expecting T_OLD_FUNCTION or T_FUNCTION or T_VAR or '}' in /in/bkpBp on line 5
Process exited with code 255.
Output for 4.3.2 - 4.3.4
Parse error: parse error, expecting `T_OLD_FUNCTION' or `T_FUNCTION' or `T_VAR' or `'}'' in /in/bkpBp on line 5
Process exited with code 255.