jsonobject
jsonobject
adalah kelas PHP untuk memudahkan penggunaan objek yang berasal dari definisi JSON. Idenya berasal dari penggunaan pydantic
dengan python, dan kemampuannya untuk mengurai dan memvalidasi data json menjadi objek.
jsonobject
Saya harus menggunakan API dari PHP, dan API itu mengembalikan saya jsonobject s. Jadi saya perlu menguraikannya menjadi objek PHP yang bisa saya gunakan di aplikasi.
Alur kerjanya adalah
jsonobject
untuk mengurai definisi JSONMari kita ambil contoh JSON berikut:
{
"id" : 0 ,
"name" : " John Doe " ,
"age" : 42 ,
"emails" : [
" [email protected] " ,
" [email protected] "
],
"address" : {
"street" : " My street " ,
"number" : 42 ,
"city" : " My city " ,
"country" : " My country "
}
}
Dengan menggunakan jsonobject
, saya akan dapat mendefinisikan model data saya menggunakan kelas-kelas berikut:
class User extends jsonobject {
const ATTRIBUTES = [
' id ' => ' int ' ,
' name ' => ' str ' ,
' age ' => ' int ' ,
' emails ' => ' list[str] ' ,
' address? ' => ' Address ' ,
];
}
class Address extends jsonobject {
const ATTRIBUTES = [
' street ' => ' str ' ,
' number ' => ' int ' ,
' city ' => ' str ' ,
' country ' => ' str ' ,
];
}
Dan kemudian tambahkan perintah berikut:
$ user = User:: fromObject ( json_decode ( $ json_text_definition ));
Kelas jsonobject
akan melakukan penguraian konten menjadi objek, dan kita akan dapat menggunakan atributnya seperti yang didefinisikan:
echo ( $ user -> name );
Kelas yang ditentukan juga dapat memiliki metode yang akan memudahkan penerapan model data aplikasi. Misalnya, dimungkinkan untuk mendefinisikan kelas User
seperti ini:
class User extends jsonobject {
const ATTRIBUTES = [
' id ' => ' int ' ,
' name ' => ' str ' ,
' age ' => ' int ' ,
' emails ' => ' list[str] ' ,
' address? ' => ' Address ' ,
];
public function isAdult () {
return $ this -> age >= 18 ;
}
}
jsonobject
Ide dari kelas jsonobject
adalah menggunakannya untuk mengurai data json menjadi objek. Sehingga objek tersebut mungkin berisi metode lain yang akan membantu mengimplementasikan model data aplikasi.
Saat objek json (atau larik) diurai, kontennya diurai secara rekursif sesuai dengan tipe yang ditentukan dalam konstanta ATTRIBUTES
. Jika data tidak valid, karena tidak mengandung nilai yang diharapkan, pengecualian akan diberikan.
Untuk menggunakan jsonobject kita harus membuat subkelas jsonobject
dan mendefinisikan konstanta ATTRIBUTES
untuk kelas tersebut sehingga ia mendefinisikan atribut yang diharapkan untuk objek di kelas tersebut, beserta tipe masing-masingnya.
Konstanta ATTRIBUTES
adalah array asosiatif yang kuncinya adalah nama setiap atribut , dan nilainya adalah tipe setiap atribut .
Jenis yang mungkin dapat berupa:
jsonobject
. Saat menentukan nama atribut, seseorang dapat menambahkan ?
di akhir nama untuk menunjukkan bahwa atribut tersebut opsional. Misalnya, address?
di bagian kasus penggunaan adalah opsional.
Setiap field dianggap wajib sehingga harus ada dalam objek (atau array) yang diurai. Selain itu, objek harus bertipe yang ditentukan (yaitu objek harus diurai dengan benar berdasarkan tipe tertentu).
Atribut apa pun yang bukan opsional dianggap bersifat wajib. Hal ini menjadi perhatian khusus dalam dua hal:
fromArray
atau fromObject
).jsonobject
Saat membuat objek dari struktur eksternal, jsonobject
akan menangani setiap bidang wajib. Dan jika salah satu dari mereka hilang, pengecualian akan muncul.
Pada contoh berikutnya, pengecualian akan muncul karena usia bidang wajib tidak disediakan.
class User extends jsonobject {
const ATTRIBUTES = [
" name " => " str " ,
" age " => " int " ,
];
}
( . . . )
$ user = User:: fromArray ([ " name " => " John " ]);
Saat mengonversi objek menjadi array atau objek (atau mendapatkan representasi jsonnya), bidang wajib akan mendapatkan nilai default, meskipun tidak disetel.
Jadi pada contoh berikutnya
class User extends jsonobject {
const ATTRIBUTES = [
" name " => " str " ,
" age " => " int " ,
" birthDate? " => " str "
];
}
$ user = new User ();
echo (( string ) $ user );
Outputnya akan menjadi
{
"name" : " " ,
"age" : 0
}
Karena meskipun atribut name dan age bersifat wajib dan mendapatkan nilai defaultnya (yaitu 0 untuk angka, kosong untuk string, daftar, atau dikt), atribut tanggal lahir tidak wajib dan belum disetel. Jadi itu tidak dihasilkan dalam output.
null
pada atribut wajibMasalah pengaturan nilai ke null mempunyai relevansi khusus ketika mempertimbangkan apakah suatu atribut bersifat opsional atau tidak.
Orang mungkin berpikir bahwa, jika kita menetapkan nilai ke null, hal itu berarti menghapus nilai tersebut sehingga hanya dapat dilakukan untuk nilai opsional tetapi tidak untuk nilai wajib.
Di jsonobject
kita memiliki konsep yang berbeda, karena menyetel properti ke null berarti "menetapkan nilai ke null " dan tidak membatalkan setelan properti. Untuk membatalkan penyetelan properti, kita harus menggunakan fungsi yang tidak disetel atau semacamnya.
jsonobject
juga memungkinkan untuk menghapus nilai. Untuk atribut opsional, ini berarti menghilangkan nilai sehingga tidak akan memiliki nilai apa pun dalam representasi array atau objek (jika mengambil nilainya, nilainya akan disetel ke null ).
Namun untuk atribut wajib, menghapus setelannya berarti menyetel ulang nilainya ke default . Itu berarti bahwa ini akan diinisialisasi ke nilai default dari tipe tersebut (yaitu 0 untuk angka, kosong untuk daftar, string atau dicts, dll.) atau nilai defaultnya dalam konstanta ATTRIBUTES
.
jsonobject
juga dapat mewarisi atribut dari kelas induknya. Ambil contoh berikut:
class Vehicle extends jsonobject {
const ATTRIBUTES = [
" brand " => " str " ,
" color " => " str "
]
}
class Car extends Vehicle {
const ATTRIBUTES = [
" wheels " => " int "
]
}
class Boat extends Vehicle {
const ATTRIBUTES = [
" length " => " float "
]
}
Dalam contoh ini, kelas Vehicle
hanya akan memiliki atribut brand dan color , tetapi kelas Car
akan memiliki atribut brand , color dan wheel , sedangkan kelas Boat
akan memiliki atribut brand , color dan length .
Objek dari kelas turunan jsonobject
dapat dibuat menggunakan metode statis ::fromArray
atau ::fromObject
, dimulai dari objek yang diurai json .
Pada contoh sebelumnya, jika kita memiliki file car.json dengan isi sebagai berikut:
{
"brand" : " BMW " ,
"color" : " black "
}
Kita dapat menggunakan kode berikut untuk mendapatkan instance dari kelas Vehicle
:
$ json = file_get_contents ( " car.json " );
$ vehicle = Vehicle:: fromArray (( array ) json_decode ( $ json , true ));
Alternatifnya adalah dengan membuat instance objek seperti pada contoh berikutnya
* PHP 8 ke atas:
$ car = new Car (brand: " BMW " , color: " black " , wheels: 4 );
* Versi PHP sebelumnya:
$ car = new Car ([ " brand " => " BMW " , " color " => " black " , " wheels " => 4 ]);
jsonobject
jsonobject
adalah kelas inti untuk perpustakaan ini. Metodenya adalah:
__construct($data)
- Membuat objek baru dari data yang diberikan__get($name)
- Mengembalikan nilai atribut dengan nama yang diberikan__set($name, $value)
- Menetapkan nilai atribut dengan nama tertentu__isset($name)
- Mengembalikan nilai true jika atribut dengan nama tertentu disetel__unset($name)
- Membatalkan nilai atribut opsional (atau mengatur ulang nilai atribut wajib).toArray()
- Mengembalikan array asosiatif dengan data objek. Array dibuat secara rekursif, mengunjungi setiap sub-atribut untuk setiap atribut.toObject()
- Mengembalikan objek dengan data objek sebagai atribut. Array dibuat secara rekursif, mengunjungi setiap sub-atribut untuk setiap atribut.toJson()
- Mengembalikan string json dengan representasi objek sebagai objek standar.::fromArray($data)
- Membuat objek, dengan mengurai array asosiatif yang diberikan ke dalam atribut yang ditentukan di kelas. Masing-masing atribut diurai secara rekursif, sesuai dengan tipe yang ditentukan padanya.::fromObject($data)
- Membuat objek, dengan menguraikan objek tertentu ke dalam atribut yang ditentukan di kelas. Masing-masing atribut diurai secara rekursif, sesuai dengan tipe yang ditentukan padanya. JsonDict
Objek ini digunakan untuk menangani kamus yang berasal dari definisi json. Kelas JsonDict
diketik sehingga setiap elemen harus berasal dari tipe tertentu.
Objek JsonDict
dapat digunakan sebagai objek seperti array (misalnya $jsonDict["key1"]) tetapi (pada saat penulisan teks ini) jenis elemen yang dimasukkan ke dalam kamus tidak dicentang. Tipe ini digunakan untuk mengurai konten saat membuat dict (misalnya menggunakan fungsi statis fromArray
) atau untuk membuang konten ke array atau objek (misalnya menggunakan fungsi toArray
).
Metodenya adalah:
toArray()
toObject()
::fromArray($data)
::fromObject($data)
Metode ini ditafsirkan dengan cara yang sama seperti dalam kasus jsonobject
. Dan tipe elemen dalam dict mungkin merujuk pada tipe kompleks yang akan dipertimbangkan secara rekursif saat menguraikan konten.
misal ketik list[list[int]]
akan digunakan untuk mengurai [ [ 1, 2, 3], [ 4, 5, 6 ]]
JsonArray
Objek ini sangat mirip dengan JsonDict
dengan pengecualian bahwa indeksnya harus berupa bilangan bulat. Dalam hal ini $value["key1"]
akan menghasilkan pengecualian.
Dalam hal ini, fungsi untuk menambahkan elemen ke array (yaitu []
) juga diimplementasikan.
Saat mendefinisikan kelas, dimungkinkan untuk menginisialisasi nilai untuk objek yang baru dibuat, dan untuk atribut-atribut yang bersifat opsional.
Ada dua cara:
### Menggunakan properti kelas
Nilai suatu objek dapat diinisialisasi dengan menggunakan properti kelas, jadi jika nilai atribut ditetapkan di kelas, nilai tersebut akan disalin ke instance sebagai atribut, jika nilai tersebut ditentukan.
Misalnya
class User extends jsonobject {
const ATTRIBUTES = [
' id ' => ' int ' ,
' name ' => ' str ' ,
' age ' => ' int ' ,
' emails ' => ' list[str] ' ,
' address? ' => ' Address ' ,
' sex? ' => ' str '
];
public $ sex = " not revealed " ;
}
Sekarang, atribut sex
diinisialisasi menjadi tidak terungkap alih-alih menjadi null .
Cara membuatnya adalah dengan mendefinisikan tuple [ <type>, <default value> ]
untuk tipe objeknya. Mengambil contoh berikutnya:
class User extends jsonobject {
const ATTRIBUTES = [
' id ' => ' int ' ,
' name ' => ' str ' ,
' age ' => ' int ' ,
' emails ' => ' list[str] ' ,
' address? ' => ' Address ' ,
' sex? ' => [ ' str ' , ' not revealed ' ]
];
}
Atribut sex
bersifat opsional saat mengambil data pengguna. Dengan menggunakan definisi baru untuk kelas ini, jika sex
tidak disetel, nilainya akan disetel ke "tidak terungkap" dan bukannya null
.
Fitur penting adalah, jika string yang disetel sebagai <nilai default> sesuai dengan metode objek, maka string tersebut akan dipanggil setelah mendapatkan nilai (jika belum disetel), dan nilai yang disetel untuk properti tersebut akan menjadi akibat dari panggilan itu.
Misalnya
class User extends jsonobject {
const ATTRIBUTE = [
...
' birthDay? ' => [ ' str ' , ' computeBirthDate ' ]
]
function computeBirthDate () {
$ now = new DateTime ();
$ now ->sub( DateInterval ::createFromDateString("{ $ this -> age } years"));
return $ now ->format("Y-m-d");
}
}
Dalam contoh ini, jika kita belum menyetel properti birthDate
tetapi properti tersebut diambil, properti tersebut akan dihitung dengan mengurangkan usia ke tanggal saat ini.
Jika ingin mengurai objek arbitrer menjadi jsonobject
, dimungkinkan untuk menggunakan fungsi jsonobject ::parse_typed_value
. Ini penting untuk dapat mengonversi dari tipe apa pun ke tipe jsonobject
.
misalnya
$ myobject = jsonobject :: parse_typed_value ( " list[str] " , [ " my " , " name " , " is " , " John " ]);
Akan mendapatkan objek bertipe JsonList<str>
.
Perilaku default pustaka ini adalah memastikan bahwa nilai yang ditetapkan untuk atribut sesuai dengan tipe yang ditentukan. Namun itu berarti, karena float
bukan int
, menyetel float ke 0
akan gagal karena 0
adalah bilangan bulat. Dalam hal ini, pengguna harus memberikan nilai sebelum menetapkannya. Untuk mengontrol apakah akan memeriksa jenisnya dengan ketat atau tidak, Anda dapat menggunakan konstanta STRICT_TYPE_CHECKING
.
Jika
STRICT_TYPE_CHECKING
disetel keTrue
, jenisnya akan diperiksa secara ketat dan misalnya menugaskan9.3
keint
akan memunculkan pengecualian. Jika disetel keFalse
, tipe numerik akan dikonversi satu sama lain. Jadi misalnya jika kita menetapkan9.3
keint
maka secara otomatis akan terpotong menjadi9
.
Pemeriksaan tipe penting lainnya adalah ketika menetapkan nilai kosong (yaitu ""
atau null
) ke tipe numerik. Dalam hal ini, kita memiliki konstanta STRICT_TYPE_CHECKING_EMPTY_ZERO
.
Jika
STRICT_TYPE_CHECKING_EMPTY_ZERO
diatur keTrue
(perilaku default), saat menetapkan nilai kosong ke tipe numerik, itu akan dianggap0
. yaitu menetapkan string kosong atau nilainull
ke atributint
, berarti menetapkan0
. Jika disetel keFalse
, perpustakaan akan memeriksa jenisnya dan pada akhirnya akan memunculkan pengecualian.
Sekarang JsonList
juga memungkinkan untuk menggunakan indeks negatif, sehingga -1
akan menjadi elemen terakhir, -2
kedua dari belakang, dll.
Objek JsonList
menyertakan fungsi untuk menyortir atau memfilter.
public function sort(callable $callback = null) : JsonList
: mengurutkan daftar menggunakan callback yang diberikan. Jika tidak ada panggilan balik yang diberikan, daftar akan diurutkan menggunakan fungsi perbandingan default.public function filter(callable $callback) : JsonList
: memfilter daftar menggunakan callback yang diberikan. Callback harus mengembalikan nilai boolean. Jika panggilan balik mengembalikan true
, elemen tersebut akan disertakan dalam daftar yang dihasilkan. Jika mengembalikan false
, elemen tersebut akan dibuang.