ให้วิธีการพิมพ์อย่างเคร่งครัดเพื่อจัดการกับผลลัพธ์ที่ประสบความสำเร็จและข้อผิดพลาดสำหรับแอปพลิเคชัน PHP ของคุณ
แรงบันดาลใจจาก Neverthrow ดังนั้นที่นี่เราอยู่กับการใช้งาน Neverthrow อย่างง่ายจาก PHP
การขว้างปาและการจับนั้นคล้ายกับการใช้คำสั่ง goto - กล่าวอีกนัยหนึ่ง; มันทำให้เหตุผลเกี่ยวกับโปรแกรมของคุณยากขึ้น ประการที่สองโดยการใช้การโยนคุณตั้งสมมติฐานว่าผู้โทรของฟังก์ชั่นของคุณกำลังดำเนินการจับ นี่เป็นแหล่งที่มาของข้อผิดพลาด ตัวอย่าง: dev หนึ่งขว้างและ dev อื่นใช้ฟังก์ชั่นโดยไม่มีความรู้มาก่อนว่าฟังก์ชั่นจะโยน ดังนั้นและกรณีขอบถูกทิ้งไว้และตอนนี้คุณมีผู้ใช้ที่ไม่มีความสุขผู้บังคับบัญชาแมวแมว ฯลฯ
จากทั้งหมดที่กล่าวมามีกรณีการใช้งานที่ดีสำหรับการขว้างในโปรแกรมของคุณ แต่น้อยกว่าที่คุณคิด
TL; DR: No Throw = มีความสุขมากขึ้นและแอปพลิเคชัน ข้อผิดพลาดน้อยลงเกี่ยวกับการผลิตและเพิ่มสิ่งที่แห้งและนำกลับมาใช้ใหม่ในแอพ PHP ของคุณ
PHP 8.2+ ตั้งแต่ v2.0.0
composer require shipsaas/never-throw NeverThrow\Result และพร้อมที่จะขยายเวลาได้ตลอดเวลา
isOk()isError()getOkResult()getErrorResult() เราจะสร้างคลาสใหม่สองคลาส: ความสำเร็จและข้อผิดพลาด และอย่าลังเลที่จะนำข้อมูลใด ๆ ของคุณ
use NeverThrow SuccessResult ;
use NeverThrow ErrorResult ;
// Success
class BookShipperOkResult extends SuccessResult
{
public function __construct (
public string $ bookingId
) {}
}
enum BookingErrors {
case NO_SHIPPER_AVAILABLE ;
case OVERWEIGHT_PACKAGE ;
case INVALID_ADDRESS ;
}
// Error
class BookShipperErrorResult extends ErrorResult
{
public function __construct (
public BookingErrors $ outcome
) {}
}ขั้นตอนสุดท้ายก่อนที่จะใช้ Neverthrow การสร้างคลาสผลลัพธ์โดยเฉพาะช่วยให้เรา:
use NeverThrow Result ;
class BookShipperResult extends Result
{
public function getOkResult (): BookShipperOkResult
{
return parent :: getOkResult ();
}
public function getErrorResult (): BookShipperErrorResult
{
return parent :: getErrorResult ();
}
} public function createBooking ( User $ user , BookingOrder $ order ): BookShipperResult
{
$ hasAnyShipperAvailable = $ this -> shipperService -> hasAnyShipperAvailable ();
if (! $ hasAnyShipperAvailable ) {
return new BookShipperResult (
new BookShipperErrorResult (
BookingErrors:: NO_SHIPPER_AVAILABLE
)
);
}
$ isOverweight = ! $ this -> weightService -> isValid ( $ order );
if ( $ isOverweight ) {
return new BookShipperResult (
new BookShipperErrorResult (
BookingErrors:: OVERWEIGHT_PACKAGE
)
);
}
$ bookingId = $ this -> book ( $ user , $ order );
return new BookShipperResult ( new BookShipperOkResult ( $ bookingId ));
} $ bookingResult = $ this -> service -> createBooking ( $ user , $ order );
if ( $ bookingResult -> isError ()) {
$ errorResult = $ bookingResult -> getErrorResult ();
// handle error
return showError ( match ( $ errorResult -> outcome ) {
BookingErrors:: NO_SHIPPER_AVAILABLE => ' No shipper available at the moment. Please wait ' ,
BookingErrors:: OVERWEIGHT_PACKAGE => ' Your package is overweight ' ,
});
}
return showBooking ( $ bookingResult -> getOkResult ()-> bookingId );อย่างที่คุณเห็นด้วยรหัสด้านบนมี:
มันจะนำการพัฒนาที่ยอดเยี่ยมอย่างแท้จริงและไม่มีความเจ็บปวด
ด้วยประเภทผลตอบแทนที่พิมพ์อย่างเคร่งครัดนักพัฒนาสามารถรู้ว่าเกิดอะไรขึ้นกับบริการ/ห้องสมุดอื่น ๆ จึงทำให้สามารถใช้ซ้ำได้ดีขึ้น และเราไม่จำเป็นต้องห่อลอง/จับและ uglify รหัสของเรา
ไม่ต้องใช้ข้อยกเว้นในทางที่ผิดพวกเขาควรใช้สำหรับสถานการณ์ที่ไม่คาดคิดเท่านั้น (และข้อผิดพลาด! == ข้อยกเว้นข้อเท็จจริง)
function transfer (): Transaction
{
if (! $ hasEnoughBalance ) {
thrown new InsufficientBalanceError ();
}
if (! $ invalidRecipient ) {
throw new InvalidRecipientError ();
}
if (! $ invalidMoney ) {
throw new InvalidTransferMoneyError ();
}
$ transaction = $ this -> transferService -> transfer (...);
if (! $ transaction ) {
throw new TransferFailedError ();
}
return $ transaction ;
}ฟังก์ชั่นนี้ส่วนใหญ่เกี่ยวกับสิ่งที่ผิดพลาด แต่ประเภทของเราจะแจ้งให้เราทราบถึงเส้นทางที่ประสบความสำเร็จเท่านั้น นั่นหมายถึง 4/5th ของเอาต์พุตของฟังก์ ชั่นไม่ได้รับการออกแบบ !
"ข้อยกเว้น" หรือ "ข้อผิดพลาด" ข้างต้นไม่ใช่ข้อยกเว้นหรือข้อผิดพลาดเลย พวกเขาเป็นผลลัพธ์ พวกเขาสามารถคาดเดาได้ส่วนที่สมเหตุสมผลของระบบของเรา ฮิวริสติกของฉันคือถ้าพวกเขาเป็นสิ่งที่ผู้จัดการผลิตภัณฑ์ที่ดีจะสนใจพวกเขาไม่ใช่ข้อยกเว้นและคุณไม่ควรโยนพวกเขา!
ข้อยกเว้นเป็นสิ่งที่คาดเดาไม่ได้ที่เราไม่สามารถวางแผนได้อย่างสมเหตุสมผลว่าระบบไม่ควรพยายามกู้คืนและเราไม่ควรกำหนดเส้นทางไปยังผู้ใช้
ใบอนุญาต MIT