我正在创建一个OpenCart扩展程序,管理员可以使用管理面板中的用户界面更改其电子邮件模板。
我希望用户可以选择将变量添加到他的自定义电子邮件模板中。例如,他可以投入:
您好$order['customer_firstname']
,您的订单已处理完毕。
此时$ order将是未定义的,用户只是在告诉定义要发送的消息。这将存储到数据库中,并在发送电子邮件时调用。
问题是,如何让“$order['customer_firstname']
”成为一个字符串,然后在必要时转换为变量?
由于 彼得
答案 0 :(得分:7)
如果我理解你的问题,你可以这样做:
客户有textarea或类似信息输入模板
亲爱的%NAME%,等等等等%SOMETHING%
然后你可以
$values = array('%SOMETHING%' => $order['something'], '%NAME%' => $order['name']);
$str = str_replace(array_keys($values), array_values($values), $str);
答案 1 :(得分:2)
用户将使用大约40个变量。有没有办法让我为每个“%VARIABLE%”设置它?
是的,您可以借助回调函数轻松地为每个变量执行此操作。
这允许您使用您选择的功能处理每个匹配,返回所需的替换。
$processed = preg_replace_callback("/%(\S+)%/", function($matches) {
$name = $matches[1]; // between the % signs
$replacement = get_replacement_if_valid($name);
return $replacement;
},
$text_to_replace_in
);
从这里,你可以做任何你喜欢的事,点符号,例如:
function get_replacement_if_valid($name) {
list($var, $key) = explode(".", $name);
if ($var === "order") {
$order = init_oder(); // symbolic
if(array_key_exists($key, $order)) {
return $order[$key];
}
}
return "<invalid key: $name>";
}
这种简单的实现允许您处理替换%order.name%
替换为$order['name']
。
答案 2 :(得分:1)
您可以将其存储为Hello $order['customer_firstname']
并在访问时确保您使用双引号"
“将变量转换为其对应的值。
echo "Hello $order['customer_firstname']";
修改:根据评论,Prash答案的变体,
str_replace('%CUSTOMERNAME%', $order['customer_name'], $str);
答案 3 :(得分:1)
如果你想保留PHP语法,那么正则表达式适合过滤它们:
$text = preg_replace(
"/ [$] (\w+) \[ '? (\w+) \'? \] /exi",
"$$1['$2']", # basically a constrained eval
$text
);
请注意,它需要在定义$ order的范围内执行。否则(并且最好)使用preg_replace_callback
代替最大的灵活性。
您也可以通过这种方式允许其他语法。例如,{order[customer]}
或%order.customer%
比PHP语法更常见且更易于使用。
答案 4 :(得分:1)
您可以定义自己的简单模板引擎:
function template($text, $context) {
$tags = preg_match_all('~%([a-zA-Z0-9]+)\.([a-zA-Z0-9]+)%~', $text, $matches);
for($i = 0; $i < count($matches[0]); $i++) {
$subject = $matches[0][$i];
$ctx = $matches[1][$i];
$key = $matches[3][$i];
$value = $context[$ctx][$key];
$text = str_replace($subject, $value, $text);
}
return $text;
}
这允许您转换这样的字符串:
$text = 'Hello %order.name%. You have %order.percent%% discount. Pay a total ammount of %payment.ammount% using %payment.type%.';
$templated = template($text, array(
'order' => array(
'name' => 'Alex',
'percent' => 20
),
'payment' => array(
'type' => 'VISA',
'ammount' => '$299.9'
)
));
echo $templated;
进入这个:
Hello Alex. You have 20% discount. Pay a total ammount of $299.9 using VISA.
这允许您定义任意数量的变量。
答案 5 :(得分:0)
您正在寻找的是:
eval("echo \"" . $input . "\";");
但请,请不要这样做,因为这样可以让用户运行他想要的任何代码。
更好的方法是自定义模板系统,您可以使用%user_firstname%
之类的内容为用户提供可用值列表。然后,您可以使用str_replace
和朋友将这些标记与实际值交换出来,但您仍然可以扫描任何类型的恶意代码。
这就是为什么Markdown和类似的东西很受欢迎;它们使用户可以控制其内容的呈现,同时仍然可以轻松扫描HTML / JS / PHP / SQL注入/他们可能试图潜入的任何其他内容,因为白名单比黑名单更容易。
答案 6 :(得分:-1)
也许您可以拥有这样的模板:
$tpl = "Hello {$order['customer_firstname']}, your order has been processed.".
如果$ order和该特定键不为null,则可以直接使用echo $tpl
并在文本中显示'customer_firstname'
键的内容。关键是这里的花括号。