如果可能,将字符串作为文字类型返回

时间:2015-07-15 16:13:54

标签: php

我有一个包含一些字符串的数组,如果可能,我需要将每个值转换为文字类型。例如:

$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以某种方式做到了这一点。我应该硬编码吗?

3 个答案:

答案 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)

我不认为有本地方式,如果我是你,我会使用正则表达式来猜测类型。它会工作。但是,它比转换要慢。