我有一个像
这样的字符串格式数组$string = "array(array('aaa','bbb','ccc','ddd'),array('AAA','BBB','CCC','DDD'))";
到数组,结果将是:
echo $array[0][0];
aaa
答案 0 :(得分:2)
如果您确定该字符串将始终包含数组(任何嵌套)和字符串,您可以编写自己的字符串解析器以避免eval
字符串。
我很快将一个放在一起,应该处理递归数组,字符串和数字。它不处理布尔值,null和对象实例:
$string = "array(array('aaa','bbb','ccc','ddd'),array('AAA','BBB','CCC','DDD',1,2,3,-3.5)))";
class Tokens {
private $tokens;
public function __construct ($code) {
$tokens = token_get_all("<?php " . $code . ";");
$this->tokens = array_filter($tokens, function ($token) {
return (! is_array($token) || $token[0] !== T_WHITESPACE);
});
$this->pop();
}
public function pop () {
return array_shift($this->tokens);
}
public function peek () {
return $this->tokens[0];
}
public function doesMatch ($what) {
$token = $this->peek();
if (is_string($what) && ! is_array($token) && $token === $what) {
return true;
}
else if (is_int($what) && is_array($token) && $token[0] === $what) {
return true;
}
return false;
}
public function forceMatch ($what) {
$token = $this->peek();
if (is_string($what) && (is_array($token) || $token !== $what)) {
throw new Exception("unexpected token - expecting " . $what);
}
else if (is_int($what) && (! is_array($token) || $token[0] !== $what)) {
throw new Exception("unexpected token - expecting " . token_name($what));
}
// consume
$this->pop();
}
}
function parseValue (Tokens $tokens) {
if ($tokens->doesMatch(T_LNUMBER)) {
// long number
$token = $tokens->pop();
return (int) $token[1];
}
if ($tokens->doesMatch(T_DNUMBER)) {
$token = $tokens->pop();
return (double) $token[1];
}
if ($tokens->doesMatch(T_CONSTANT_ENCAPSED_STRING)) {
$token = $tokens->pop();
return stripslashes(substr($token[1], 1, -1));
}
throw new Exception("unexpected value token");
}
function parseArray (Tokens $tokens) {
$uminus = 1;
$found = 0;
$result = array();
$tokens->forceMatch(T_ARRAY);
$tokens->forceMatch("(");
while (true) {
if ($tokens->doesMatch(",") && $found > 0) {
$tokens->forceMatch(",");
}
else if ($tokens->doesMatch(")")) {
$tokens->forceMatch(")");
break;
}
else if ($tokens->doesMatch("-")) {
$tokens->forceMatch("-");
$uminus = -1;
}
else if ($tokens->doesMatch(T_ARRAY)) {
$result[] = parseArray($tokens);
}
else if ($tokens->doesMatch(T_LNUMBER)) {
// long number
$result[] = $uminus * parseValue($tokens);
$uminus = 1;
}
else if ($tokens->doesMatch(T_DNUMBER)) {
// double number
$result[] = $uminus * parseValue($tokens);
$uminus = 1;
}
else if ($tokens->doesMatch(T_CONSTANT_ENCAPSED_STRING)) {
// string
$string = parseValue($tokens);
if ($tokens->doesMatch(T_DOUBLE_ARROW)) {
$tokens->pop();
$result[$string] = parseValue($tokens);
}
else {
$result[] = $string;
}
$uminus = 1;
}
else {
throw new Exception("yet unhandled token type");
}
++$found;
}
return $result;
}
$tokens = new Tokens($string);
$result = parseArray($tokens);
var_dump("RESULT: ", $result);
我可以在http://gnuwin32.sourceforge.net/packages/gawk.htm中找到更高级的解析器版本。
我不是说我建议为此编写自己的解析器。编写自己的解析器可能很棘手且容易出错,如果有更简单的解决方案,应该避免使用它。我只想说清楚eval
仍然可以避免。
首选解决方案可能仍然是与另一方达成一致,采用不同且广泛接受的格式(如JSON)。
答案 1 :(得分:1)
您的字符串未正确转义,请在外部使用"
,然后eval
$string = "array(array('aaa','bbb','ccc','ddd'),array('AAA','BBB','CCC','DDD'))";
$array = eval($string);
echo $array[0][0];
注意:eval
与用户输入结合使用时很危险,并且由于安全问题而无法在所有环境中使用。
答案 2 :(得分:-1)
@cmorrissey你的回答很有帮助
这是解决方案:
$string = '$array = array(array("aa","bb","cc","dd"),array("AA","BB","CC","DD"));';
eval($string);
echo $array[0][0];