【问题标题】:strip null values of json object去除 json 对象的空值
【发布时间】:2011-10-12 14:10:08
【问题描述】:

我所有的 AJAX 请求都是 json 格式,并在 javascript 中解析。

如何防止空值显示在 HTML 页面中,而无需在 javascript 中为每个 json 值编写 if 语句?

或者我应该编写一个自定义 PHP 函数来将数组编码为 json,而不是使用 json_encode(),这样它就不会显示“null”?

【问题讨论】:

    标签: php json


    【解决方案1】:

    在服务器端使用 PHP,

    您可以在json_encode 之前使用array_filter

    array_filter 不带第二个参数会删除条目数组的 null 元素,例如:

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

    $result 包含:

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

    如您所见,null 元素已被移除。

    【讨论】:

    • 感谢您的回答,但这不适用于多维数组,删除键将导致“未定义”值
    • @Sobek,顺便说一句,您不能同时删除一个值并保留密钥。
    【解决方案2】:

    我将添加到已接受的答案中,因为这仅在您拥有一维对象或数组时才有效。如果有任何数组或对象嵌套,那么为了使公认的解决方案起作用,您必须创建某种递归数组过滤器。不理想。

    我的同事和我想出的最佳解决方案是在 JSON 字符串从服务器返回之前实际执行正则表达式。

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

    正则表达式将删除格式为,"key":null 的字符串中的所有位置,包括前导逗号和键开头之间的任何空格。之后它还会匹配"key":null,,以确保在 JSON 对象的开头没有找到空值。

    这不是一个理想的解决方案,但它比创建递归数组过滤器要好得多,因为对象可能有几个维度深。更好的解决方案是 json_encode 有一个标志,可以让您指定是否希望空条目保留在输出字符串中。

    【讨论】:

    • 最后这对我有用。我有多维 JSON 对象。我同意如果json_encode 本身支持它会很好,但我非常怀疑这是否会发生。至少在我的经验中,PHP 在多维方面往往很弱。
    • 这对我有用,但我在每个 null 之前添加了 `?` 以说明何时设置 JSON_PRETTY_PRINT 并且键和值之间有空格。
    • 由于某种原因这对我不起作用。
    【解决方案3】:

    只删除NULL,但保留FALSE''0

    function is_not_null($var)
    {
        return !is_null($var);
    }
    
    echo json_encode(array_filter((array) $object, 'is_not_null'));
    

    【讨论】:

      【解决方案4】:
      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);
      }
      

      【讨论】:

      • 也许您可以添加一些评论和解释,教我们!仅放置代码的附加值较少。
      • @HonzaZidek __toString() 是一种神奇的方法,当对象被转换为字符串时会被调用。所做的是返回被调用对象的副本,但首先遍历它并取消设置其所有属性。你会做类似 var_dump((string) $object).
      【解决方案5】:

      在 javascript 端使用原生 JSON.stringify 方法怎么样? 您可以设置第二个参数,一个函数来删除具有空值的键。 如果返回 undefined,则该属性不包含在输出 JSON 字符串中(请查看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);
      }
      

      然后你可以通过调用得到一个“标准化”的 JSON 对象:

      var obj = removeNulls(obj);
      

      【讨论】:

        【解决方案6】:
        echo json_encode(array_filter((array) $object, function($val) {
            return !empty($val);
        }));
        

        【讨论】:

        • 查看接受的答案:不带第二个参数的array_filter 将删除条目数组的空元素。所以,这比你的提议要简单得多。
        【解决方案7】:
        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)
            );
        }`
        

        当然,您可以使用自定义 jsonSerialize 方法创建抽象类,并由此扩展您的所有 DTO

        【讨论】:

          猜你喜欢
          • 2022-01-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多