通过引用翻译变量替换文本中的占位符
Replace placeholders in text by referencing a translation variable
我正在尝试从以下函数中删除 eval。我尝试使用 sprintf 和 ${} ,但仍然找不到解决方案。
这里是函数:
function parseDbString(string $value = 'Looking for a good {{ $pippo }}'){
$pippo='Pizza';
return preg_replace_callback('/{{(.*?)}}/', function($res) use ($pippo) {
// $val=${trim($res[1])}; Returns "Undefined variable: $pippo"
$val=@eval("return ".trim($res[1]).";"); // Returns "Looking for a good Pizza"
return isset($val) ? $val : $res[0];
},$value);
}
伙计,你正在使用一些奇怪的 Perl 风格的代码。问题是 PHP 调用的双 $$
。一旦你 trim 一 $
离开它就可以了。
<?php
function parseDbString(string $value = 'Looking for a good {{ $pippo }}'){
$pippo='Pizza';
return preg_replace_callback('/{{(.*?)}}/', function($res) use ($pippo) {
$val=${substr(trim($res[1]), 1)}; // here trim the $ away from the matched string
return isset($val) ? $val : $res[0];
},$value);
}
echo parseDbString(); // prints "Looking for a good Pizza"
检查http://sandbox.onlinephpfunctions.com/code/86b3f37ac6c315d8e9a757c827455281df21fc89
的输出
在 return 值
之后它对我很有效
function parseDbString(string $value = 'Looking for a good {{$pippo}}') {
$pippo = 'Pizza';
return preg_replace_callback('/{{(.*?)}}/', function($res) use ($pippo) {
// $val=${trim($res[1])}; Returns "Undefined variable: $pippo"
$val = @eval("return " . trim($res[1]) . ";"); // Returns "Looking for a good Pizza"
return isset($val) ? $val : $res[0];
}, $value);
return $value;
}
但如果你想让它更动态,你可以使用它下面的函数你可以将 $data 作为数组传递,如 ['$pippo'=>'pizza'] 并在第二个参数
中传递字符串
function parseDbString2($data , $string) {
$parsed = preg_replace_callback('/{{(.*?)}}/', function ($matches) use ($data) {
list($shortCode, $index) = $matches;
if (isset($data[$index])) {
return $data[$index];
} else {
throw new \Exception("Shortcode {$shortCode} not found ", 1);
}
}, $string);
return $parsed;
}
希望对您有所帮助
所以,是的,eval()
作为 php 中排名最高的 "evils" 之一经常被人厌恶。在大多数情况下,当一项任务适合由 eval()
或变量-变量(基本上是封装不良的数组)来解决时,这是不适当的 stored/declared 数据的症状,通常是最好的行动方案是一个完整的反思。
为了在不从根本上重写自定义函数的情况下解决您的孤立问题,我将提供一个较小的 "evil"(但在我看来仍然是 "evil",因为它的使用存在风险)-- GLOBALS
& global
...
代码:(Demo)
function parseDbString(string $value = 'Looking for a good {{ $pippo }}'){
global $pippo; // declare $pippo as a global variable
$pippo = 'Pizza';
return preg_replace_callback('/{{ $(.*?) }}/', function($m) use ($pippo) {
echo "Global: " , $GLOBALS['pippo'];
echo "\n{$m[1]}\n";
return $GLOBALS[$m[1]] ?? $m[0]; // null coalescing operator provides fallback
},$value);
}
echo parseDbString();
输出:
Global: Pizza # <-- for demonstraton purposes
pippo # <-- for demonstraton purposes
Looking for a good Pizza # <-- desired output
...那么为什么这个解决方法是 "bad idea",好吧,假设你有一个包含 {{ $db }}
的字符串——这样一个通用变量名很可能存在于你的全局变量列表中变量。因此,如果您的字符串中的 {{ variable }}
匹配全局范围内的任何变量,您将得到错误的结果。
现在,您应该做什么?只需在数组中声明您的 $pippo
数据,以便您可以利用关联关系。 (Demo)
function parseDbString(string $value = 'Looking for a good {{ $pippo }}'){
$lookup = ['pippo' => 'Pizza'];
return preg_replace_callback('/{{ $(.*?) }}/', function($m) use ($lookup) {
return $lookup[$m[1]] ?? $m[0]; // null coalescing operator provides fallback
}, $value);
}
echo parseDbString();
根据您对输入数据的控制程度,您现在可以删除输入字符串中 pippo
之前的 $
-- 这会在此处消除一些不必要的字符,并且那里。
如果您还在阅读,可以使用 strtr()
或 str_replace()
来清理整个内容。 (Demo)
function parseDbString(string $value = 'Looking for a good {{ $pippo }}'){
$lookup = ['{{ $pippo }}' => 'Pizza']; // this can be extended all you like!
return strtr($value, $lookup);
}
echo parseDbString();
用另一个分隔符替换{{}}
。
例如:
class Test {
protected $item1 = 'I`m item-1';
protected $item2 = 'I`m item-2';
public function parseDbString($value = 'Looking for a good 1:$$item1 2:$$item2 5:$$item5 blabla'){
$m = '';
$result = $value;
if( preg_match_all('~$$(.+?)\s~s', $value, $m)){
foreach( $m[1] as $var ){
if( property_exists( $this, $var )){
$result = str_replace('$$' .$var, $this->{$var}, $result);
} else {
$result = str_replace('$$' .$var, 'UNDEFINED', $result);
}
}
}
return $result;
}
}
$test = new Test();
var_dump( $test->parseDbString() );
我正在尝试从以下函数中删除 eval。我尝试使用 sprintf 和 ${} ,但仍然找不到解决方案。
这里是函数:
function parseDbString(string $value = 'Looking for a good {{ $pippo }}'){
$pippo='Pizza';
return preg_replace_callback('/{{(.*?)}}/', function($res) use ($pippo) {
// $val=${trim($res[1])}; Returns "Undefined variable: $pippo"
$val=@eval("return ".trim($res[1]).";"); // Returns "Looking for a good Pizza"
return isset($val) ? $val : $res[0];
},$value);
}
伙计,你正在使用一些奇怪的 Perl 风格的代码。问题是 PHP 调用的双 $$
。一旦你 trim 一 $
离开它就可以了。
<?php
function parseDbString(string $value = 'Looking for a good {{ $pippo }}'){
$pippo='Pizza';
return preg_replace_callback('/{{(.*?)}}/', function($res) use ($pippo) {
$val=${substr(trim($res[1]), 1)}; // here trim the $ away from the matched string
return isset($val) ? $val : $res[0];
},$value);
}
echo parseDbString(); // prints "Looking for a good Pizza"
检查http://sandbox.onlinephpfunctions.com/code/86b3f37ac6c315d8e9a757c827455281df21fc89
的输出在 return 值
之后它对我很有效function parseDbString(string $value = 'Looking for a good {{$pippo}}') {
$pippo = 'Pizza';
return preg_replace_callback('/{{(.*?)}}/', function($res) use ($pippo) {
// $val=${trim($res[1])}; Returns "Undefined variable: $pippo"
$val = @eval("return " . trim($res[1]) . ";"); // Returns "Looking for a good Pizza"
return isset($val) ? $val : $res[0];
}, $value);
return $value;
}
但如果你想让它更动态,你可以使用它下面的函数你可以将 $data 作为数组传递,如 ['$pippo'=>'pizza'] 并在第二个参数
中传递字符串function parseDbString2($data , $string) {
$parsed = preg_replace_callback('/{{(.*?)}}/', function ($matches) use ($data) {
list($shortCode, $index) = $matches;
if (isset($data[$index])) {
return $data[$index];
} else {
throw new \Exception("Shortcode {$shortCode} not found ", 1);
}
}, $string);
return $parsed;
}
希望对您有所帮助
所以,是的,eval()
作为 php 中排名最高的 "evils" 之一经常被人厌恶。在大多数情况下,当一项任务适合由 eval()
或变量-变量(基本上是封装不良的数组)来解决时,这是不适当的 stored/declared 数据的症状,通常是最好的行动方案是一个完整的反思。
为了在不从根本上重写自定义函数的情况下解决您的孤立问题,我将提供一个较小的 "evil"(但在我看来仍然是 "evil",因为它的使用存在风险)-- GLOBALS
& global
...
代码:(Demo)
function parseDbString(string $value = 'Looking for a good {{ $pippo }}'){
global $pippo; // declare $pippo as a global variable
$pippo = 'Pizza';
return preg_replace_callback('/{{ $(.*?) }}/', function($m) use ($pippo) {
echo "Global: " , $GLOBALS['pippo'];
echo "\n{$m[1]}\n";
return $GLOBALS[$m[1]] ?? $m[0]; // null coalescing operator provides fallback
},$value);
}
echo parseDbString();
输出:
Global: Pizza # <-- for demonstraton purposes
pippo # <-- for demonstraton purposes
Looking for a good Pizza # <-- desired output
...那么为什么这个解决方法是 "bad idea",好吧,假设你有一个包含 {{ $db }}
的字符串——这样一个通用变量名很可能存在于你的全局变量列表中变量。因此,如果您的字符串中的 {{ variable }}
匹配全局范围内的任何变量,您将得到错误的结果。
现在,您应该做什么?只需在数组中声明您的 $pippo
数据,以便您可以利用关联关系。 (Demo)
function parseDbString(string $value = 'Looking for a good {{ $pippo }}'){
$lookup = ['pippo' => 'Pizza'];
return preg_replace_callback('/{{ $(.*?) }}/', function($m) use ($lookup) {
return $lookup[$m[1]] ?? $m[0]; // null coalescing operator provides fallback
}, $value);
}
echo parseDbString();
根据您对输入数据的控制程度,您现在可以删除输入字符串中 pippo
之前的 $
-- 这会在此处消除一些不必要的字符,并且那里。
如果您还在阅读,可以使用 strtr()
或 str_replace()
来清理整个内容。 (Demo)
function parseDbString(string $value = 'Looking for a good {{ $pippo }}'){
$lookup = ['{{ $pippo }}' => 'Pizza']; // this can be extended all you like!
return strtr($value, $lookup);
}
echo parseDbString();
用另一个分隔符替换{{}}
。
例如:
class Test {
protected $item1 = 'I`m item-1';
protected $item2 = 'I`m item-2';
public function parseDbString($value = 'Looking for a good 1:$$item1 2:$$item2 5:$$item5 blabla'){
$m = '';
$result = $value;
if( preg_match_all('~$$(.+?)\s~s', $value, $m)){
foreach( $m[1] as $var ){
if( property_exists( $this, $var )){
$result = str_replace('$$' .$var, $this->{$var}, $result);
} else {
$result = str_replace('$$' .$var, 'UNDEFINED', $result);
}
}
}
return $result;
}
}
$test = new Test();
var_dump( $test->parseDbString() );