นำข้อมูลที่ดึงมาจากบริการเว็บ JSON มาแปลงเป็นออบเจ็กต์และอาร์เรย์ที่ซ้อนกัน โดยใช้คลาสโมเดลของคุณเอง
เริ่มต้นจากออบเจ็กต์ฐาน โดยจะจับคู่ข้อมูล JSON กับคุณสมบัติของคลาส และแปลงให้เป็นประเภทหรืออ็อบเจ็กต์แบบง่ายที่ถูกต้อง
มันเหมือนกับพารามิเตอร์ SOAP ดั้งเดิมที่แมป SoapClient
ของ PHP ให้คุณ แต่สำหรับ JSON มันไม่ได้ขึ้นอยู่กับสคีมาใดๆ มีเพียงคำจำกัดความคลาส PHP ของคุณเท่านั้น
การตรวจหาประเภททำงานโดยการแยกวิเคราะห์การประกาศประเภทและคำอธิบายประกอบ @var
docblock ของคุณสมบัติคลาส เช่นเดียวกับคำแนะนำประเภทในวิธี setter
คุณไม่จำเป็นต้องแก้ไขคลาสโมเดลของคุณโดยเพิ่มโค้ดเฉพาะ JSON มันทำงานโดยอัตโนมัติโดยแยกวิเคราะห์ docblock ที่มีอยู่แล้ว
ไลบรารีนี้ไม่มีการขึ้นต่อกัน
คำสำคัญ: การดีซีเรียลไลเซชัน การให้น้ำ
สารบัญ
map()
คลาสโมเดลจะต้องเขียนด้วยมือ
เนื่องจาก JsonMapper ไม่ต้องอาศัยข้อมูลสคีมาใดๆ (เช่นจาก json-schema) จึงไม่สามารถสร้างคลาสโมเดลได้โดยอัตโนมัติ
netresearch/jsonmapper
พร้อมผู้แต่งJsonMapper
map
หรือ mapArray
ขึ้นอยู่กับข้อมูลของคุณแมปวัตถุปกติ:
<?php
require ' autoload.php ' ;
$ mapper = new JsonMapper ();
$ contactObject = $ mapper -> map ( $ jsonContact , new Contact ());
// or as classname
$ contactObject = $ mapper -> map ( $ jsonContact , Contact::class);
แมปอาร์เรย์ของวัตถุ:
<?php
require ' autoload.php ' ;
$ mapper = new JsonMapper ();
$ contactsArray = $ mapper -> mapArray (
$ jsonContacts , array (), ' Contact '
);
แทนที่จะใช้ array()
คุณอาจใช้ ArrayObject
และคลาสที่ได้รับ เช่นเดียวกับคลาสที่ใช้ ArrayAccess
JSON จากบริการเว็บสมุดที่อยู่:
{
"name" : "Sheldon Cooper" ,
"address" : {
"street" : "2311 N. Los Robles Avenue" ,
"city" : "Pasadena"
}
}
คลาส Contact
ในพื้นที่ของคุณ:
<?php
class Contact
{
/**
* Full name
*/
public string $ name ;
public ? Address $ address ;
}
คลาส Address
อยู่ในพื้นที่ของคุณ:
<?php
class Address
{
public $ street ;
public $ city ;
public function getGeoCoords ()
{
//do something with $street and $city
}
}
รหัสใบสมัครของคุณ:
<?php
$ json = json_decode ( file_get_contents ( ' http://example.org/sheldon.json ' ));
$ mapper = new JsonMapper ();
$ contact = $ mapper -> map ( $ json , new Contact ());
echo " Geo coordinates for " . $ contact -> name . " : "
. var_export ( $ contact -> address -> getGeoCoords (), true );
JsonMapper
ใช้แหล่งที่มาหลายแห่งเพื่อตรวจหาประเภทที่ถูกต้องของคุณสมบัติตามลำดับต่อไปนี้:
วิธีการตั้งค่า ( set
+ ucwords($propertyname)
)
ขีดล่าง " _
" และขีดกลาง " -
" ทำให้ตัวอักษรตัวถัดไปเป็นตัวพิมพ์ใหญ่ คุณสมบัติ foo_bar-baz
นำไปสู่เมธอด setter setFooBarBaz
หากมีคำใบ้ประเภทในลายเซ็นวิธีการ แสดงว่าประเภทที่ใช้:
ฟังก์ชั่นสาธารณะ setPerson (ติดต่อ $ บุคคล) {... }
docblock ของวิธีการได้รับการตรวจสอบสำหรับคำอธิบายประกอบ @param $type
:
- * @param ติดต่อ $person ผู้ติดต่อหลักสำหรับแอปพลิเคชันนี้ - ฟังก์ชั่นสาธารณะ setPerson($ คน) {...}
หากตรวจไม่พบประเภทใด ค่า JSON ธรรมดาจะถูกส่งผ่านไปยังเมธอดตัวตั้งค่า
ประเภทคุณสมบัติของคลาส (ตั้งแต่ PHP 7.4):
ติดต่อสาธารณะ $person;
ประเภทการส่งเสริมคุณสมบัติตัวสร้าง (ตั้งแต่ PHP 8.0):
ฟังก์ชั่นสาธารณะ __ สร้าง (ผู้ติดต่อที่ได้รับการป้องกัน $ บุคคล) {}
@var $type
คำอธิบายประกอบ docblock ของคุณสมบัติคลาส:
- * @var myapplicationmodelContact - $บุคคลสาธารณะ;
ที่พักจะต้องเป็นสาธารณะจึงจะสามารถใช้งานได้โดยตรง คุณยังสามารถใช้ $bIgnoreVisibility เพื่อใช้คุณสมบัติที่ได้รับการคุ้มครองและเป็นส่วนตัวได้
หากตรวจไม่พบประเภท คุณสมบัติจะได้รับชุดค่า JSON ธรรมดา
หากไม่พบคุณสมบัติ JsonMapper จะพยายามค้นหาคุณสมบัติในลักษณะที่ไม่คำนึงถึงขนาดตัวพิมพ์ คุณสมบัติ JSON isempty
จะถูกแมปกับคุณสมบัติ PHP isEmpty
บันทึก
คุณต้องระบุเนมสเปซแบบเต็มเพื่อให้ประเภทใช้งานได้ ชื่อคลาสสัมพัทธ์ได้รับการประเมินในบริบทของเนมสเปซคลาสปัจจุบัน โดยไม่คำนึงถึงการนำเข้าใด ๆ ที่อาจมีอยู่
PHP ไม่ได้จัดเตรียมการนำเข้าผ่าน Reflection; ข้อความความคิดเห็นจะมีเฉพาะข้อความตามตัวอักษรของประเภทเท่านั้น ด้วยเหตุผลด้านประสิทธิภาพ JsonMapper จะไม่แยกวิเคราะห์ซอร์สโค้ดด้วยตัวเองเพื่อตรวจจับและขยายการนำเข้าใดๆ
ประเภทเรียบง่าย
string
bool
, boolean
int
integer
double
float
array
object
mixed
ชื่อคลาส มีและไม่มีเนมสเปซ
Contact
- ข้อยกเว้นจะถูกส่งออกไปหากค่า JSON เป็น null
อาร์เรย์ของประเภทและชื่อคลาสอย่างง่าย:
int[]
Contact[]
อาร์เรย์หลายมิติ:
int[][]
TreeDeePixel[][][]
ArrayObjects ประเภทธรรมดาและชื่อคลาส:
ContactList[Contact]
NumberList[int]
enums ที่ได้รับการสนับสนุน โดยมีและไม่มีเนมสเปซ
Suit:string|Suit:int
- ข้อยกเว้นจะถูกส่งออกไปหากไม่มีค่า JSON อยู่ในแจงนับ
ประเภทที่เป็นโมฆะ:
int|null
หรือ ?int
- จะเป็น null
หากค่าใน JSON เป็น null
มิฉะนั้นจะเป็นจำนวนเต็มContact|null
หรือ ?Contact
- จะเป็น null
หากค่าใน JSON เป็น null
มิฉะนั้นจะเป็นวัตถุประเภท Contact
ArrayObjects และคลาสที่ขยายจะถือเป็นอาร์เรย์
ตัวแปรที่ไม่มีประเภทหรือประเภท mixed
จะได้รับการตั้งค่า JSON โดยตรงโดยไม่มีการแปลงใดๆ
ดูเอกสารประเภท phpdoc สำหรับข้อมูลเพิ่มเติม
บันทึก
คุณลักษณะนี้ถูกปิดใช้งานตามค่าเริ่มต้นด้วยเหตุผลด้านความปลอดภัยตั้งแต่เวอร์ชัน 5 โปรดดูรายละเอียดที่ $bStrictObjectTypeChecking
เมื่อวัตถุจะถูกสร้างขึ้น แต่ JSON มีประเภทธรรมดาเท่านั้น (เช่น string, float, boolean) ค่านี้จะถูกส่งผ่านไปยังตัวสร้างคลาส ตัวอย่าง:
รหัส PHP:
public DateTime $ date ;
เจสัน:
{ "date" : "2014-05-15" }
ซึ่งจะส่งผลให้มีการเรียก new DateTime('2014-05-15')
เมื่อตัวแปรถูกกำหนดให้เป็นอ็อบเจ็กต์ของคลาสนามธรรมหรืออินเทอร์เฟซ ปกติแล้ว JsonMapper จะพยายามสร้างอินสแตนซ์เหล่านั้นโดยตรงและหยุดทำงาน
การใช้คุณสมบัติ $classMap
ของ JsonMapper คุณสามารถระบุคลาสที่จะได้รับอินสแตนซ์แทน:
$ jm = new JsonMapper ();
$ jm -> classMap [ ' Foo ' ] = ' Bar ' ;
$ jm -> map (...);
สิ่งนี้จะสร้างวัตถุประเภท Bar
เมื่อตัวแปรถูกกำหนดให้เป็นประเภท Foo
นอกจากนี้ยังเป็นไปได้ที่จะใช้ callable ในกรณีที่จำเป็นต้องกำหนดคลาสการใช้งานจริงแบบไดนามิก (เช่น ในกรณีของการรวม) คลาสที่แมป ('Foo' ในตัวอย่างด้านล่าง) และข้อมูล Json จะถูกส่งผ่านเป็นพารามิเตอร์ในการเรียก
$ mapper = function ( $ class , $ jvalue ) {
// examine $class and $jvalue to figure out what class to use...
return ' DateTime ' ;
};
$ jm = new JsonMapper ();
$ jm -> classMap [ ' Foo ' ] = $ mapper ;
$ jm -> map (...);
JsonMapper ส่งข้อยกเว้นเมื่อคุณสมบัติ JSON เป็น null
เว้นแต่ว่าคุณสมบัติคลาส PHP มีประเภทที่เป็นโมฆะ เช่น Contact|null
หรือ ?Contact
หาก API ของคุณมีหลายฟิลด์ที่อาจเป็น null
และคุณไม่ต้องการทำให้คำจำกัดความประเภททั้งหมดของคุณเป็นโมฆะ ให้ตั้งค่า:
$ jm -> bStrictNullTypes = false ;
ตั้งแต่เวอร์ชัน 5.0.0 ค่า null
ในอาร์เรย์จะนำไปสู่ JsonMapper_Exception
เว้นแต่ว่าประเภทจะเป็นโมฆะได้ - เช่น array[?string]
หรือ array[string|null]
หากต้องการรับพฤติกรรมก่อนหน้านี้กลับคืนมา (อนุญาตให้มีค่าว่างแม้ว่าจะไม่ได้ประกาศก็ตาม) ให้ตั้งค่า:
$ jm -> bStrictNullTypesInArrays = false ;
เมธอด setLogger()
ของ JsonMapper รองรับอินสแตนซ์ตัวบันทึกที่เข้ากันได้กับ PSR-3 ทั้งหมด
เหตุการณ์ที่ได้รับการบันทึก:
ในระหว่างการพัฒนา API มักจะมีการเปลี่ยนแปลง หากต้องการรับการแจ้งเตือนเกี่ยวกับการเปลี่ยนแปลงดังกล่าว คุณสามารถกำหนดค่า JsonMapper ให้ส่งข้อยกเว้นในกรณีที่ข้อมูลสูญหายหรือยังไม่ทราบข้อมูล
เมื่อ JsonMapper เห็นคุณสมบัติในข้อมูล JSON ที่ไม่ได้กำหนดไว้ในคลาส PHP คุณสามารถปล่อยให้มีข้อยกเว้นโดยการตั้งค่า $bExceptionOnUndefinedProperty
:
$ jm = new JsonMapper ();
$ jm -> bExceptionOnUndefinedProperty = true ;
$ jm -> map (...);
คุณอาจเลือกที่จะจัดการคุณสมบัติเหล่านั้นด้วยตัวเองโดยตั้งค่า callable เป็น $undefinedPropertyHandler
:
/**
* Handle undefined properties during JsonMapper::map()
*
* @param object $object Object that is being filled
* @param string $propName Name of the unknown JSON property
* @param mixed $jsonValue JSON value of the property
*
* @return void
*/
function setUndefinedProperty ( $ object , $ propName , $ jsonValue )
{
$ object ->{ ' UNDEF ' . $ propName } = $ jsonValue ;
}
$ jm = new JsonMapper ();
$ jm -> undefinedPropertyHandler = ' setUndefinedProperty ' ;
$ jm -> map (...);
หรือหากคุณจะให้ JsonMapper จัดการ setter ให้กับคุณ คุณสามารถส่งคืนสตริงจาก $undefinedPropertyHandler
ซึ่งจะใช้เป็นชื่อคุณสมบัติ
/**
* Handle undefined properties during JsonMapper::map()
*
* @param object $object Object that is being filled
* @param string $propName Name of the unknown JSON property
* @param mixed $jsonValue JSON value of the property
*
* @return void
*/
function fixPropName ( $ object , $ propName , $ jsonValue )
{
return ucfirst ( $ propName );
}
$ jm = new JsonMapper ();
$ jm -> undefinedPropertyHandler = ' fixPropName ' ;
$ jm -> map (...);
บันทึก
ใช้งานได้เฉพาะเมื่อ $bStrictObjectTypeChecking ยังคงเปิดใช้งานอยู่
คุณสมบัติในคลาส PHP ของคุณสามารถทำเครื่องหมายเป็น "จำเป็น" ได้โดยการใส่ @required
ใน docblock:
/**
* @var string
* @required
*/
public $ someDatum ;
เมื่อข้อมูล JSON ไม่มีคุณสมบัตินี้ JsonMapper จะส่ง JsonMapper_Exception
เมื่อ $bExceptionOnMissingData
ถูกเปิดใช้งาน:
$ jm = new JsonMapper ();
$ jm -> bExceptionOnMissingData = true ;
$ jm -> map (...);
ตัวเลือก $bRemoveUndefinedAttributes
ทำให้ JsonMapper ลบคุณสมบัติออกจากออบเจ็กต์สุดท้ายหากไม่ได้อยู่ในข้อมูล JSON:
$ jm = new JsonMapper ();
$ jm -> bRemoveUndefinedAttributes = true ;
$ jm -> map (...);
คุณสามารถอนุญาตการแมปไปยังคุณสมบัติส่วนตัวและที่ได้รับการป้องกันและวิธีการตั้งค่าโดยการตั้งค่า $bIgnoreVisibility
เป็นจริง:
$ jm = new JsonMapper ();
$ jm -> bIgnoreVisibility = true ;
$ jm -> map (...);
เมื่อประเภทของตัวแปรเป็นคลาสและข้อมูล JSON เป็นประเภทธรรมดาเช่น string
JsonMapper สามารถส่งค่านี้ไปยังตัวสร้างคลาสได้เมื่อกำหนดค่าให้ทำดังนี้:
$ jm = new JsonMapper ();
$ jm -> bStrictObjectTypeChecking = false ;
$ jm -> map (...);
ซึ่งสามารถใช้เพื่อเริ่มต้นวัตถุ DateTime โดยอัตโนมัติจากสตริงวันที่
การปิดใช้งานการตรวจสอบประเภทออบเจ็กต์ที่เข้มงวดนี้อาจนำไปสู่ปัญหาได้ แต่:
@required
คุณสมบัติที่จำเป็นจะไม่ถูกกรอกบันทึก
ค่าเริ่มต้นเปลี่ยนจาก false
เป็น true
ในเวอร์ชัน 5 เพื่อเพิ่มความปลอดภัย
ตอนนี้คุณต้องเลือกถ้าคุณต้องการส่งประเภทง่าย ๆ ไปยังตัวสร้างคลาส
map()
คุณอาจต้องการส่งข้อมูลอาร์เรย์ไปยัง map()
ที่คุณได้รับจากการโทร
json_decode ( $ jsonString , true )
ตามค่าเริ่มต้น JsonMapper จะส่งข้อยกเว้นเนื่องจาก map()
กำหนดให้วัตถุเป็นพารามิเตอร์แรก คุณสามารถหลีกเลี่ยงสิ่งนั้นได้โดยการตั้งค่า $bEnforceMapType
เป็น false
:
$ jm = new JsonMapper ();
$ jm -> bEnforceMapType = false ;
$ jm -> map (...);
JsonMapper สามารถเรียกวิธีการที่กำหนดเองได้โดยตรงบนแต่ละวัตถุหลังจากการแมปเสร็จสิ้น:
$ jm = new JsonMapper ();
$ jm -> postMappingMethod = ' afterMapping ' ;
$ jm -> map (...);
ตอนนี้มีการเรียกใช้ afterMapping()
บนวัตถุที่แมปแต่ละรายการ (หากคลาสมีเมธอดนั้น)
คุณอาจส่งข้อโต้แย้งเพิ่มเติมไปยังการโทรกลับหลังการแมป:
$ jm = new JsonMapper ();
$ jm -> postMappingMethod = ' afterMapping ' ;
$ jm -> postMappingMethodArguments = [ 23 , ' foo ' ];
$ jm -> map (...);
ผ่านทางผู้แต่งจาก Packagist:
$ ผู้แต่งต้องการ netresearch/jsonmapper
ทางเลือก
JsonMapper ได้รับอนุญาตภายใต้ OSL 3.0
JsonMapper เป็นไปตามมาตรฐานการเข้ารหัส PEAR
คริสเตียน ไวส์เก้, cweiske.de