1. JSON là gì?

JSON là chữ viết tắt của Javascript Object Notation. Đây là một dạng dữ liệu tuân theo một quy luật nhất định mà hầu hết các ngôn ngữ lập trình hiện nay đều có thể đọc được. Bạn có thể sử dụng lưu nó vào một file, một record trong CSDL rất dễ dàng. JSON là một định dạng tiêu chuẩn trong trao đổi dữ liệu nhẹ, nhanh chóng và dễ dàng tạo (generate) và phân tích (parse) dễ dàng sử dụng và truy vấn hơn XML rất nhiều.

Vì định dạng JSON là một định dạng dựa trên văn bản, nó có thể dễ dàng được gửi đến và từ một máy chủ và được sử dụng làm định dạng dữ liệu bởi bất kỳ ngôn ngữ lập trình nào.

Ví dụ dưới đây mình định nghĩa một chuỗi JSON lưu trữ thông tin cá nhân của mình như sau, đây là ví dụ quan trọng nhất của phần json là gì.

{

"username" : "Thành Nguyễn",

"email" : "thanhnguyen18@gmail.com",

"website" : "Laptrinhtudau.com",

"title" : "Học lập trình với JSON"

}

Như vậy cú pháp của JSON rất đơn giản là mỗi thông tin dữ liệu sẽ có 2 phần đó là keyvalue, điều này tương ứng trong CSDL là tên field và giá trị của nó ở một record nào đó. Tuy nhiên nhìn qua thì đơn giản nhưng nếu ta nói kỹ về nó thì có một vài điều như sau:

  • Chuỗi JSON được bao lại bởi dấu ngoặc nhọn {}
  • Các key, value của JSON bắt buộc phải đặt trong dấu nháy kép {“}, nếu bạn đặt nó trong dấu nháy đơn thì đây không phải là một chuỗi JSON đúng chuẩn. Nên trường hợp trong value của bạn có chứa dấu nháy kép thì hãy dùng dấu (\) để đặt trước nó nhé, ví dụ học \”json là gì\” tại website laptrinhtudau.com.
  • Nếu có nhiều dữ liệu (nhiều cặp key => value) thì ta dùng dấu phẩy (,) để ngăn cách
  • Các key của JSON bạn nên đặt chữ cái không dấu hoặc số, dấu _ và không có khoảng trắng., ký tự đầu tiên không nên đặt là số. Điều này rất giống với nguyên tắc đặt tên biến trong PHP, các bạn có thể xem lại nhé!.

Như vậy ta có thể thấy dữ liệu của JSON được chia làm 2 cấu trúc cơ bản:

  • Object: Được định nghĩa là một tập hợp các cặp key / value.
  • Array: Được định nghĩa là một danh sách các giá trị được sắp xếp.

Trong JSON, các key luôn là các string, trong khi giá trị có thể là một string, number, true hoặc false, null, thậm chí là một Object hoặc một Array. Các string phải được đặt trong dấu ngoặc kép “” và có thể chứa các ký tự thoát như \n, \t và \.

2. Xử lý JSON trong PHP

2.1. Hàm json_decode

Hàm json_decode() được sử dụng để giải mã một đối tượng JSON thành một đối tượng PHP hoặc một mảng kết hợp.

Cú pháp:

json_decode($json_string, $assoc);

Trong đó:

  • $json_string: là chuỗi JSON
  • $assoc có hai giá trị true / false. Nếu true thì kết quả nó trả về là dạng array, ngược lại nếu false thì kết quả trả về dạng object. Mặc định là false.

Ví dụ: ta dùng hàm json_decode để chuyển về dạng mảng và object:

$json_string = 
'
    {
        "name" : "Thành Nguyễn",
        "email" : "Thanhnguyen18@gmail.com",
        "website" : "laptrinhtudau.com"
    }
';
// Dạng Mảng
var_dump(json_decode($json_string, true));
// Dạng Object
var_dump(json_decode($json_string));

2.2. Hàm json_encode

Hàm này có chức năng ngược lại hàm json_decode, nó sẽ chuyển một mảng trong PHP hoặc object trong PHP thành chuỗi JSON. Giá trị được mã hóa có thể là bất kỳ loại dữ liệu PHP nào ngoại trừ tài nguyên như cơ sở dữ liệu hoặc liên quan đến xử lý tệp.

Cú pháp:

json_encode($array);

Trong đó: $array là mảng mà ta muốn chuyển đổi. Kết quả chuỗi JSON sẽ tự động chuyển các ký tự có dấu, các ký tự đặc biệt sang dạng an toàn nên bạn nhìn vào nó hơi khác.

Ví dụ: Sử dụng hàm json_encode để chuyển đổi mảng sau sang chuỗi JSON:

$array = array(
    "name" => "Thành Nguyễn",
    "email" => "Thanhnguyen18@gmail.com",
    "website" => "laptrinhtudau.com" 
); 
echo json_encode($array);

