Sau khi chúng ta đã học được 2 phần của bài học, chắc hẳn bạn đã nắm được một số kiến thức về JSON. Và ở phần cuối này mình sẽ hướng dẫn cho các bạn về việc gỡ lỗi JSON trong PHP. Mình cũng không thể giới thiệu hết tất cả được nên các bạn có thể tham khảo chi tiết tại https://www.php.net/

6. Các thông số của JSON

Cú pháp của JSON trong PHP:

  • string json_encode ( mixed $value [, int $options = 0 [, int $depth = 512 ]] )
  • mixed json_decode ( string $json [, bool $assoc = false [, int $depth = 512 [, int $options = 0 ]]] )

Ý nghĩa của các thông số này mình sẽ giải thích cụ thể như sau:

Json_encode:

  • Value: Giá trị đang được mã hóa. Có thể là bất kỳ loại nào ngoại trừ một tài nguyên. Tất cả dữ liệu chuỗi phải được mã hóa UTF-8
  • Options: Bitmask bao gồm SON_HEX_QUOT, JSON_HEX_TAG, JSON_HEX_AMP, JSON_HEX_APOS, JSON_NUMERIC_CHECK, JSON_PRETTY_PRINT, JSON_UNESCAPED_SLASHES, JSON_FORCE_OBJECT, JSON_PRESERVE_ZERO_FRACTION, JSON_UNESCAPED_UNICODE, JSON_PARTIAL_OUTPUT_ON_ERROR.
  • Depth: Đặt độ sâu tối đa. Phải lớn hơn 0

Json_decode:

  • json: Chuỗi json đang được giải mã. Chức năng này chỉ hoạt động với các chuỗi được mã hóa UTF-8.
  • assoc: Hàm nên trả về mảng kết hợp thay vì các đối tượng.
  • option: Bitmask của các tùy chọn giải mã JSON. Hiện tại chỉ JSON_BIGINT_AS_STRING được hỗ trợ (mặc định là truyền các số nguyên lớn dưới dạng số nổi)

Chú ý

Việc xử lý json_decode đối với JSON không hợp lệ rất phức tạp và rất khó xác định một cách đáng tin cậy nếu quá trình giải mã thành công, json_decode trả về null cho đầu vào không hợp lệ, mặc dù null cũng là một đối tượng hoàn toàn hợp lệ để JSON giải mã. Để tránh những sự cố như vậy, bạn nên luôn gọi json_last_error mỗi khi sử dụng.

7. Gỡ lỗi JSON trong PHP

Khi json_encode hoặc json_decode không phân tích được chuỗi được cung cấp, nó sẽ trả về false. Bản thân PHP sẽ không đưa ra bất kỳ lỗi hoặc cảnh báo nào khi điều này xảy ra, nguyên nhân là do người dùng sử dụng hàm json_last_error()json_last_error_msg() để kiểm tra xem có lỗi xảy ra hay không và hành động tương ứng trong ứng dụng của bạn (gỡ lỗi, hiển thị thông báo lỗi , …).

Ví dụ: mình sẽ đưa ra một lỗi mà khá phổ biến đó là không thể giải mã/mã hóa một chuỗi JSON:

// Chuỗi JSON được tạo không chính xác
$jsonString = json_encode("{'Bad JSON':\xB1\x31}");
if (json_last_error() != JSON_ERROR_NONE) {
    printf("JSON Error: %s", json_last_error_msg());
}

#> JSON Error: Malformed UTF-8 characters, possibly incorrectly encoded

8. Hàm json_last_error_msg

Hàm json_last_error_msg() trả về thông báo mà người lập trình cơ thể đọc được về lỗi cuối cùng xảy ra khi cố gắng mã hóa / giải mã một chuỗi:

  • Hàm này sẽ luôn trả về một chuỗi , ngay cả khi không có lỗi xảy ra.
  • Chuỗi không lỗi mặc định là No Error
  • Nó sẽ trả về false nếu xảy ra một số lỗi (không xác định) khác
  • Hãy cẩn thận khi sử dụng điều này trong các vòng lặp, vì json_last_error_msg sẽ bị ghi đè trên mỗi lần lặp.

