dataclass ช่วยให้คุณเปลี่ยน array ธรรมดาของคุณเป็นคลาส PHP ที่ระบุประเภทได้อย่างรวดเร็วด้วยการลดนอร์มัลไลซ์อัตโนมัติของอ็อบเจ็กต์และคอลเลกชันที่ฝังไว้ ซึ่งโดยปกติจะต้องใช้งานมากหากคุณใช้นอร์มัลไลเซอร์และดีนอร์มัลไลเซอร์ Library ได้รับแรงบันดาลใจจากโมดูล Python pydantic มันใช้พลังการพิมพ์คำใบ้ที่มีตั้งแต่ PHP 7.4
เป้าหมายหลักของแพ็คเกจนี้คือเพื่อให้มีวิธีที่รวดเร็วในการมีคลาสที่เน้นประเภทอย่างเคร่งครัดสำหรับการใช้งานต่อไป เช่น การแมปเพย์โหลดของคำขอกับคลาสที่พิมพ์อย่างเคร่งครัด เพื่อให้คุณสามารถใช้แทนอาร์เรย์ซึ่งอาจตรงกับความต้องการของคุณหรือไม่ก็ได้ จะไม่แทนที่การตรวจสอบข้อมูลของคุณ แต่จะทำให้คุณแน่ใจว่า fx ที่ได้รับเพย์โหลด JSON ตรงกับประเภทที่การดำเนินงานแบ็กเอนด์ของคุณคาดว่าจะได้รับ เป็นสิ่งที่เหมือนกับที่กล่าวไว้ข้างต้น pydantic BaseModel หรืออินเทอร์เฟซ TypeScript
สิ่งที่คุณต้องมีคือสร้างคลาสหรือสองคลาส:
declare (strict_types= 1 );
class MyEmbededClass
{
public float $ number ;
}
class MyClass
{
public int $ number ;
public ? string $ optionalText = null ;
public MyEmbededClass $ embeded ;
} เมื่อขั้นตอนถัดไปส่งผ่านชื่อคลาสหลักและข้อมูลที่ได้รับ เช่น จาก JSON ที่ได้รับไปจนถึงวิธี transform :
$ data = ' {
"number": 1,
"embeded": {
"number": 1.23
}
} ' ;
$ object = transform (MyClass::class, json_decode ( $ data , true ));หากต้องการแมปข้อมูลที่ได้รับกับ dataclass ที่ทำงานได้อย่างสมบูรณ์อย่างรวดเร็ว:
var_dump ( $ object ) object (MyClass) {
[ " number " ]=> int( 1 )
[ " optionalText " ]=> NULL
[ " embeded " ]=>
object(MyEmbededClass) {
[ " number " ]=>
float( 1.23 )
}
} คุณไม่ต้องกังวลกับการส่งค่า null จาก json_decode มันจะส่ง TransformException สำหรับฟิลด์ root หากตรวจพบ
คุณไม่ต้องกังวลเกี่ยวกับฟิลด์ที่หายไปและประเภทที่ไม่ถูกต้อง เนื่องจากไลบรารีตรวจพบข้อกำหนดที่ระบุประเภททั้งหมด และส่ง TransformException พร้อมข้อผิดพลาด (พร้อมที่จะทำหน้าที่เป็นการตอบสนอง) ชี้ไปยังฟิลด์ที่ตรงกันทุกประการพร้อมข้อความเหตุผลง่ายๆ ตัวอย่างเช่น:
echo json_encode ( $ transformException , JSON_PRETTY_PRINT ){
"errors" : [
{
"field" : " optionalText " ,
"reason" : " Field must have value "
},
{
"field" : " embeded " ,
"reason" : " Field must have value "
}
]
} คุณยังสามารถใช้ Transform::to ซึ่งจริงๆ แล้วเรียกว่าโดยฟังก์ชันตัวช่วย transform ฟังก์ชั่นตัวช่วยจะใช้การตั้งค่าที่เหมาะสมที่สุดสำหรับวัตถุ Transform (ทันทีที่ปรากฏ)
$ data = ' {
"number": 1,
"embeded": {
"number": 1.23
}
} ' ;
$ transformer = new Transform ();
$ object = $ transformer -> to (MyClass::class, json_decode ( $ data , true ));หากคุณต้องการใช้ Constructor พร้อมอาร์กิวเมนต์ที่บอกเป็นนัย คุณสามารถทำได้ แต่มีวิธีที่จำกัด ไลบรารีรองรับการกรอกอาร์กิวเมนต์ตัวสร้างด้วยค่าจากเพย์โหลดเท่านั้น หมายความว่าตัวสร้างต้องใช้ประเภทและชื่อตัวแปรเดียวกันกับคุณสมบัติของคลาส ตัวอย่างเช่น:
class MyClass
{
public float $ number ;
public ? int $ numberTwo = null ;
public function __construct ( float $ number )
{
$ this -> number = $ number ;
}
}การใช้ชื่อหรือประเภทอื่นสำหรับอาร์กิวเมนต์ตัวสร้างจะไม่ทำงาน เป้าหมายคือการสนับสนุนการบังคับให้นักพัฒนากรอกคุณสมบัติ
ตัวสร้างใด ๆ ที่มีพารามิเตอร์อื่นนอกเหนือจากคุณสมบัติจะโยน UnsupportedException พารามิเตอร์ต้องมีประเภทเดียวกันกับคุณสมบัติ คำสั่งซื้อไม่เกี่ยวข้อง หากจำเป็น จะมีเพียงคุณสมบัติย่อยบางส่วนเท่านั้นที่สามารถมีอยู่ใน Constructor
โปรดดูตัวอย่างเพิ่มเติมที่ docs/ directory
เรียบง่ายเหมือน
composer install rutek/ dataclass
ข้อควรสนใจ: โปรดระวังการใช้คำแนะนำประเภท array ไม่สามารถใช้งานได้ (จะส่ง UnsupportedException หากตรวจพบ) เนื่องจาก PHP ไม่มีวิธีพิมพ์รายการคำแนะนำของอาร์เรย์ โปรดตรวจสอบส่วน คอลเลกชัน ด้านล่างสำหรับข้อมูลเพิ่มเติม
รองรับสเกลาร์ PHP ทั้งสี่ตัว
รองรับการพิมพ์แบบ nullability คุณสามารถใช้ตัวอย่าง ?string เพื่อยอมรับทั้ง string และ null ได้อย่างปลอดภัย โปรดทราบว่าการใช้เฉพาะ ?string $field ไม่ได้หมายความว่าอาร์เรย์ที่แปลงแล้วอาจไม่มีช่องนี้ หมายความว่าค่านี้ยอมรับ null เท่านั้น
หากคุณต้องการยอมรับการเปลี่ยนแปลงข้อมูลที่ไม่มีบางฟิลด์ คุณสามารถใช้ค่าเริ่มต้นได้ เช่น ?string $field = null ไลบรารี dataclass จะตรวจพบว่าคุณสมบัตินี้ไม่อยู่ในเพย์โหลด และจะใช้ค่าเริ่มต้นแทน
PHP ไม่รองรับฟิลด์ array บอกประเภทประเภท หากคุณต้องการฝังคอลเลกชั่นของอ็อบเจ็กต์หรือสเกลาร์ คุณต้องใช้คลาส Collection คุณต้องขยายมันด้วยคอนสตรัคเตอร์ที่มีการแยกโครงสร้างอาร์กิวเมนต์แบบบอกใบ้เช่น:
class Tags extends Collection
{
public function __construct ( string ... $ names )
{
$ this -> items = $ names ;
}
} อาร์เรย์ที่บอกเป็นนัยประเภทเช่น string[] ถูกปฏิเสธใน RFC ดังนั้นจึงเป็นไปได้ว่าพฤติกรรมนี้จะไม่เปลี่ยนแปลงในเร็วๆ นี้
ไลบรารีจะตรวจสอบว่าค่าที่ระบุตรงกับประเภทคำแนะนำของตัวสร้างหรือไม่
ไม่มีความเป็นไปได้ที่จะตรวจสอบรายการขั้นต่ำและสูงสุด แต่อาจมีคุณสมบัติดังกล่าวในเวอร์ชันถัดไป
โปรดทราบว่าคุณสามารถใช้ Collection เป็นคลาสพื้นฐานที่คุณต้องการแปลงได้ เช่น:
$ tags = transform (Tags::class, [ ' tag1 ' , ' tag2 ' ]);TransformException - ข้อมูลไม่ตรงกับสคีมาของคุณ นี่เป็นข้อยกเว้นพื้นฐานที่คุณคาดหวังได้ ทุกครั้งที่ข้อมูลของคุณ (เพย์โหลด) ส่งผ่านไปยังฟังก์ชัน transform(string $class, $data) หรือ Transform::to จะไม่ตรงกับคลาสที่ระบุประเภทของคุณ คุณจะได้รับ TransformException พร้อมเมธอด getErrors(): FieldError[] ซึ่งอธิบายสิ่งที่จริงๆ เกิดขึ้น.
ทุก FieldError มีทั้ง field ที่อธิบายว่าฟิลด์ใดที่ล้มเหลวในการตรวจสอบประเภท และ reason ที่อธิบายด้วยคำง่ายๆ ว่าเหตุใดจึงถูกปฏิเสธ หากมีวัตถุซ้อนกัน คุณสามารถคาดหวังว่าจะได้รับค่า field เช่น parentProperty.childrenProperty (ระดับที่คั่นด้วยจุด)
Class รองรับการทำให้เป็นอนุกรม JSON และจะส่งกลับสิ่งที่ชอบเสมอ:
{
"errors" : [
{
"field" : " optionalText " ,
"reason" : " Field must have value "
},
{
"field" : " embeded " ,
"reason" : " Field must have value "
}
]
} โปรดทราบว่าฟิลด์ code อาจถูกเพิ่มในอนาคต
UnsupportedException - เฉพาะในกรณีที่คำแนะนำประเภทของคุณไม่ได้รับการสนับสนุน ไลบรารีไม่ครอบคลุมทุกสถานการณ์เนื่องจากคุณสามารถกำหนดคำแนะนำประเภทที่จะไม่มีบริบทที่เข้มงวดได้ ตัวอย่างเช่น หากคุณใช้คุณสมบัติ object คุณจะไม่สามารถตรวจสอบได้เนื่องจากออบเจ็กต์ใดๆ จะตรงกับสคีมาของคุณ ในกรณีเช่นนี้ คุณสามารถคาดหวัง UnsupportedException ได้
ไม่รองรับประเภทการรวม PHP 8.0 และประเภทแยก PHP 8.1 ในขณะนี้
ยังไม่รองรับ Native PHP 8.1 enums ในขณะนี้
ฟิลด์คำแนะนำประเภททั้งหมดจะต้องเป็นแบบสาธารณะในขณะนี้ การใช้คุณลักษณะดังกล่าวเป็นเรื่องที่น่าสงสัย เนื่องจากคุณจะต้องสร้าง getters สำหรับคุณสมบัติดังกล่าวซึ่งเป็นค่าใช้จ่ายที่ไม่ต้องการ ไลบรารีมีจุดมุ่งหมายเพื่อสร้างความเป็นไปได้ในการกำหนดสคีมาภายในสำหรับข้อมูลที่ได้รับจากระบบระยะไกล (API, ข้อความคิว/บัส, เบราว์เซอร์)
การตรวจสอบการสะท้อนทั้งหมดจะเกิดขึ้นทุกครั้งที่มีการเรียกใช้ฟังก์ชัน transform Transform::to คุณสามารถคาดหวังฟังก์ชันแคชเพื่อประสิทธิภาพที่ดีขึ้นได้ในเร็วๆ นี้
โปรดจำไว้ว่าเป้าหมายของแพ็คเกจนี้ไม่ใช่เพื่อตรวจสอบความถูกต้องของข้อมูลที่คุณได้รับอย่างสมบูรณ์ แต่เพื่อสร้างคลาสง่ายๆ ซึ่งทำให้เพย์โหลดของคุณพิมพ์ได้อย่างสมบูรณ์เมื่อมีโครงสร้างที่ซับซ้อน คุณจะไม่ต้องเข้ารหัสคลาสใน JSON ด้วยฟิลด์ class เนื่องจากคำแนะนำประเภทของคุณจะบอกโค้ดของคุณว่าควรสร้างออบเจ็กต์หรืออาร์เรย์ใดแทนค่าที่ฝังไว้บางส่วน
หากคุณกำลังสร้าง API และคุณต้องการการตรวจสอบความถูกต้องของสคีมา OpenAPI ระดับองค์กร คุณควรตรวจสอบ hkarlstrom/openapi-validation-middleware และหลังจากนั้น คุณสามารถแมปเพย์โหลดที่ได้รับกับคลาสที่บอกเป็นนัยโดยใช้ไลบรารีนี้ -