php 用递归方法把json转换成数组?

juzqafwq  于 12个月前  发布在  PHP
关注(0)|答案(8)|浏览(124)

我正在尝试将数组中的json字符串转换为数组,

$config = array(
    "type"  => '{"category":"admin","page":"page"}',
    "say"     => "Hello",
    "php"   => array(
        "say"     => "no",
        "type"  => '{"category":"admin","page":"page"}',
        "gran"  =>array(
            "name" => "Hi"
        )
    )
);

字符串
我的工作代码,

class objectify
{

    public function json_to_array($array, $recursive = true)
    {
        # if $array is not an array, let's make it array with one value of former $array.
        if (!is_array($array)) $array = array($array);

        foreach($array as $key => $value)
        {
            if($recursive === false) $array[$key] = (!empty($value) && is_string($value) && json_decode($value) != NULL) ? json_decode($value, true): $value;
                else $array[$key] = (!empty($value) && is_string($value) && json_decode($value) != NULL) ? json_decode($value, true): is_array($value) ? self::json_to_array($array) : $value;
        }

        return $array;
    }
}


它工作得很好 * 没有 * 递归方法**,但当我想做递归时,你可以在上面的代码中看到,

$object = new objectify();
$config = $object->json_to_array($config);
print_r($config);


错误消息,

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 2048 bytes) in C:\wamp\www\test\2012\php\set_variable.php on line 79


我只想得到这个结果,

Array
(
    [type] => Array
        (
            [category] => admin
            [page] => page
        )
    [say] => Hello
        (
            [say] => no
            [type] => {"category":"admin","page":"page"}
            [gran] => Array
                (
                    [name] => Hi
                )

        )

)

编辑:

$config = 'type={"category":"admin","page":"page"}&text_editor={"name":"mce-basic"}&parent_id=self&subtitle=true&description=true&content_1=true&script_1=true&primary_image=true';
parse_str($config,$array);
print_r($array);


结果表明,

Array
(
    [type] => {"category":"admin","page":"page"}
    [text_editor] => {"name":"mce-basic"}
    [parent_id] => self
    [subtitle] => true
    [description] => true
    [content_1] => true
    [script_1] => true
    [primary_image] => true
)

yizd12fk

yizd12fk1#

快速解决方案:

$full_array = array_map('json_decode', $array);

字符串
如果不是所有的参数都是JSON,并且你想要实际的数组而不是stdClass对象,你可能必须这样做:

function json_decode_array($input) { 
  $from_json =  json_decode($input, true);  
  return $from_json ? $from_json : $input; 
}
$full_array = array_map('json_decode_array', $array);


如果你在JSON之外有更多层次的嵌套数组,那么你必须自己做递归。试试这个版本的objectify:

class objectify
{
  public function json_mapper($value, $recursive = true) {
    if (!empty($value) && is_string($value) &&
        $decoded = json_decode($value, true)) {
      return $decoded;
    } elseif (is_array($value) && $recursive) {
      return array_map('objectify::json_mapper', $value);
    } else {
      return $value;
    }
  }

  // currying, anyone?
  public function json_mapper_norecurse($value) { 
     return objectify::json_mapper($value, false);
  }

  public function json_to_array($array, $recursive = true)
  {
    # if $array is not an array, let's make it array with one value of
    # former $array.
    if (!is_array($array)) {
      $array = array($array);
    }

    return array_map(
      $recursive ? 'objectify::json_mapper' 
                 : 'objectify::json_mapper_norecurse', $array);
  }
}


这对我来说在你的两组样本数据上都很有效。

hgqdbh6s

hgqdbh6s2#

就您的代码而言,您似乎犯了一个错误,导致它永远循环(递归部分的最后一部分):

is_array($value) ? self::json_to_array($array) : $value;

字符串
您将整个数组而不是测试为数组的值馈送给递归函数。
将其更改为:

is_array($value) ? self::json_to_array($value) : $value;


应该能解决。

**编辑:**看起来是嵌套的三元条件导致了问题,如果你在第二个条件周围加上大括号,它会起作用:

else
        {
           $array[$key] = (!empty($value) && is_string($value) && json_decode($value) != NULL)
                               ? json_decode($value, true)
                               : (is_array($value) ? self::json_to_array($value) : $value);
        }


See the working example的一个。

h22fl7wq

h22fl7wq3#

如果你想递归地转换所有的json,你需要把json_decode的第二个参数设置为true

$config_array = json_decode($config, true);

字符串

e0uiprwp

e0uiprwp4#

就可以轻松得多完成。

function objectify(& $v, $k) {
    $v_decoded = json_decode($v, true);
    if ($v_decoded) { $v = $v_decoded; }
}

array_walk_recursive($config, 'objectify');
print_r($config);

Array
(
[type] => Array
    (
        [category] => admin
        [page] => page
    )

[say] => Hello
[php] => Array
    (
        [say] => no
        [type] => Array
            (
                [category] => admin
                [page] => page
            )

        [gran] => Array
            (
                [name] => Hi
            )

    )

)

字符串

dsekswqp

dsekswqp5#

如果你使用的是laravel framework并且post参数包含数组,那么在array map中使用json_decode来解码递归值。

$params = array_map('json_decode', $request->all());

字符串

svgewumm

svgewumm6#

function jsonDecodeRecursively(Array &$arr)
{
    foreach($arr as $key => &$val)
    {
        if(is_string($val) && json_decode($val))
        {
            $val = json_decode($val, true);
        }

        if(is_iterable($val))
        {
            jsonDecodeRecursively($val);
        }
    }

    return $arr;
}

字符串
这将遍历父数组并递归地解码所有子元素json编码的数组。

6ovsh4lw

6ovsh4lw7#

要递归地将json字符串转换为数组或对象,请使用以下函数,该函数通过引用修改输入数组/对象,替换json字符串,然后最终返回整个变异的有效负载。
从PHP8.3开始,json_validate()可以很容易地判断一个字符串是否是有效的json。这个原生函数只接受一个字符串作为它的第一个参数。
我的函数被设计成动态地适应那些希望json字符串根据第二个参数变成对象或数组的调用。默认将json字符串转换成数组。
产品编号:(Demo

function decode_json_only(array|object &$data, bool $toArray = true)
{
     foreach ($data as &$v) {
        if (is_string($v) && json_validate($v)) {
            $v = json_decode($v, $toArray);
        }
        if (is_array($v) || is_object($v)) {
            $v = (__FUNCTION__)($v, $toArray);
        }
    }
    return $data;
}

var_export(decode_json_only($config));

字符串

35g0bw71

35g0bw718#

你可以使用简单的功能:

$array = json_decode(json_encode($object), true);

字符串
地址:https://gist.github.com/victorbstan/744478

setTimeout(function () { alert("JavaScript"); }, 1000);

相关问题