Uff! PHP feil for kule barn

Whoops er et lite bibliotek, tilgjengelig som en komposerpakke, som hjelper deg med å håndtere feil og unntak i PHP-prosjektene dine.

Ut av boksen får du en elegant, intuitiv og informativ feilside hver gang noe går i buksen opp i søknaden din. Enda bedre, under alle som er en veldig rett frem, men fleksibel, verktøysett for å håndtere feil på en måte som gir mening for hva det er som du gjør.

Bibliotekets hovedtrekk er:

  • Detaljert og intuitiv side for feil og unntak
  • Kodevisning for alle rammer
  • Fokuser på feil- / unntaksanalyse ved bruk av egendefinerte, enkle mellom-ware / håndteringsverktøy
  • Støtte for JSON og AJAX forespørsler
  • Inkluderte leverandører for Silex og Zend-prosjekter gjennom de medfølgende leverandørene, og inngår som en del av Laravel 4-kjernen
  • Ren, kompakt og testet kodebase, uten ekstra avhengigheter

Whoops oppnår dette gjennom et system med stablede handlers. Du forteller Whoops som håndterer du vil bruke (du kan velge mellom de medfølgende håndteringene eller lage dine egne), og hvis noe skjer, blir alle håndterer gitt, i rekkefølge, en sjanse til å gjøre noe - dette kan være alt fra å analysere feil (Whoops gjør det enklere å trekke ut meningsfull informasjon fra en feil eller et unntak), for å vise nyttige feilskjermer (som den innebygde PrettyPageHandler, som gir deg den kule utseendet siden vist på bildet ovenfor).

La oss prøve det først, ved å se på det grunnleggende, og deretter ved å ha en tur til å bygge vår egen handler med Whoops og Laravel-rammen. For denne korte veiledningen antar jeg at du er moderat komfortabel med PHP, og at du har hørt om Composer. Hvis dette ikke er tilfelle, les det på Nettuts+.


Installere Whoops

Opprett en katalog for prosjektet ditt, bytt til det, opprett en composer.json fil med Whoops-kravet, og installer det. Whoops (fra versjon 1.0.5) har ingen avhengighet, så dette tar bare et sekund.

 $ cd / path / to / your / project $ komponist krever filp / whoops 1. * $ composer install

Bruke Whoops: Grunnleggende

For å se den smarte feilsiden i handling, la oss sette opp Whoops og sørge for at noe går i stykker ved å kaste et unntak i koden vår. Lag en fil i prosjektets katalog; for denne veiledningen, la oss si at den heter, index.php.

 $ cd / path / to / your / project $ din-favoritt-editor index.php

Fordi vi installerte Whoops with Composer, og det er PSR-0-kompatibelt, er alt vi trenger å gjøre, å kreve Composer autoloader og vi er klare til å begynne å bruke biblioteket i vår egen kode!

 pushHandler (new Whoops \ Handler \ PrettyPageHandler ()); // Sett Whoops som standard feil og unntakshåndterer som brukes av PHP: $ whoops-> register (); kaste ny RuntimeException ("Oopsie!"); ?>

Hvis du allerede har en webserver som kjører, går du videre og får tilgang til filen du nettopp har opprettet. Ikke glem: Hvis du bruker PHP 5.4, kan du utnytte den innebygde utviklingsserveren slik som:

 $ cd / path / til / ditt / prosjekt $ php -S localhost: 8080

Dette er hva du får:

Ganske pent, ikke sant? Handlers, selv, kan avsløre muligheter for å endre eller øke deres oppførsel. For eksempel kan du blant annet sette tittelen på standard feil siden, og til og med sette inn ekstra informasjon:

 setPageTitle ("Det er ødelagt!"); // Angi sidens tittel $ errorPage-> setEditor ("sublime"); // Sett redigereren som ble brukt for "Åpne" linken $ errorPage-> addDataTable ("Ekstra info", array ("stuff" => 123, "foo" => "bar", "useful-id" => "baloney ")); $ Whoops-> pushHandler ($ errorPage); $ Whoops-> register (); kaste ny RuntimeException ("Oopsie!"); ?>

