在 PHP 7.4 中,json_decode 解码失败(返回 JSON 解码时最后发生的错误,不等于没有错误发生)的分析

1、当 basename: “collections” 时,解码成功。如图1

图1

2、当 basename: “collectiontitem” 时,解码失败。如图2

图2

3、查看 解码 的代码实现

        $result = json_decode($data, true);

        if (json_last_error() !== \JSON_ERROR_NONE) {
            $message = "Invalid json: $data".PHP_EOL;

            if (function_exists('json_last_error_msg')) {
                $message .= ': ' . json_last_error_msg();
            }

            throw new \RuntimeException($message);
        }

4、先分析成功的流程,打印 json_last_error()

        //var_dump($data);
        $result = json_decode($data, true);
        //var_dump($result);
        var_dump(json_last_error());

        if (json_last_error() !== \JSON_ERROR_NONE) {
            //dd(json_last_error());
            $message = "Invalid json: $data".PHP_EOL;

            if (function_exists('json_last_error_msg')) {
                $message .= ': ' . json_last_error_msg();
            }

            throw new \RuntimeException($message);
        }
int(0)
int(0)
int(0)
int(0)
int(0)
int(0)
int(0)
int(0)
int(0)
int(0)
int(0)
int(0)
int(0)
int(0)
int(0)
int(0)
int(0)
int(0)
int(0)
int(0)
int(0)
int(0)
int(0)
int(0)
int(0)
int(0)
int(0)
int(0)
int(0)
int(0)
int(0)

5、再分析失败的流程,打印 json_last_error(),其中一次失败的值等于 4。如图3

图3

int(0)
int(0)
int(0)
int(0)
int(0)
int(0)
int(0)
int(0)
int(0)
int(0)
int(0)
int(0)
int(0)
int(0)
int(0)
int(0)
int(0)
int(0)
int(0)
int(0)
int(0)
int(0)
int(0)
int(0)
int(0)
int(0)
int(0)
int(0)
int(0)
int(4)

6、打印当值为 4 时的 $data、$result

        //var_dump($data);
        $result = json_decode($data, true);
        //var_dump($result);
        //var_dump(json_last_error());
        //exit;

        if (json_last_error() !== \JSON_ERROR_NONE) {
            var_dump($data);
            var_dump($result);
            var_dump(json_last_error());
            exit;
            //dd(json_last_error());
            $message = "Invalid json: $data".PHP_EOL;

            if (function_exists('json_last_error_msg')) {
                $message .= ': ' . json_last_error_msg();
            }

            throw new \RuntimeException($message);
        }
string(872) "
{
  "sections": {
    "collection": {
      "type": "collection",
      "settings": {
        "slug": "{{ $CollectionsSlug }}",
        "page": {{ Request::query('page') ?? '1' }}
      }
    },
    "carousel": {
      "type": "carousel",
      "settings": {
        "color_scheme": "inverse",
        "loop": true,
        "autoplay": true,
        "interval": 10,
        "slidesPerView": 6
      },
      "blocks": {
        "slide-1": {
          "type": "slide",
          "settings": {
            "image": "https://cdn.cloudfastin.com/assets/2021/06/4fdfbe61604c5abe7e07746042e532b1.jpg"
          }
        },
        "slide-2": {
          "type": "slide",
          "settings": {
            "image": "https://cdn.cloudfastin.com/assets/2021/06/45077c55aa09821c24aa1610ff7d3830.jpg"
          }
        }
      }
    }
  }
}
"
NULL
int(4)

7、当删除 “page”: {{ Request::query(‘page’) ?? ‘1’ }} 后,解析成功。最终分析得出原因在于 JSON_ERROR_SYNTAX 语法错误。如图4

图4

            if (json_last_error() === \JSON_ERROR_SYNTAX) {
                echo 'JSON_ERROR_SYNTAX';
            }

8、编辑 $data,需要将 “page”: {{ Request::query(‘page’) ?? ‘1’ }} 替换为 “”page”: {{ Request::query(‘page’) ?? ‘1’ }}”。但是,page 的值类型为 int ,现在这样已经变化为了 string 类型。最为根本的解决方案应该是想办法运行程序,将其变化为 “page”: 1 才是。如图5

图5

        $result = json_decode($data, true);
        var_dump($data);
        var_dump($result);
        var_dump(json_last_error());

        if (json_last_error() !== \JSON_ERROR_NONE) {
            $message = "Invalid json: $data".PHP_EOL;

            if (function_exists('json_last_error_msg')) {
                $message .= ': ' . json_last_error_msg();
            }

            throw new \RuntimeException($message);
        }
string(838) "
{
  "sections": {
    "collection": {
      "type": "collection",
      "settings": {
        "slug": "{{ $CollectionsSlug }}",
        "page": "{{ Request::query('page') ?? '1' }}"
      }
    },
    "carousel": {
      "type": "carousel",
      "settings": {
        "color_scheme": "inverse",
        "loop": true,
        "autoplay": true,
        "interval": 10,
        "slidesPerView": 6
      },
      "blocks": {
        "slide-1": {
          "type": "slide",
          "settings": {
            "image": "https://cdn.cloudfastin.com/assets/2021/06/4fdfbe61604c5abe7e07746042e532b1.jpg"
          }
        },
        "slide-2": {
          "type": "slide",
          "settings": {
            "image": "https://cdn.cloudfastin.com/assets/2021/06/45077c55aa09821c24aa1610ff7d3830.jpg"
          }
        }
      }
    }
  }
}
"
array(1) {
  ["sections"]=>
  array(2) {
    ["collection"]=>
    array(2) {
      ["type"]=>
      string(10) "collection"
      ["settings"]=>
      array(2) {
        ["slug"]=>
        string(22) "{{ $CollectionsSlug }}"
        ["page"]=>
        string(35) "{{ Request::query('page') ?? '1' }}"
      }
    }
    ["carousel"]=>
    array(3) {
      ["type"]=>
      string(8) "carousel"
      ["settings"]=>
      array(5) {
        ["color_scheme"]=>
        string(7) "inverse"
        ["loop"]=>
        bool(true)
        ["autoplay"]=>
        bool(true)
        ["interval"]=>
        int(10)
        ["slidesPerView"]=>
        int(6)
      }
      ["blocks"]=>
      array(2) {
        ["slide-1"]=>
        array(2) {
          ["type"]=>
          string(5) "slide"
          ["settings"]=>
          array(1) {
            ["image"]=>
            string(79) "https://cdn.cloudfastin.com/assets/2021/06/4fdfbe61604c5abe7e07746042e532b1.jpg"
          }
        }
        ["slide-2"]=>
        array(2) {
          ["type"]=>
          string(5) "slide"
          ["settings"]=>
          array(1) {
            ["image"]=>
            string(79) "https://cdn.cloudfastin.com/assets/2021/06/45077c55aa09821c24aa1610ff7d3830.jpg"
          }
        }
      }
    }
  }
}
int(0)

 

永夜