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 และหลังจากนั้น คุณสามารถแมปเพย์โหลดที่ได้รับกับคลาสที่บอกเป็นนัยโดยใช้ไลบรารีนี้ -