Ta chỉ nên sử dụng chức năng này để hiển thị thông báo, không phải để kiểm tra đối chiếu trong các câu lệnh điều khiển.

9. Hàm json_last_error

Hàm json_last_error() trả về một số nguyên được ánh xạ tới một trong các hằng số được xác định trước do PHP cung cấp.

Ta sẽ có một số hàm về lỗi trong JSON:

  • JSON_ERROR_NONE: không có lỗi nào xảy ra
  • JSON_ERROR_DEPT: đã vượt quá độ sâu ngăn xếp tối đa
  • JSON_ERROR_STATE_MISMATCH: JSON không hợp lệ hoặc không đúng định dạng
  • JSON_ERROR_CTRL_CHAR: lỗi ký tự điều khiển, có thể được mã hóa không chính xác
  • JSON_ERROR_SYNTAX: lỗi cú pháp (kể từ PHP 5.3.3)
  • JSON_ERROR_UTF8: các ký tự UTF-8 không đúng định dạng, có thể được mã hóa không chính xác (kể từ PHP 5.5.0)
  • JSON_ERROR_RECURSION: một hoặc nhiều tham chiếu đệ quy trong giá trị được mã hóa
  • JSON_ERROR_INF_OR_NAN: một hoặc nhiều giá trị NAN hoặc INF trong giá trị được mã hóa
  • JSON_ERROR_UNSUPPORTED_TYPE: đã đưa ra một giá trị thuộc loại không thể mã hóa
<?php
// Một chuỗi json hợp lệ
$json[] = '{"Organization": "PHP Documentation Team"}';

// Một chuỗi json không hợp lệ sẽ gây ra cú pháp
// lỗi, trong trường hợp này chúng tôi đã sử dụng "instead of" để báo giá
$json[] = "{'Organization': 'PHP Documentation Team'}";


foreach ($json as $string) {
    echo 'Decoding: ' . $string;
    json_decode($string);

    switch (json_last_error()) {
        case JSON_ERROR_NONE:
            echo ' - Không có lỗi';
        break;
        case JSON_ERROR_DEPTH:
            echo ' - Đã vượt quá độ sâu ngăn xếp tối đa';
        break;
        case JSON_ERROR_STATE_MISMATCH:
            echo ' - Dòng chảy dưới hoặc các chế độ không khớp';
        break;
        case JSON_ERROR_CTRL_CHAR:
            echo ' - Đã tìm thấy ký tự điều khiển không mong muốn';
        break;
        case JSON_ERROR_SYNTAX:
            echo ' - Lỗi cú pháp, JSON không đúng định dạng';
        break;
        case JSON_ERROR_UTF8:
            echo ' - Ký tự UTF-8 không đúng định dạng, có thể được mã hóa không chính xác';
        break;
        default:
            echo ' - Lỗi không thể nhận biết';
        break;
    }

    echo PHP_EOL;
}
?>

10. Giải mã chuỗi JSON trong PHP

Các hàm json_decode() phải mất một chuỗi JSON-mã hóa như tham số đầu tiên của nó và phân tích nó thành một biến PHP.

Thông thường, json_decode() sẽ trả về một đối tượng của \ stdClass nếu mục cấp cao nhất trong đối tượng JSON là một từ điển hoặc một mảng được lập chỉ mục nếu đối tượng JSON là một mảng. Nó cũng sẽ trở lại giá trị vô hướng hoặc NULL cho các giá trị vô hướng nhất định, chẳng hạn như chuỗi đơn giản, “true”, “false”, và “null”. Nó cũng trả NULL về bất kỳ lỗi nào.