Exceptions7:26 with Phil Sturgeon
Exceptions are different from errors. Exceptions can easily be caught and handled separately on a case-by-case basis, whereas catching errors can only be done application-wide.
In the last video we discussed how PHP was exception light and 0:00 used optional error messages or false E values to report a problem. 0:04 The core itself might not use exceptions much, but 0:08 they are available if you wish to use them in your own code. 0:10 And you'll certainly run into them using components or frameworks. 0:12 The problem with giving false E values is that you have to go looking for a mistake 0:16 and check the documentation to see which method provides the error message. 0:20 It's be much better to have an exception thrown at you to make it 0:23 extremely obvious. 0:26 Let's take a look at how we can throw various types of an exception from 0:28 a function and have PHP react differently to each of them. 0:31 If we look in the workspace we'll see a couple of files there which you 0:34 should recognize already from composer. 0:36 We open the index.php. 0:38 There's quite a lot of code in here, but don't panic. 0:40 I'm gonna explain what all of this means. 0:42 On line three here we have display errors which we're already familiar with. 0:45 This will help us recognize any errors that are unexpected. 0:48 We have a include vendor autoload.php which once again is, composer related. 0:52 And this is where our, our new code starts. 0:57 Basically, this is a HTTP download script which will download the body of 0:59 any URL that we provide. 1:04 On lines eight to ten here, we define multiple types of exception. 1:05 You can just use the core exception class, but 1:09 defining your own exceptions by extending the exception class makes it 1:11 much easier to distinguish different types of exception later on. 1:14 I'm breaking a few rules here by defining multiple classes and functions in the same 1:18 body, normally these should be split out into different files, but for the sake of 1:22 demonstrating, I, I kind of broke the rules there and threw them in together. 1:25 On line 13 here we're defining a function named fetch http body and 1:29 it takes one argument which is a URL. 1:35 This argument is a string value of the URL that we'd like to download. 1:38 Line 15 here instantiates a class called browser which lives 1:43 inside the buzz name space. 1:47 This is a handy little package which lets us work with HTTP interactions in 1:48 a much more sane fashion than the curl extension, and we 1:52 can rely on this working even if the curl extension is not installed on the server. 1:55 Line 16 here is using our newly instantiated browser object and 1:59 running the get method. 2:03 And passing the URL as an argument. 2:04 The response is an object. 2:06 And it's stored in this response variable. 2:08 Then on lines 18 we're downloading the content of the response. 2:11 This is the HTTP body. 2:15 The actual HTML of the response. 2:16 On line 19 here we are looking at the response object. 2:19 And running the getStatusCode method. 2:22 And storing that in a status code variable. 2:25 We'll use both these items in a moment. 2:28 On line 21 we're creating a status group variable. 2:30 And we're doing some string work on the status code to find out 2:33 what the very first digit is. 2:37 This means that if we get a code of 400 back then we only want the four. 2:38 If you're not familiar with HTTP status codes, 2:43 just know that there are lots of different codes, each with a different meaning. 2:45 And we can group these codes based on the first digit. 2:48 For example, if we get code 404 that means a missing page. 2:51 And because it starts with a four we know that it's a HTTP client error. 2:55 An HTTP client could be a web browser or in this case our PHP code. 2:59 Because the client asked for 3:04 a missing page we should tell them that they messed up. 3:05 So this status code variable can contain two, three, four, or five. 3:08 Depending on the type of exception we throw the outside code will want to 3:13 interact differently. 3:16 By using the status group variable in a switch element we can 3:18 throw different exceptions. 3:21 These rules are based on the HTTP specification, so 3:23 just go along with them if you don't completely understand the HTTP spec. 3:25 So 23, we have a switch statement looking at the status group. 3:29 And then we have a case for 3:32 each different potential value the status group can contain. 3:33 By line 25, we know the value starts with a 2, 3:37 which according to the HTTP specification, means everything worked. 3:39 That means we can go ahead and 3:43 return the content variable and there is no need for an exception. 3:45 On line 27, we know the code started with a 3 which means a redirection happened. 3:48 To let the function call know about that we can throw in new HTTP, redirect 3:53 exception with a human readable message and the specific status code included. 3:57 If we get to line 29 here. 4:01 We know that the code started with a four and 4:04 that must mean that the client made a bad request. 4:05 We can let them know about that by throwing a new HTTP client exception. 4:08 On line 31 here, we have a code starting with a 5, 4:12 which the HTTP specification explains means a server error. 4:15 So let's throw a HTTP server exception with another human readable string. 4:19 Finally, line 32 has a default case. 4:23 That means if we get an unexpected value in the status group then we 4:26 can throw a generic exception explaining that we don't know what's going on, 4:28 something weird happened. 4:31 Now, I know that's quite a lot to take in but the main takeaway here is 4:33 that different types of problem have different types of exceptions. 4:36 So reactions can differ based on the exception. 4:39 Let's take a look at some code that reacts differently based on different exceptions. 4:42 If wee look at line 39 here we'll see that we're calling our fetch HTTP body and 4:46 we're echoing the result directly. 4:51 We're also passing in a string. 4:54 This string contains a URL which will go into the URL parameter in our 4:55 function defined above. 4:59 You'll also notice that on the line above, on line 38, we have a try block. 5:01 This try means that it should look out for any exceptions being thrown, and 5:04 if the exceptions being thrown match any of these four here, 5:08 then the piece of code in that catch block will run. 5:12 We'll know which type of exception is being thrown by looking at the output of 5:15 our error, because we have this string appended on the front. 5:18 We're then outputting getMessage. 5:23 And in the case of these first three, we're also outputting the code. 5:26 If you're not sure how printf works it's just a, a, a pretty way to format strings. 5:29 Look it up in the manual if you need to understand it, 5:34 but these basically put, these values into place. 5:36 So I think it's about time that we ran our script to see what happened. 5:40 If we go to the Preview icon here. 5:42 Then we see example domain, this is exactly the output we were expecting. 5:45 We got to example.org ourselves, then that's what you see, 5:51 looks exactly the same, brilliant. 5:54 Now let's try and break it, if I put in a garbage URL like this, so 5:56 it definitely doesn't exist on the website. 6:00 Then we should be able to refresh, and perfect. 6:02 We got a client error and 6:05 the code 404 which as I explained earlier means page missing. 6:06 We go back to our code, and try and break it in another way. 6:09 We got a general error saying it failed to open stream. 6:13 Now, this isn't one of our exceptions, but it is being caught by our code. 6:16 This exception is being thrown by buzz. 6:20 They've thrown some sort of exception that we haven't made a catch for. 6:23 But because we have this catchall statement here we're catching it anyway. 6:27 This is great. 6:31 It's not only if we ensured that we're looking out for 6:32 specific events from our code and reacting to them accordingly, but we're also 6:33 using a catchall block to catch any other exceptions that we didn't expect. 6:37 Instead of simply echoing out these errors we can use them to do 6:40 useful things in our code. 6:43 A HTTP server exception might retry the connection. 6:45 A HTTP client exception might send an error to the user. 6:48 A general exception might fire off an email to somebody on the development team, 6:52 letting them know that code needs to be improved. 6:55 The point here is by reacting to specific expectations, 6:58 you can get very granular in how you react to specific problems. 7:01 Which is so much more useful than just looking for 7:04 a false return value, and then saying nope. 7:06 That didn't work. 7:09 Exceptions can take a little while to get your head around, but on a very basic 7:10 level, custom exception classes should be used like a category of exception. 7:13 Then the specific error message and code provide further information. 7:18 This is much easier than trying to work out if false is good or bad. 7:22
You need to sign up for Treehouse in order to download course files.Sign up