JSON Dari Database – PHP dan MySQL

Pada artikel sebelumnya telah kita bahas lengkap mengenai JSON Pada PHP, pada kesempatan ini, kita akan membahas bagaimana membuat JSON dari database beserta permasalahan yang ada.
Sebelum melanjutkan membaca artikel ini, sebaiknya sobat sudah membaca artikel: Memahami JSON Pada PHP

I. Membuat JSON dari Database

Sebelum melanjutkan membahas tentang JSON dari database, kita perlu contoh data. Untuk contoh data, misal kita memiliki tabel artikel yang ada di database blog dengan data sebagai berikut:
idtitlecontent
1Memahami JSON di PHP<img src=”https://jagowebdev.com/images/logo_json.png”/> JSON merupakan kependekan dari “Javascript Object Notation”. JSON memiliki standar penulisan, yang dapat dilihat di <a href=”http://json.org”>JSON.ORG</a>JSON tidak menganggap tanda kuti satu ( ‘ ) sebagai karakter khusus sehingga tidak di-<em>escape</em>, namun bukan berarti tidak akan menimbulkan masalah, misal jika digunakan pada <span style=’color:red’>tag HTML</span>
2Panduan memahami JSON di PHP  –  Part IIArtikel ini merupakan kelanjutan dari artikel <a href=”https://jagowebdev.com/memahami-json-di-php/”>sebelumnya</a>.
Pada bagian ini, kita akan membahas lebih jauh opsi yang dapat kita gunakan ketika menggunakan fungsi json_encode() selain itu dibahas handling error ketika bekerja dengan JSON
Catatan: kolom content memiliki collation latin1_swedish_ci yang berarti juga menggunakan character set latin1_swedish
Selanjutnya, dengan fungsi json_encode, kita buat data JSON sebagai berikut:
$conn = mysqli_connect('localhost', 'root', '', 'blog');
$query = mysqli_query($conn, 'SELECT * FROM article WHERE id=1');
while ($row = mysqli_fetch_assoc($query)) {
 $data[] = $row;
}
echo '<pre>'; print_r($data); echo '</pre>';    
echo json_encode($data);
Hasil yang kita peroleh adalah:
Array
(
    [0] => Array
        (
            [id] => 1
            [title] => Memahami JSON di PHP
            [content] => <img src="http://localhost/images/logo_json.png"/>
JSON merupakan kependekan dari "Javascript Object Notation". JSON memiliki standar penulisan,  yang dapat dilihat di <a href="http://json.org">JSON.ORG</a>
JSON tidak menganggap tanda kuti satu ( ' ) sebagai karakter khusus sehingga tidak di-<em>escape</em>, namun bukan berarti tidak akan menimbulkan masalah, misal jika digunakan pada <span style='color:red'>tag HTML</span>
        )
)

[{"id":"1","title":"Memahami JSON di PHP","content":"<img src=\"http:\/\/localhost\/images\/logo_json.png\"\/>\r\nJSON merupakan kependekan dari \"Javascript Object Notation\". JSON memiliki standar penulisan,  yang dapat dilihat di <a href=\"http:\/\/json.org\">JSON.ORG<\/a>\r\n\r\nJSON tidak menganggap tanda kuti satu ( ' ) sebagai karakter khusus sehingga tidak di-<em>escape<\/em>, namun bukan berarti tidak akan menimbulkan masalah, misal jika digunakan pada <span style='color:red'>tag HTML<\/span>"}]
Note: Perhatikan bahwa pada contoh diatas, karena sumber data berbentuk indexed array, maka data JSON awal yang dihasilkan juga berbentuk array.
Atau karena data yang kita ambil hanya satu row, maka kita dapat langsung fetchhing data tersebut tanpa perlu menggunakan loop while sebagai berikut:
$conn = mysqli_connect('localhost', 'root', '', 'blog');
$query = mysqli_query($conn, 'SELECT * FROM article WHERE id=1');
$row = mysqli_fetch_assoc($query);
echo '<pre>'; print_r($row); echo '<pre>';   
echo json_encode($row);
Hasil:
Array
(
    [id] => 1
    [title] => Memahami JSON di PHP
    [content] => ...
)
{"id":"1","title":"Memahami JSON di PHP","content":"<img src=\"http:\/\/localhost\/images\/logo_json.png\"\/>\r\nJSON merupakan kependekan dari \"Javascript Object Notation\". JSON memiliki standar penulisan,  yang dapat dilihat di <a href=\"http:\/\/json.org\">JSON.ORG<\/a>\r\n\r\nJSON tidak menganggap tanda kuti satu ( ' ) sebagai karakter khusus sehingga tidak di-<em>escape<\/em>, namun bukan berarti tidak akan menimbulkan masalah, misal jika digunakan pada <span style='color:red'>tag HTML<\/span>"}
Perhatikan bahwa pada hasil diatas, karena sumber data berupa associative array, maka JSON yang dihasilkan berbentuk objek.
Perbedaan array dan objek pada JSON dapat dibaca disini: Panduan Lengkap Memahami JSON

II. Permasalahan Encoding UTF-8

Pada artikel sebelumnya kita ketahui bahwa argumen pertama dari fungsi json_encode(), yaitu teks yang akan diubah menjadi JSON harus di encode menggunakan UTF-8.
Ketika kita membuat JSON dari database, terkadang kita akan menemui permasalahan encoding ini, karena bisa jadi sebelum masuk ke database data tersebut tidak diencode menggunakan UTF-8, misal data dari inputan user.
Melanjutkan contoh sebelumnya, mari kita ambil semua data artikel dan kita ubah menjadi JSON, script yang kita gunakan adalah sebagai berikut:
$conn = mysqli_connect('localhost', 'root', '', 'blog');
$query = mysqli_query($conn, 'SELECT * FROM article');
while ($row = mysqli_fetch_assoc($query)) {
 $data[] = $row;
}
     
echo json_encode($data);
Ketika script tersebut kita jalankan, ternyata yang kita dapati hanyalah halaman kosong, kenapa? karena telah terjadi error dan jika ketika error, fungsi json_encode() tidak menampilkan pesan apa apa.
Untuk mengetahui error yang terjadi, kita dapat menggunakan fungsi json_last_error_msg() yang ada mulai PHP Versi 5.5.0. Jika fungsi tersebut dijalankan, maka kita dapati pesan sebagai berikut:
Malformed UTF-8 characters, possibly incorrectly encoded
Dari error tersebut terlihat bahwa data mengandung character non UTF-8 sehingga menyebabkan data tersebut gagal diubah menjadi JSON.
Pertanyaannya, bagaimana cara mengetahui character yang menyebabkan error? Mudahnya, kita print data aslinya terlebih dahulu, kemudian kita lihat hasilnya, misal:
$conn = mysqli_connect('localhost', 'root', '', 'blog');
$query = mysqli_query($conn, 'SELECT * FROM artikel');
while($row = mysqli_fetch_assoc($query)) {
 $data[] = $row;
}
     
echo '<pre>'; print_r($row); echo '</pre>';
hasil yang kita peroleh adalah:
Error Membuat JSON Dari Database MySQL
Jika kita perhatikan, terdapat karakter tanda tanya, karakter ini tidak dikenali oleh encoding yang ada (UTF-8) sehingga tidak dapat ditampilkan.
Padahal jika kita lihat di database manager seperti phpMyAdmin, karakter tersebut berupa tanda strip ( – ).
Catatan: Saya memasukkan data terebut dari  Microsoft Word (copy-paste), yang ternyata encodingnya bukan UTF-8 meskipun jika dilihat sepintas tidak ada karakter yang aneh.

III. Mengatasi Permasalahan Encoding UTF-8

Untuk mengatasinya, kita tidak bisa hanya dengan mendefinisikan encoding di header, misal:
header('Content-type: text/html; charset=utf-8');
atau mendefinisikan di meta seperti ini:
<html>
<head>
 <meta charset="utf-8">
</head>
<body>
 ...
</body>
</html>
Kenapa?
Karena ketika kita mengambil data menggunakan fungsi mysqli_query(), proses encoding sudah terjadi menggunakan character set default.
Sehingga jika kita lihat nilai HEX pada data hasil query, karakter tanda tanya tadi sebenarnya adalah: 0x96 atau character ke – 150 dari karakter ASCII sebagai berikut:
$conn = mysqli_connect('localhost', 'root', '', 'blog');
$query = mysqli_query($conn, 'SELECT title FROM article WHERE id = 2');
$row = mysqli_fetch_assoc($query);

$arr = str_split($row['title']);
echo ord($arr[30]); // Hasil: 150;
Karakter ke-150 ini termasuk extended character sehingga tidak tertampung dalam character set UTF-8 (UTF-8 hanya menampung character ASCII dasar, 0-127), sehingga, karakter tersebut tidak dapat ditampilkan.
Lebih lanjut, jika karakter tersebut kita tampilkan menggunakan character set yang menampung karakter tersebut, seperti WINDOWS-1252 atau ISO-8859-1, maka karakter tersebut dapat tampil dengan baik, contoh
header('Content-type: text/html; charset=WINDOWS-1252');
$conn = mysqli_connect('localhost', 'root', '', 'blog');
$query = mysqli_query($conn, 'SELECT title FROM article WHERE id = 2');
$row = mysqli_fetch_assoc($query);

echo '<pre>'; print_r($row); echo '</pre>';
Hasil:
Hasil Encoding Dengan Character Set Yang Benar
NOTE: Lebih jauh tentang character set dapat dibaca di artikel: Memahami Character Set dan Character Encoding
Solusinya?
Lantas, solusinya bagaimana?
Solusi termudahnya adalah kita ketik ulang tanda strip tadi (misal di phpMyAdmin), sehingga content benar-benar di encoding menggunakan utf-8.
Cara lain adalah mendefinisikan encoding sebelum menjalankan fungsi mysqli_query() sebagai berikut:
$conn = mysqli_connect('localhost', 'root', '', 'blog');
mysqli_set_charset($conn, 'utf8');
$query = mysqli_query($conn, 'SELECT * FROM article');
while($row = mysqli_fetch_assoc($query)) {
 $data[] = $row;
}
   
$json = json_encode($data);
echo $json;
Hasil yang kita peroleh adalah:
[
    {
        "id": "1",
        "title": "Memahami JSON di PHP",
        "content": "<img src=\"http:\/\/localhost\/images\/logo_json.png\"\/>\r\nJSON merupakan kependekan dari \"Javascript Object Notation\". JSON memiliki standar penulisan,  yang dapat dilihat di <a href=\"http:\/\/json.org\">JSON.ORG<\/a>\r\n\r\nJSON tidak menganggap tanda kuti satu ( ' ) sebagai karakter khusus sehingga tidak di-<em>escape<\/em>, namun bukan berarti tidak akan menimbulkan masalah, misal jika digunakan pada <span style='color:red'>tag HTML<\/span>"
    },
    {
        "id": "2",
        "title": "Panduan memahami JSON di PHP  \u2013  Part II",
        "content": "Artikel ini merupakan kelanjutan dari artikel <a href=\"http:\/\/jagowebdev.com\/memahami-json-di-php\/\"\/>sebelumnya<\/a>.\r\n\r\nPada bagian ini, kita akan membahas lebih jauh opsi yang dapat kita gunakan ketika menggunakan fungsi json_encode() selain itu dibahas handling error ketika bekerja dengan JSON"
    }
]
Dengan cara ini, fungsi json_encode() dapat berjalan dengan baik, namun, data di database masih tetap berisi karakter non UTF-8, untuk itu, jika memungkinkan ubah karakter yang ada di database.

IV. Tips

Bagaimana agar data di database selalu di encoding menggunakan UTF-8? Satu satunya cara adalah memastikan semua data yang masuk ke dalam database telah diencode menggunakan UTF-8.
Sebagai contoh: jika kita menyediakan form HTML untuk input data, pastikan halaman html tersebut menggunakan encoding UTF-8, misal dengan mendefinisikan meta charset seperti pada contoh sebelumnya.
<html>
<head>
 <meta charset="utf-8">
</head>
<body>
 ...
</body>
</html>
Demikian pembahasan tentang JSON dari Database dan cara mengatasi error “Malformed UTF-8 characters, possibly incorrectly encoded” ketika membuat JSON dengan PHP, semoga bermanfaat.

No comments:

Post a Comment