dụ eval của bạn là thiếu giá trị trả về:
print eval("return $sItem;");
nên làm điều đó:
$aData['test'] = 'foo';
$sItem = '$aData[\'test\']';
print eval("return $sItem;"); # foo
Nhưng không nên sử dụng eval bình thường. Bạn có thể vào bếp của địa ngục với nó bởi vì eval là ác.
Thay vì chỉ phân tích chuỗi và trả về giá trị:
$aData['test'] = 'foo';
$sItem = '$aData[\'test\']';
$r = sscanf($sItem, '$%[a-zA-Z][\'%[a-zA-Z]\']', $vName, $vKey);
if ($r === 2)
{
$result = ${$vName}[$vKey];
}
else
{
$result = NULL;
}
print $result; # foo
Điều này có thể được thực hiện với một số hình thức khác của biểu thức chính quy là tốt.
Khi cú pháp của bạn rất gần với PHP thực sự là một tập hợp con của nó, có một số thay thế bạn có thể làm nếu bạn muốn xác thực đầu vào trước khi sử dụng eval. Phương pháp này là để kiểm tra mã PHP và chỉ cho phép một tập hợp con. Điều này không xác thực chuỗi (ví dụ: cú pháp và nếu biến thực sự được đặt) nhưng làm cho nó trở nên nghiêm ngặt hơn:
function validate_tokens($str, array $valid)
{
$vchk = array_flip($valid);
$tokens = token_get_all(sprintf('<?php %s', $str));
array_shift($tokens);
foreach($tokens as $token)
if (!isset($vchk[$token])) return false;
return true;
}
Bạn chỉ cần cung cấp một mảng mã thông báo hợp lệ cho chức năng đó. Đó là những thẻ PHP, trong trường hợp của bạn đó là:
T_LNUMBER (305) (probably)
T_VARIABLE (309)
T_CONSTANT_ENCAPSED_STRING (315)
Sau đó, bạn chỉ có thể sử dụng nó và nó hoạt động với các phím phức tạp hơn cũng như:
$aData['test'] = 'foo';
$aData['te\\\'[]st']['more'] = 'bar';
$sItem = '$aData[\'test\']';
$vValue = NULL;
if (validate_tokens($sItem, array(309, 315, '[', ']')))
{
$vValue = eval("return $sItem;");
}
tôi đã sử dụng này trong another answer của câu hỏi reliably convert string containing PHP array info to array.
@all: cảm ơn tất cả các bạn, từ những gì tôi định làm (trong bức tranh lớn) giải pháp tốt nhất cho tôi để sử dụng chức năng eval ... tôi chỉ quên sử dụng return – nabizan