Også, siden dette bare er en vanlig Whoops-handler, kan vi blande og samsvare med andre håndtere for å oppnå mer dynamiske resultater. La oss forestille deg at du jobber med et AJAX + JSON-drevet nettsted. For øyeblikket, hvis søknaden din skulle mislykkes på en eller annen måte, ville du få en haug med ekkel HTML som kommer ned i røret, da du ventet JSON. Ingen stor sak:

 pushHandler (new Whoops \ Handler \ PrettyPageHandler ()); $ whoops-> pushHandler (new Whoops \ Handler \ JsonResponseHandler ()); $ Whoops-> register (); kaste ny RuntimeException ("Oopsie!");

Det er det. Nå, hvis noe feiler under en AJAX-forespørsel, vil Whoops svare med et JSON-svar som angir feilen. Hvis det ikke er en AJAX-forespørsel, fortsetter du å se den vanlige feilsiden. Hvis en feil oppstår, vil Whoops filtrere gjennom hver av de registrerte handlerne (starter ved den siste handleren som skal registreres), og gi dem en sjanse til å analysere, modifisere og svare på forespørselen.

Nå som du har en generell ide om hvordan Whoops fungerer, la oss ta en tur på å bygge vår egen handler med Whoops og Laravel 4 rammeverket.


Whoops og Laravel 4

Laravel 4 bunter Whoops som en kjerne unntakshåndterer, aktivert som standard i utviklingsmodus, inkludert en tilpasset fargeskjema av Dayle Rees:

Hvis du ikke har installert Laravel ennå, kan du gå over og følge installasjonstrinnene. Laravel er omfattet omfattende på Nettuts + og Tuts + Premium, så du vil finne mye trening her, hvis du ønsker å grave videre.

For de neste trinnene antar jeg at du er litt komfortabel med grunnleggende om Laravel 4. Men selv om du ikke er det, bør det fortsatt være lett å følge.

Hvis du er i utvikling (feilsøkingsmodus), er Whoops tilgjengelig via IoC-beholderen som Uff, og forhåndsinnstilt med en av to håndtere: PrettyPageHandler eller JsonResponseHandler, som whoops.handler (de samme to vi snakket bare om). Begge disse handlerne avslører nyttige ekstra metoder, som du har sett over med PrettyPageHandler. Ved å få tilgang til disse tjenestene, kan vi begynne å tilpasse vår Whoops-opplevelse innenfor rammen.

For enkelhets skyld, i din app / routes.php fil, la oss koble til Whoops-tjenesten og angi en tilpasset sidetittel for våre feilsider:

 setPageTitle ("Houston, vi har et problem!"); // Sett linken "åpen:" for filer til vår redaktør av valg: $ whoopsDisplayHandler-> setEditor ("sublime");  Rute :: få ('/', funksjon () // Force utførelsen til å mislykkes ved å kaste et unntak: kaste nye RuntimeException ("Oopsie!");); ?>

Tips: Whoops støtter noen få redaktører som standard, og lar deg implementere støtte for deg selv som du ønsker. Les mer om det her.

Hvis du nå får tilgang til Laravel-søknaden din, blir du møtt med en feilmelding med den egendefinerte sidetittelen din. Hvis du klikker på filbanen over kodeboksen, bør den åpne den refererte filen rett i redaktøren eller IDE-en. Hvor kult er det? Også, siden vi kan nå håndtereren allerede opprettet av Laravel-kjerne, kan vi sette for å bruke de andre funksjonene vi har lært om ovenfor. For eksempel kan vi legge til egendefinerte tabeller (med PrettyPageHandler :: addDataTable) med nyttig informasjon om vår søknad.

