توفير طريقة مكتوبة بدقة للتعامل مع نتائج النجاح والخطأ لتطبيقات PHP الخاصة بك.
مستوحى من Neverthrow ، هنا نحن هنا مع تنفيذ بسيط لـ Neverthrow من PHP.
يشبه الرمي والقبض على استخدام عبارات GOTO - بمعنى آخر ؛ يجعل التفكير في برامجك أكثر صعوبة. ثانياً ، من خلال استخدام رمي ، تضع افتراضًا بأن المتصل في وظيفتك يقوم بتنفيذ Catch. هذا هو مصدر معروف للأخطاء. مثال: يلقي أحد Dev و Dev آخر الوظيفة دون معرفة مسبقة بأن الوظيفة ستلقي. وهكذا ، تم ترك حالة Edge غير معطلة والآن لديك مستخدمون غير سعيدين أو رؤساء أو قطط ، إلخ.
مع كل ما قيل ، هناك بالتأكيد حالات استخدام جيدة لرمي في برنامجك. ولكن أقل بكثير مما قد تعتقد.
TL ؛ DR: لا رمي = أسعد الحياة والتطبيق. أقل من الأخطاء في الإنتاج وزيادة الأشياء الجافة والقابلة لإعادة الاستخدام في تطبيقات 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 );كما ترون مع الكود أعلاه ، هناك:
من شأنه أن يجلب التطور رائع حقًا ولا ألم.
مع أنواع العائدات المكتوبة بدقة ، يمكن للمطورين معرفة ما يجري مع الخدمات/المكتبات الأخرى. مما يجعل إعادة الاستخدام أفضل. وليس علينا أن نلفت المحاولة/التقاط الكود.
لا تسيء استخدام الاستثناءات ، يجب استخدامها فقط في المواقف غير المتوقعة (والأخطاء! == استثناءات ، حقيقة).
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/5 من إخراج الوظيفة غير معبأ !
"الاستثناءات" أو "الأخطاء" أعلاه ليست استثناءات أو أخطاء على الإطلاق. هم نتائج. يمكن التنبؤ بها ، وأجزاء معقولة من نظامنا. إن مجريات الأمور الخاصة بي هي ، إذا كانوا شيئًا يهتم به مدير منتج جيد ، فهي ليست استثناءات ولا يجب أن ترميها!
الاستثناءات هي أشياء لا يمكن التنبؤ بها لا يمكننا التخطيط لها بشكل معقول ، وأن النظام لا ينبغي أن يحاول الاسترداد من ، ويجب ألا نتوجه إلى المستخدم.
رخصة معهد ماساتشوستس للتكنولوجيا