Php 通过引用转换变量替换文本中的占位符
我正在尝试从以下函数中删除eval。我尝试使用sprintf和${},但仍然找不到解决方案 以下是功能:Php 通过引用转换变量替换文本中的占位符,php,eval,preg-replace-callback,custom-function,variable-names,Php,Eval,Preg Replace Callback,Custom Function,Variable Names,我正在尝试从以下函数中删除eval。我尝试使用sprintf和${},但仍然找不到解决方案 以下是功能: function parseDbString(string $value = 'Looking for a good {{ $pippo }}'){ $pippo='Pizza'; return preg_replace_callback('/{{(.*?)}}/', function($res) use ($pippo) { // $val=${trim($re
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调用的双
$$
。一旦你修剪掉一个$
它就可以工作了
<?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"
它在返回值后与我配合良好
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;
}
但若你们想让它更具动态性,你们可以使用它下面的函数,你们可以像['$pippo'=>'pizza']一样将$data作为数组传递,并在第二个参数中传递字符串
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中最高级的“邪恶”之一。在大多数情况下,当任务本身需要通过eval()
或变量(基本上是包装不良的数组)来解决时,这是数据存储/声明不当的症状,通常最好的做法是彻底重新思考
为了在不从根本上重写自定义函数的情况下解决您的孤立问题,我将提供一个较小的“邪恶”(但在我看来仍然是“邪恶”,因为它的使用存在风险)
GLOBALS&global
代码:()
输出:
Global: Pizza # <-- for demonstraton purposes
pippo # <-- for demonstraton purposes
Looking for a good Pizza # <-- desired output
根据您对输入数据的控制程度,您现在可以删除输入字符串中pippo
之前的$
,从而消除一些不必要的字符
如果你还在阅读,你可以用strtr()
或str\u replace()
来清理这一切。()
用另一个分隔符替换
{{}
。
例如:
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() );
“我想stru_replace不起作用了?”巴里说,它起作用了。我想知道的是为什么
$val=${trim($res[1])
不工作而不是计算任意变量,您能否构建变量名及其值的哈希,并使用该哈希解析字符串中的扩展?这样会更安全,也更容易调试;返回空($val)$res[0]:$val代码>?什么是$res,你能把$res变为dump吗;有?$res是preg_replace的结果数组。不起作用。。。它返回未定义变量:pippo
Hmm,适合我。虽然我使用的是PHP7,但您需要PHP7dude@Vixed那我就不知道问题出在哪里了。检查我在上面的评论中提供的链接,然后单击按钮ExecuteCode。它返回寻找好的比萨饼
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();
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() );