简体   繁体   中英

json_encode doesn't works on array_splice return but works if called directly

My goal is very simple, I want to parse the $GLOBALS variable in JSON (to log it). According to this Stackoverflow post, https://stackoverflow.com/a/23176085/1369579 , I have to remove the recursive variable.

The following code works:

<?php

$global_array = $GLOBALS;
$index = array_search('GLOBALS',array_keys($global_array));
$json = json_encode(array_splice($global_array, $index, $index-1));
var_dump($json);

?>

It returns string(59) "{"GLOBALS":{"_GET":[],"_POST":[],"_COOKIE":[],"_FILES":[]}}" (in http://sandbox.onlinephpfunctions.com )

But I have to use an intermediate variable to store the array_splice result. When I do this, I doesn't works:

<?php

$global_array = $GLOBALS;
$index = array_search('GLOBALS',array_keys($global_array));
$splice_result = array_splice($global_array, $index, $index-1);
var_dump(json_encode($splice_result));

?>

The result is bool(false) and the json_last_error_msg() returns Recursion detected .

What the difference between the two versions? I really don't understand. For me foo(bar()) is the exactly the same code than $bar = bar(); foo($bar) $bar = bar(); foo($bar)

I just understood my problem, the call of array_splice remove the $GLOBALS variable… but I still don't understand why.

I tried to put my code into a function, because I thought my problem was to put the code directly in the global scope:

<?php

function globalWithoutGlobals() {
    $global_array = $GLOBALS;
    $index = array_search('GLOBALS',array_keys($global_array));
    array_splice($global_array, $index, 1);
    return $global_array;
}

var_dump(json_encode(globalWithoutGlobals()));
var_dump(json_encode(globalWithoutGlobals()));

/* returns
# First call: success, 
string(47) "{"_GET":[],"_POST":[],"_COOKIE":[],"_FILES":[]}"
# Second call : wtf ?!!
<br />
<b>Notice</b>:  Undefined variable: GLOBALS in <b>[...][...]</b> on line <b>4</b><br />
*/

It's still very weird for me, the $global_array should be changed, not the $GLOBALS . To test this behaviour, I did the same thing on others arrays (with recursion too):

<?php

// Looks like $GLOBALS (with recursive element)
$globals_array = ["foo" => "bar"];
$globals_array['GLOBALS'] = &$globals_array;

$copy = $globals_array;
$index = array_search('GLOBALS', array_keys($copy));
array_splice($copy, $index, 1);

var_dump($globals_array);
var_dump($copy);

/* return:
array(2) {
  ["foo"]=>
  string(3) "bar"
  ["GLOBALS"]=>
  &array(2) {
    ["foo"]=>
    string(3) "bar"
    ["GLOBALS"]=>
    *RECURSION*
  }
}
array(1) {
  ["foo"]=>
  string(3) "bar"
}
*/

It returns the expected output, so why the behaviour is not the same with $GLOBALS ? 😩

To resolve my issue, I changed my approach and I stopped used array_splice , instead I just do a naive implementation with a foreach on the $GLOBALS and it works like expected:

<?php

function globalWithoutGlobals() {
    $result = [];
    foreach ($GLOBALS as $key => $value) {
        if ($key !== 'GLOBALS') {
            $result[$key] = $value;
        }
    }
    return $result;
}

var_dump(json_encode(globalWithoutGlobals()));
var_dump(json_encode(globalWithoutGlobals()));

/* it returns:
string(47) "{"_GET":[],"_POST":[],"_COOKIE":[],"_FILES":[]}"
string(47) "{"_GET":[],"_POST":[],"_COOKIE":[],"_FILES":[]}"
*/

If someone know why the behaviour is different between my two first examples above. I'm curious to understand 😊

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM