开发者

strip null values of json object

开发者 https://www.devze.com 2023-04-12 18:08 出处:网络
All my AJAX requests are in jso开发者_如何转开发n format which are being parsed in javascript.

All my AJAX requests are in jso开发者_如何转开发n format which are being parsed in javascript.

How can i prevent null values being displayed in an HTML page without needing to write an if-statement in javascript for each json value?

Or should i write a custom PHP function to encode an array to json instead of using json_encode() so it doesn't display 'null' ?


In server side with PHP,

You can use array_filter before json_encode.

array_filter without second argument removes null elements of entry array, example :

$object= array(
             0 => 'foo',
             1 => false,
             2 => -1,
             3 => null,
             4 => ''
          );

$object = (object) array_filter((array) $object);
$result = json_encode($object);

The $result contains:

{"0":"foo","2":-1}

As you see, the null elements are removed.


I'm going to add to the accepted answer because that will only work if you have a 1 dimensional object or array. If there is any array or object nesting then in order to get the accepted solution to work, you must create some sort of recursive array filter. Not ideal.

The best solution my colleague and I came up with was to actually perform a regular expression on the JSON string before it was returned from the server.

$json = json_encode($complexObject);
echo preg_replace('/,\s*"[^"]+":null|"[^"]+":null,?/', '', $json);

The regular expression will remove all places in the string of the form ,"key":null including any whitespace between the leading comma and the start of the key. It will also match "key":null, afterwards to make sure that no null values were found at the beginning of a JSON object.

This isn't an ideal solution but it's far better than creating a recursive array filter given an object could be several dimensions deep. A better solution would be if json_encode had a flag that let you specify if you wanted null entries to remain in the output string.


To remove only NULL, but keep FALSE, '', and 0:

function is_not_null($var)
{
    return !is_null($var);
}

echo json_encode(array_filter((array) $object, 'is_not_null'));


public function __toString() {
    $obj = clone $this;
    $keys = get_object_vars($obj);
    foreach ($keys as $key => $value) {
        if (!$value) {
            unset($obj->{$key});
        }
    }
    return json_encode($obj);
}


What about using the native JSON.stringify method on the javascript side? You can set, a second parameter, a function to remove keys with a null value. If you return undefined, the property is not included in the output JSON string (check the documentation for "the replacer parameter" at https://developer.mozilla.org/en-US/docs/Using_native_JSON#The_replacer_parameter).

function removeNulls(obj) {
    var str = JSON.stringify(obj, function(key, val) {
        if (val == null) return undefined;
        return val;
    });
    return JSON.parse(str);
}

Then you can have a "normalized" JSON object by calling:

var obj = removeNulls(obj);


echo json_encode(array_filter((array) $object, function($val) {
    return !empty($val);
}));


class Foo implements JsonSerializable
{
    public $param1;
    public $param2;
    
    public function jsonSerialize()
    {
        return array_filter((array) $this, function ($var) {
            return !is_null($var);
        });
    }
}

public function testJsonSerialization()
{
    $expectedJson = '{"param1":true}';

    $foo = new Foo();
    $foo->param1 = true;
    $foo->param2 = null;

    $this->assertEquals(
        $expectedJson,
        json_encode($foo)
    );
}`

of course you can create Abstract class with custom jsonSerialize method and extend all your DTOs from this


A version that works with multi-dimensional arrays.

$withoutNull = function($a) use (&$withoutNull) {
    return array_filter(
        array_map(
            fn($p) => is_array($p) ? $withoutNull($p) : $p, $a
        )
    );
};

Example:

$a = [
    "name" => "nathan",
    "data" => [
        "age" => 27,
        "something" => null
    ],
    "another" => null
];
$b = $withoutNull($a);
print_r($b);

Output:

Array
(
    [name] => nathan
    [data] => Array
        (
            [age] => 27
        )

)
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号