Geben Sie eine streng typisierte Möglichkeit, mit Erfolgs- und Fehlerergebnissen für Ihre PHP -Anwendungen umzugehen.
Inspiriert von unthrow, also hier sind wir mit einer einfachen Implementierung von Neverthrow von PHP.
Das Werfen und Fangen ist der Verwendung von GOTO -Aussagen sehr ähnlich - mit anderen Worten; Es macht die Begründung über Ihre Programme schwieriger. Zweitens nehmen Sie die Annahme, dass der Anrufer Ihrer Funktion den Fang implementiert. Dies ist eine bekannte Quelle für Fehler. Beispiel: Ein Dev wirft und ein anderes Entwickler verwendet die Funktion ohne Vorkenntnis, dass die Funktion werfen wird. So wurde der Fall von Edge unberechtigt und jetzt haben Sie unglückliche Benutzer, Chefs, Katzen usw.
Nach all dem gibt es definitiv gute Anwendungsfälle, um Ihr Programm einzugeben. Aber viel weniger als du vielleicht denkst.
TL; DR: Kein Wurf = glücklicheres Leben & Anwendung. Weniger Fehler bei der Produktion und erhöhen Sie die trockenen und wiederverwendbaren Dinge in Ihren PHP -Apps.
PHP 8.2+ seit v2.0.0
composer require shipsaas/never-throw NeverThrow\Result ERGEBNISSKLASSE und bereit, jederzeit verlängert zu werden.
isOk()isError()getOkResult()getErrorResult() Wir werden zwei neue Klassen erstellen: Erfolg & Fehler. Und fühle dich frei, deine Daten zu platzieren
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
) {}
}Letzter Schritt vor der Verwendung von Neverthrow. Das Erstellen einer dedizierten Ergebnisklasse hilft uns zu:
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 );Wie Sie mit dem obigen Code sehen können, gibt es:
Es würde die Entwicklung wirklich großartig und keine Schmerzen bringen.
Mit streng typisierten Rückgabetypen können Entwickler wissen, was mit anderen Diensten/Bibliotheken vor sich geht. Macht das wiederverwendbare besser. Und wir müssen den Versuch/Fang nicht einwickeln und unseren Code hässlich.
Missbrauche Ausnahmen nicht, sie sollten nur für unerwartete Situationen (und Fehler! == Ausnahmen, Fakt) verwendet werden.
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 ;
}Der größte Teil dieser Funktion geht tatsächlich um die Dinge, die schief gehen können, aber unsere Typen informieren uns nur über den erfolgreichen Weg. Das bedeutet, dass 4/5 der Ausgabe der Funktion nicht angegeben sind!
Die obigen "Ausnahmen" oder "Fehler" sind überhaupt keine Ausnahmen oder Fehler. Sie sind Ergebnisse. Sie sind vorhersehbare, vernünftige Teile unseres Systems. Meine Heuristik ist, wenn sie etwas sind, das sich um einen guten Produktmanager kümmert, sind sie keine Ausnahmen und Sie sollten sie nicht werfen!
Ausnahmen sind unvorhersehbare Dinge, die wir nicht vernünftigerweise planen können, dass das System nicht versuchen sollte, sich zu erholen, und wir sollten nicht zum Benutzer übergehen.
MIT -Lizenz