我有一个包含一些字符串的数组,如果可能,我需要将每个值转换为文字类型。例如:
$list = [
"integerPositive" => "123",
"integerNegative" => "-123",
"integerHexadecimal" => "0x10", // not priority
"booleanTrue" => "true",
"booleanFalse" => "false",
"theNull" => "null",
"theEmpty" => "",
"theArray" => "[1, 2, 3]", // not priority
"anyelse" => "keep",
];
将转身:
$list = [
"integerPositive" => 123,
"integerNegative" => -123,
"integerHexadecimal" => 16,
"booleanTrue" => true,
"booleanFalse" => false,
"theNull" => null,
"theEmpty" => null, // or keep empty string
"theArray" => [1, 2, 3],
"anyelse" => "keep",
];
问题:有一些原生方式可以做到这一点?我知道parse_ini_string
以某种方式做到了这一点。我应该硬编码吗?
答案 0 :(得分:1)
这是一个非常天真的尝试,可以处理您的示例输入。可能需要一些调整:
<?php
function string_to_type($s)
{
$s = trim($s);
if (preg_match('/^-?\d+$/', $s) === 1) {
$s = intval($s);
} else if (preg_match('/^-?\d*\.\d+$/', $s) === 1) {
$s = floatval($s);
} else if (preg_match('/^-?0x[[:xdigit:]]+$/', $s) === 1) {
$s = intval($s, 16);
} else if (strcasecmp($s, 'true') == 0) {
$s = true;
} else if (strcasecmp($s, 'false') == 0) {
$s = false;
} else if (strcasecmp($s, 'null') == 0 || $s === '') {
$s = null;
} else if (preg_match('/^\[(.*)\]$/', $s, &$matches) === 1) {
/* This won't handle nested arrays, but depending on
* how your arrays are formatted, you might be able to
* get away with just:
*
* $s = json_decode($s);
*/
$contents = explode(',', $matches[1]);
for ($i = 0; $i < count($contents); $i++) {
$contents[$i] = string_to_type($contents[$i]);
}
$s = $contents;
}
return $s;
}
function array_value_to_type(array $arr)
{
$out = array();
foreach ($arr as $key => $val) {
$out[$key] = string_to_type($val);
}
return $out;
}
$input = array(
"integerPositive" => "123",
"integerNegative" => "-123",
"integerHexadecimal" => "0x10", // not priority
"booleanTrue" => "true",
"booleanFalse" => "false",
"theNull" => "null",
"theEmpty" => "",
"theArray" => "[1, 2, 3]", // not priority
"anyelse" => "keep",
);
$output = array_value_to_type($input);
var_dump($input);
var_dump($output);
?>
答案 1 :(得分:1)
你真的应该把变量编码为JSON ...... whitch使得解码成为真正的类型非常容易。 如果您无法控制字符串的来源,下面是原始解码的粗略示例......并非特别漂亮。
function listEntryDecoder($v){
if($v=='true'){
return true;
} else if($v=='false'){
return false;
} else if($v=='null'){
return null;
} else if( is_numeric($v) ){
return (int)$v;
} else if(substr($v,0,1)=='['){//Arrays
$PartResult = explode(',',substr($v,1,-1));
foreach($PartResult as $Pk => $Pv){
$PartResult[$Pk] = listEntryDecoder($Pv);//Recursion = dangerous
}
return $PartResult;
} else {
return $v;
}
}
$list = [
"integerPositive" => "123",
"integerNegative" => "-123",
"integerHexadecimal" => "0x10", // not priority
"booleanTrue" => "true",
"booleanFalse" => "false",
"theNull" => "null",
"theEmpty" => "",
"theArray" => "[1, 2, 3]", // not priority
"anyelse" => "keep",
];
$list2 = array();
foreach($list as $k => $v){
$list2[$k] = listEntryDecoder($v);
}
这给出了以下输出:
array(9) {
["integerPositive"]=>
int(123)
["integerNegative"]=>
int(-123)
["integerHexadecimal"]=>
int(0)
["booleanTrue"]=>
bool(true)
["booleanFalse"]=>
bool(false)
["theNull"]=>
NULL
["theEmpty"]=>
string(0) ""
["theArray"]=>
array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
}
["anyelse"]=>
string(4) "keep"
}
答案 2 :(得分:0)
我不认为有本地方式,如果我是你,我会使用正则表达式来猜测类型。它会工作。但是,它比转换要慢。