我希望用户能够插入如下标签:
Lorem ipsum dolor sit amet, {module_user_name, 123} consectetur adipiscing elit.
正如您在上面的示例中所看到的,标记有几个参数。第一个是所需的功能,参数将取决于所请求的功能。
所以我会使用正则表达式来检测{和},反馈?然后我会抓住第一个参数并检查它是否存在。
如果确实存在,我会使用一个好的命名约定来避免使用大量的IF ELSE或切换脚本。像module_user_name一样会触发moduleUserName()函数,或类似的东西,反馈?
**这只是我对如何解决这个问题的想法,我只是想知道是否有人可以改进它或指出速度等问题。
答案 0 :(得分:2)
我认为标签是指某种形式的插件标记。然后{
语法有点过于轻量级,可能很容易与常规文本冲突;为什么替换应该谨慎进行。这里的一个好方法就是像这样使用preg_replace_callback()
:
$html = preg_replace_callback('/\{([\w\s,\d]+)\}/', "tags_", $html);
function tags_($call) {
// split up
$func = explode(",", $call[1]);
$func = array_map("trim", $func);
// test for handler existence
if (function_exists($func[0])) {
return call_user_func_array(array_shift($func), $func);
}
return $call[0]; // do not replace
}
如果存在,则只调用指定的用户函数。如果找到{wacky text 123}
之类的内容,那么回调只会返回它,从而使原始的$html
保持不变。
答案 1 :(得分:2)
我的建议非常接近马里奥已经给你的东西,但我想补充一下:
你应该对正则表达式更加详细,以便忽略看起来不像函数的东西(例如{12345})
如果你真的必须将“module_user_name”翻译成“moduleUserName”,那么你应该把它设置为一个数组,而不是一个开关:
$ tags = array( / * user tag => php函数* / 'module_user_name'=> 'moduleUserName', 'module_user_id'=> 'getUserId', //等 ); if(isset($ tags [$ func])){ call_user_func($ tags [$ func],...) }
避免使用switch()的原因是因为它像一堆if / elseif语句一样执行,并且到达底部的情况需要更长的时间,而数组有不断的查找时间(我很确定是这种情况)
如果您不想维护一个巨大的数组(我不会),那么只需决定您将用于每个用户标记的前缀,以便{module_user_name, 123}
转换为php { {1}}并且只调用以USER_TAG_module_user_name(123)
开头的函数。
不要忘记为用户提供一种方法USER_TAG_
,而不会将其转换为其他内容(即使用{
或{{
)
答案 2 :(得分:0)
如果确实存在,我会用一个好的 命名约定以避免必须 使用大量IF ELSE或开关 脚本。就像module_user_name一样 触发moduleUserName()函数,或 类似的东西,反馈?
这听起来像是自动加载器上的一个变体,每个名称都映射到一个类/函数。如果您完全控制命名,那应该不是问题。如果必须支持现有标记和/或命名约定不一致,则需要switch语句或类似标记。
实际上,这类似于Smarty进行函数调用的方式。与编写自己的解析器相反,您可以探索它。它的实现是完善的,可能比你第一次写的更好。