我有一组用户输入($ atts)作为key =>值对。某些值可以写为数组表达式,例如:
'setting' => 'array(50,25)'
在这些情况下,我想将该字符串中包含的数组表达式转换为实际数组。所以输出将是这样的:
$atts = array(
'setting' => array(50,25),
'another' => 'not written as an array expression'
)
逻辑上写,代码是:
对于数组$ atts中的每个key =>值对... 如果值是一个格式化为数组表达式的字符串... 将该值分解为数组。
有人知道我会用PHP写这个吗?
答案 0 :(得分:3)
function stringToArray($string) {
$string = "return " . $string . ";";
if (function_exists("token_get_all")) {//tokenizer extension may be disabled
$php = "<?php\n" . $string . "\n?>";
$tokens = token_get_all($php);
foreach ($tokens as $token) {
$type = $token[0];
if (is_long($type)) {
if (in_array($type, array(
T_OPEN_TAG,
T_RETURN,
T_WHITESPACE,
T_ARRAY,
T_LNUMBER,
T_DNUMBER,
T_CONSTANT_ENCAPSED_STRING,
T_DOUBLE_ARROW,
T_CLOSE_TAG,
T_NEW,
T_DOUBLE_COLON
))) {
continue;
}
exit("For your security, we stoped data parsing at '(" . token_name($type) . ") " . $token[1] . "'.");
}
}
}
return eval($string);
}
$a='array(10,20)';
print_r(stringToArray($a));
答案 1 :(得分:2)
使用tokenizer:
function stringToArray($str) {
$array = array();
$toks = token_get_all("<?php $str");
if ($toks[1][0] != T_ARRAY || $toks[2] != '(' || end($toks) != ')')
return null;
for($i=3; $i<count($toks)-1; $i+=2) {
if (count($toks[$i]) != 3)
return null;
if ($toks[$i][0] == T_WHITESPACE) {
$i--;
continue;
}
if ($toks[$i][0] == T_VARIABLE || $toks[$i][0] == T_STRING)
return null;
$value = $toks[$i][1];
if ($toks[$i][0] == T_CONSTANT_ENCAPSED_STRING)
$value = substr($value, 1, strlen($value) - 2);
$array[] = $value;
if ($toks[$i + 1] != ',' && $toks[$i + 1] != ')' && $toks[$i + 1][0] != T_WHITESPACE)
return null;
}
return $array;
}
以上内容仅适用于文字。传递变量,常量,表达式,嵌套数组或格式错误的数组声明将返回null
:
stringToArray('array(1,2)'); // works
stringToArray('array(1,2.4)'); // works
stringToArray('array("foo",2)'); // works
stringToArray('array(\'hello\',2)'); // works
stringToArray('array()'); // works
stringToArray('array(1,2 + 3)'); // returns null
stringToArray('array(1,2 + 3)'); // returns null
stringToArray('array("foo"."bar")'); // returns null
stringToArray('array(array("hello"))'); // returns null
stringToArray('array($a,$b)'); // returns null
stringToArray('array(new bar)'); // returns null
stringToArray('array(SOME_CONST)'); // returns null
stringToArray('hello'); // returns null
您还可以使用以下内容检查字符串是否为数组表达式:
function isArrayExpression($str) {
$toks = token_get_all("<?php $str");
return (
$toks[1][0] == T_ARRAY &&
$toks[2] == '(' &&
end($toks) == ')'
);
}
isArrayExpression('array(1,2,3)'); // true
isArrayExpression('array is cool'); // false
isArrayExpression('array(!!!!'); // false
您可以随时根据自己的需要进行调整。希望这会有所帮助。
答案 2 :(得分:0)
您可以使用eval,但我强烈建议您不要使用它,而是尝试重新考虑您的设计以更好的方式来处理设置。 所以对你的例子而不是存储
'setting' => 'array(50,25)'
你可以做点什么吗
'setting' => array('type'=>'array', 'value'=>'50, 25')
然后加载设置 你可以做到
switch($type)
case 'array'
$val = explode(', ', $value)
或类似的东西
但与其他人建议的那样,我会尝试使用序列化来保存设置
答案 3 :(得分:0)
正如你的帖子评论中所建议的,eval()会做你想要的。但是,首先将数组存储为字符串并不实际。如果您希望数据更具便携性,我建议您使用json_encode()甚至serialize()