Ví dụ tiếp theo là cách decoding JSON data và cách truy cập các phần tử riêng lẻ của đối tượng JSON hoặc mảng trong PHP:

<?php
// Gán chuỗi được mã hóa JSON cho một biến PHP
$json = '{"Khánh":27,"Đức":32,"Huyền":35,"Thúy":30}';
// Decode JSON data thành mảng kết hợp trong PHP
$arr = json_decode($json, true);
// Truy cập giá trị của mảng kết hợp
echo $arr["Khánh"];  // Output: 27
echo $arr["Đức"];  // Output: 32
echo $arr["Huyền"];   // Output: 35
echo $arr["Thúy"];  // Output: 30
// Decode JSON data thành đối tượng trong PHP
$obj = json_decode($json);
// Truy cập dữ liệu từ đối tượng được trả về
echo $obj->Khánh;   // Output: 65
echo $obj->Đức;   // Output: 80
echo $obj->Huyền;    // Output: 78
echo $obj->Thúy;   // Output: 90
?>

Bạn cũng có thể lặp qua dữ liệu được decoding bằng vòng lặp foreach(), như thế này:

<?php
// Gán chuỗi được mã hóa JSON cho một biến PHP
$json = '{"Khánh":27,"Đức":32,"Huyền":35,"Thúy":30}'; 
// Decode JSON data thành mảng kết hợp trong PHP
$arr = json_decode($json, true);
// Lặp qua mảng Kết hợp
foreach($arr as $key=>$value){
    echo $key . "=>" . $value . "<br>";
}
echo "<hr>";
// Decode JSON data thành đối tượng trong PHP
$obj = json_decode($json);
// Lặp qua đối tượng
foreach($obj as $key=>$value){
    echo $key . "=>" . $value . "<br>";
}
?>

Thông thường chúng ta sẽ kết hợp hàm json_decode trong php để chuyển đổi một mảng các thông tin nào đó sang chuỗi JSON và lưu vào trong CSDL. Sau đó khi lấy thông tin từ MYSQL để hiển thị ra website thì chúng ta dùng hàm json_encode để chuyển đổi ngược trở lại. Như vậy khó khăn lớn nhất của những bạn mới học chính là ý tưởng thiết kế CSDL như thế nào để lưu JSON? Thông thường những field nào mà cần tìm kiếm thông tin thì bạn nên tạo một field riêng. Còn các thông tin mà không áp dụng trong tìm kiếm thì bạn có thể đưa nó vào một chuỗi JSON rồi lưu vào một field. Như vậy sẽ giải được số lượng field.

2.3. Trích xuất giá trị từ dữ liệu JSON lồng nhau trong PHP

Trong khi làm việc với JSON, các đối tượng và mảng JSON cũng có thể được lồng nhau. Một đối tượng JSON có thể tùy ý chứa các đối tượng JSON, mảng, mảng lồng nhau, mảng đối tượng JSON,…

Ví dụ: Ta sẽ giải mã các đối tượng JSON lồng nhau và in tất cả các giá trị nó trong PHP:

<?php
// Khai báo hàm đệ quy để trích xuất các giá trị lồng nhau
function printValues($arr) {
    global $count;
    global $values;  
    // Kiểm tra đầu vào của một mảng
    if(!is_array($arr)){
        die("ERROR: Đầu vào không phải một mảng");
    } 
    /*Lặp qua một mảng
    Nếu giá trị tự nó là một mảng thì gọi hàm đệ quy
    Nếu không thì thêm giá trị tìm thấy vào mảng đầu ra
    Tăng bộ đếm lên 1 đơn vị*/
    foreach($arr as $key=>$value){
        if(is_array($value)){
            printValues($value);
        } else{
            $values[] = $value;
            $count++;
        }
    }
     // Trả về tổng số giá trị được tìm thấy trong Mảng
    return array('total' => $count, 'values' => $values);
} 
// Gán chuỗi JSON được mã hóa cho một biến PHP
$json = '{
    "book": {
        "name": "Harry Potter and the Goblet of Fire",
        "author": "J. K. Rowling",
        "year": 2000,
        "characters": ["Harry Potter", "Hermione Granger", "Ron Weasley"],
        "genre": "Fantasy Fiction",
        "price": {
            "paperback": "$10.40", "hardcover": "$20.32", "kindle": "4.11"
        }
    }
}';
// Decode Dữ liệu JSON thành định dạng mảng kết hợp
$arr = json_decode($json, true);
// Gọi hàm và in tất cả các giá trị
$result = printValues($arr);
echo "<h3>" . $result["total"] . " value(s) found: </h3>";
echo implode("<br>", $result["values"]);
echo "<hr>";
// In giá trị riêng lẻ
echo $arr["book"]["author"] . "<br>";  // Output: J. K. Rowling
echo $arr["book"]["characters"][0] . "<br>";  // Output: Harry Potter
echo $arr["book"]["price"]["hardcover"];  // Output: $20.32
?>