我正在尝试制作自己的模板引擎,(不要问为什么!)
并将尝试制作:
{{@Form::input("name")}}
在我的渲染系统中,我将制作以下eval代码:
preg_match_all('/'{'{'@(.*?)'}'}/is',$data,$output);
$out="";
foreach ( $output[1] as $variables):
$find = '{{@' . $variables . '}}';
$data = str_replace($find, eval($variables), $data);
endforeach;
但是我收到这个错误
Parse error: syntax error, unexpected $end in /home/psafari/public_html/slt/classes/template.class.php(43) : eval()'d code on line 1
它应该按照模板引擎中的指定运行"Form::input('something')"。我做错了什么?
尽管已经有uber相关的评论反对构建新的模板引擎,但我建议打破找到的字符串。以{{@Form::input("name")}}
为例,您将拥有{{@CLASS_NAME:FUNCTION_NAME(params)}}。因此,使用regex,您可以打断找到的字符串(正如您已经做的那样),创建检测到的类的实例或引用该类,然后调用使用动态调用解析的方法(如果找不到任何一个,显然会失败/错误)。
至于参数,您可以避免限定符(在本例中为引号)并在每个逗号上打断,或者使用限定符并再次通过regex进行不同的解析。你的电话。对于解析和找到的每个参数,都会将它们添加到函数调用中。为了避免eval
,并且考虑到PHP不支持随机数目的参数(如Python对args
和kwargs
所做的那样),将数组作为将在模板文件中使用的函数的单个参数。
你也可以有一个"接口"函数,它接受一定数量的参数,然后接收函数(或类+函数名),计算它找到的参数数量,最后根据找到的正确参数数量将调用中继到实际的底层函数。尽管添加的越多,处理就越模糊——假设模板引擎的用户能够定义新的模板方法,但使用第二条路径是一个非常糟糕的主意(因为您必须在这些接口函数上支持多达N的参数)。