La oss gå på et enda eksempel. Dette vil være vårt første forsøk på å skrive vår egen tilpassede handler. Vi ønsker å få alle stakkrammer for et unntak, og fjerne alt som ikke er en del av vår programkode. Høres enkelt nok, rett?

 pushHandler (funksjon ($ unntak, $ unntakInspector, $ runInstance) // Få samlingen av stabelrammer for det nåværende unntaket: $ frames = $ exceptionInspector-> getFrames (); // Filtrer eksisterende rammer slik at vi bare holder dem inne appen / mappen $ frames-> filter (funksjon ($ frame) $ filePath = $ frame-> getFile (); // Match hvilken filsti som inneholder / app / ... returnere preg_match ("/ \ / app \ /.+ / i ", $ filePath);); returnerer Handler :: DONE;);  Rute :: få ('/', funksjon () // Force utførelsen til å mislykkes ved å kaste unntak: kaste nye RuntimeException ("Oopsie!";;); ?>

Tips: Du trenger ikke å returnere Handler :: FERDIG - Dette tjener bare et semantisk formål. Hvis du vil ha Whoops å slutte å kjøre noen ekstra handlere etter din, skriv returbehandler :: LAST_HANDLER. Hvis du vil ha Whoops for å gå ut av manuskriptet etter handleren din, returhåndterer :: QUIT.

Du kan se at det er bemerkelsesverdig kortfattet. Whoops \ Run's pushHandler Metoden aksepterer et lukke som mottar opptil tre argumenter: Unntaket, et unntaksinspektør, som avslører noen bruksmetoder til, du gjettet det, inspiser unntak, og Whoops \ Run eksempel som fanget unntaket. Gjennom denne håndteringen bruker vi unntaksinspektøren til å trekke ut rammestammen, alt innenfor en fin måte FrameCollection gjenstand:

 getFrames (); // # => Whoops \ Unntak \ FrameCollection; telle ($ rammer); # => int foreach ($ rammer som $ ramme) get_class ($ frame); // # => Whoops \ Unntak \ Frame utskrift $ frame-> getFile (). ":". $ frame-> getLine (). "\ N"; # => "/path/to/file.php:123"?>

Tips: Whoops konverterer internt lokaler til en spesiell handler: Whoops \ Handler \ CallbackHandler.

Du kan telle, iterere, kart og filtrere innholdet i denne klassen, med det interessante, men viktige aspektet at kart- og filteroperasjonen muterer objektet på plass. Dette betyr at begge disse operasjonene endrer den opprinnelige forekomsten direkte, i stedet for å opprette en ny samling. Hvordan er dette viktig? Det betyr at håndtere lettere kan utføre endringer som sprer seg nedover til alle de andre håndtererne i stabelen. Dette er akkurat det vi gjorde med vår enkle handler ovenfor. Hvis du kjører skriptet igjen, ser du at vi får en kortere liste over stabelrammer, bare om koden som ligger i vår søknadskatalog.

Når det gjelder rammeobjektet, seg selv (Whoops \ Unntak \ Frame), avslører det et sett med metoder for å samle informasjon om rammeinnholdet (filbanen, linjenummeret, metoden eller funksjonsanropet, klassenavnet, osv.), og metoder som lar deg legge ved kommentarer til individuelle stakkrammer. En rammekommentar er en nyttig funksjon i Whoops som gir håndterere mulighet til å gi tilleggsinformasjon som de samler fra et unntak ved å legge ved notater direkte til individuelle rammer i stabelen. Håndterer som PrettyPageHandler, for eksempel kan du samle disse kommentarene og vise dem sammen med rammens filbane og linjenummer.

 pushHandler (funksjon ($ unntak, $ unntakInspector, $ runInstance) foreach ($ exceptionInspector-> getFrames () som $ i => $ frame) $ frame-> addComment ("Dette er rammenummer $ i");  Return Handler :: DONE;); ?>

Ramme kommentarer kan også motta et sekund omfang argument. Hvis du har flere tilpassede håndteringsprogrammer, kan du for eksempel filtrere rammebeskrivelser med dette argumentet for å samle kun informasjonen du bryr deg om.

 getFrames (); foreach ($ rammer som $ ramme) // Var denne rammen innenfor en kontrollerklasse? (slutter i Controller) $ className = $ frame-> getClass (); if (substr ($ className, -10) == "Controller") $ frame-> addComment ("Denne rammen er inne i en kontroller: $ className", "controller-error");  // Senere, i en annen handler, få alle kommentarer innenfor 'kontroller-feil'-omfanget: $ controllerErrors = $ frame-> getComments ("controller-errors"); // # => array?>

Også av interesse, den PrettyPageHandler Helt naturlig HTML-rømmer rammebeskrivelsene før de vises, men vil intelligent fange URIer i kommentarens kropp og konvertere dem til klikkbare ankerelementer. Vil du koble rammer til dokumentasjon, eller til GitHub-depotene? Det er lett nok; la oss lage vår egen handler klasse for dette eksempelet.

Tips: Ved å bruke din egen klasse i stedet for en lukning får du litt ekstra kontroll over håndtereren din - for ikke å nevne at det blir enklere å dekke med automatiserte tester. Dine tilpassede handlerklasser må implementere Whoops \ Handler \ HandlerInterface grensesnitt, men du kan i stedet bare utvide Whoops \ Handler \ Handler klasse, og implementer den manglende håndtak metode, som vist i eksemplet nedenfor.

 getInspector () -> getFrames (); foreach ($ rammer som $ ramme) $ file = $ frame-> getFile (); $ line = $ frame-> getLine (); // Noen rammer kan ikke ha en filsti, for eksempel hvis den er vist innenfor // en Closure, så vi må sjekke for det: hvis (! $ Fil) fortsetter; // Sjekk om filbanen for denne rammen var innenfor mappen laravel / framework //, inne i Composer-leverandøren / katalogen, og bruk en regex-fangst // for å trekke ut bare de delene vi vil ha: hvis (preg_match ("/ \ / leverandør \ / laravel \ / framework \ / (. +) $ / ", $ file, $ matches)) $ path = $ matches [1]; // Første kamp er hele banen, andre er vår fangst $ url = "$ this-> repoBase / $ path"; // Vi kan også koble direkte til et linjenummer, hvis vi har det. Github // støtter dette ved å legge til #L til slutten av nettadressen: if ($ line! == null) $ url. = "#L $ line";  $ frame-> addComment ($ url, "github-linker");  returbehandler :: DONE; ?>

Det er det, så langt vår handler går. Sett den klassen et sted i prosjektet ditt, og alt som er igjen å gjøre, er å aktivere og prøve det ut:

 pushHandler (ny LaravelGithubLinkHandler ()); // ...?>

Med bare en håndfull kodelinjer har vi lagt til et ekstra lag av (muligens ubrukelig, men hei, det er et eksempel) funksjonalitet til våre feilsider. Her er noen ekstra ideer, hvis du leter etter en utfordring:

  • Pakke din tilpassede feilbehandler som Laravel-tjenesteleverandør.
  • Bruker du Git til å administrere prosjektet ditt? Bygg en tilpasset håndterer som knytter seg til git skylden for å avgjøre hvem den siste personen til å berøre den filen som fortsetter å kaste et unntak (og rop på dem) var direkte fra feilsiden.
  • Hvis du føler deg modig, bruk nikics PHP-Parser til å analysere den plagsomme koden, og gi forslag til reparasjoner (jeg lover at det ikke er så komplisert som det høres ut).

Siste tanker

Jeg håper at denne korte veiledningen har hjulpet deg med å få en forståelse av hva slags muligheter dette biblioteket muliggjør i dine hverdagsprosjekter. For mer informasjon, se den komplette API-dokumentasjonen.

Whoops er ramme-agnostisk, lett og, tror jeg, ganske kraftig i sin enkelhet og fokuserer på miks og samsvarende små verktøy. Den er også åpen kildekode og åpen for forslag og forbedringer. Hvis du vil bidra eller rapportere en feil, gå til det offisielle depotet!