So in this video, we are going to be talking about errors about how to handle built in PHP.
Errors and exceptions and how to do that the most secure way, and the way that will also give you the
necessary information about what has happened.
So this app is currently lacking any error handling.
And we need to add some error handling because every serious application needs a way to deal with errors.
And in PHP we've got two kinds of errors the built in errors, warnings and notices.
This was initially the way PHP reported errors, and it also outputted those errors on the screen directly.
You're gonna see in a second what I mean.
And another kind of errors are exceptions.
This was introduced later in PHP.
That's why we have two kinds of errors that can happen in PHP.
First, let me trigger the traditional PHP error.
This can happen, for example, if I echo or use a variable that wasn't initiated first.
So this hey variable obviously doesn't exist anywhere in here.
That's why this should cause some kind of an error.
And by default, in most modern versions of PHP this would be reported in console.
So let me refresh this page.
You can see this is not reported on this page that this variable is not defined.
But inside the console where PHP server runs, we can see a PHP warning that we are using an undefined
variable.
So it is good that PHP changed this behavior because.
Now let me show you how this looked like before.
So this word times in older versions of PHP, and I think that every single one of you have seen this
online popping up randomly on some older websites using WordPress.
So first let's set the error reporting level to display all errors.
This is how you do that.
And we're gonna set using any set method the setting called display underscore errors.
In modern PHP versions this is disabled by default.
And that's the right thing to do.
Let's just enable it so you can see what I mean.
Now when I refresh this page this is what I was talking about.
I guess every single one of you, even if you didn't know that is PHP.
You seen that on at least one website.
I think it's terrible.
It's ugly error reporting.
And it is unsafe because it is telling the random visitor of the website what language you are using,
what framework you are potentially using, and where your files are kept, and also what PHP file had
the error.
So it's great that now it is disabled by default.
Let's comment this out then it's enough to see it in the console.
So another kind of errors are exceptions.
So you already know a little about exceptions.
And you can throw your own exceptions or just handle the exceptions produced by some PHP libraries.
For example PDO can produce some exceptions if for example you can't connect to database, you can't
insert it to data to the database.
Can't read the data or there are some database errors.
Like for example, you are trying to insert a record that already exists.
So typically, the most modern solution to any kind of errors in PHP is to throw an exception.
So this is what I was talking about earlier, that we don't really have any error handling in this app,
so we need to handle exceptions.
Before we do, let me trigger an exception manually so we can see how it looks like.
So you do it using throw and you create just a new instance of the exception.
It can be let's use runtime exception saying whoops.
Now let me refresh the page and jump back to the terminal.
So the page that was returned isn't really telling us anything.
It looks really broken.
So that is not even a page that we have created.
This is the default browser page.
And when we take a look at the terminal, it contains a little bit more information about the error
that we maybe can use for debugging.
So our goal would be to create some common error page that will give our users more confidence that
something bad has happened, but maybe they can try again not to display this really terrible page that
looks like everything just went completely wrong and there is no recovery.
And also to handle those errors the same way.
Doesn't matter if there is a built in PHP error, or an exception is thrown by either our code or some
built in PHP code.
Now let's get to it.
Let's see how can we change the way errors are handled in PHP?
Now, I think that we should start with handling exceptions in a better way because as you can see right
now, currently if an exception happens, it is pretty catastrophic.
The whole page basically disappears and we see some default browser page.
Now we need to remember that exceptions can still be handled inside a try catch block.
That's best for when you expect a certain exception can be happening.
For example, with database connections it's quite possible that something would go wrong.
Now, currently we just need to add a handler that will handle unhandled exceptions.
However, this sounds so exceptions that weren't handled by our try catch block.
And they are really unexpected.
So without any changes here, let's jump to the bootstrap PHP file, because this is where I'd like
to set up the error handling.
So we want to report all the errors.
And another function that will be useful is set exception handler.
That's just a PHP function that will let us create our own custom way to handle exceptions.
So we need to call it.
This is set exception handler.
And we pass a callable here which is just a function.
Now we need to create one.
I think we can create another file just for errors.
I'm going to call it error handling.
And it's really crucial for our app.
That's why I think it can be on the same level as the bootstrap file.
Also, I think that the error handling should be one of the first things that happen inside the bootstrap
file.
I think it's pretty obvious because if we would move it at the end of the bootstrap file, all those
things that happen in between can potentially cause some errors, which would be then not really properly
reported and handled.
That's why it's important to do it as the first thing now.
That's also why we're gonna use require once and just require this error file right away.
So this is error handling PHP.
And now let's jump back to this file and create our custom exception handler.
So we need to pass a function here.
Let's see how this function should look like.
So it should only accept one parameter of type throwable which can be Of type error or exception.
That's why we type it with an interface.
So let me add a function called.
Exception handler that accepts throwable.
And it doesn't really return anything.
And let's implement some better exception handling.
Let's begin by producing a message that we are about to log.
The same as things are currently logged in the terminal.
So I just want a custom message.
So we say that this was an uncaught exception.
That's important to just say it that it wasn't caught.
Next up we need to concatenate with the actual class name of this exception.
This is important information.
For this we can just use the getclass function of PHP.
Passing this argument that I've called the exception, you can customize the name of that argument.
Then concatenate to close the parentheses.
That's just the beginning because next up we are going to sorry the colon goes in here.
Next up we concatenate that with further information from this exception object.
Because it contains the actual message we can get it through a method.
And next up let's also say in what file this happened.
Keep in mind this is information for us.
We're going to be logging this.
This is not displayed to the user.
So from exception we can also get the file name.
And additionally It's also concatenate this with online and say basically in which line this has happened.
This would be exception get line.
So that's the full message I'd like us to output.
Now in PHP there is this error log message that will put that on the console.
So let's do it.
And the rest let's just use the function we already have returning 500 code, but with some response
we're gonna say an unexpected error occurred.
Please, please try again later.
So as you see as little as possible information will be getting to the visitors of our website.
And this is intentional because they won't be fixing the errors in our code.
That's why they don't need to know the actual message.
Exception, and especially the file and line in which this has happened.
Now the final step is to jump to bootstrap and just pass a string with the function name that will handle
those exceptions.
After those changes, I should be able to refresh this page and see a nicer message.
Now nothing stops us from actually rendering a view.
So we've got this templates folder.
We can create a whole page including the header and footer called maybe 404 or 500 specific for errors
that will display the whole page with a very nice error and maybe very nice error message.
I mean, and maybe some instructions on how to recover.
But I think that for the purpose of demonstration, that's enough.
And also, let's jump to the terminal where we have our custom message that uncaught exception with
the class name has happened with the message and all the other info.
So another thing to handle apart from exception handler is this error handler.
So let's see the function set error handler.
That's the next one that we would have to call.
This is set error handler.
And obviously we need to prepare this handler first.
That's why we're gonna jump to error handling and create another function that can handle the non exception
errors in PHP.
So let's take a look at this set error handler function.
The first argument to it is callable.
But notice that it is nullable.
This means we can pass null to this function.
What's the point of that if we are about to set a custom error handler?
Well, the point is that if you pass null, it resets any custom handlers that you have assigned before
going back to the default PHP behavior.
Now let's see how our function that we are about to create should look like.
So this is the handler.
So here you can read that passing null will reset to the default PHP handler.
Now let's create a function that we can call error handler.
As you can see this function needs to return a boolean.
We're going to explain why and the arguments here.
So we've got an integer the error number.
Then a string error string.
This is a kind of a message.
And additionally we've got a string error file and then an integer.
This is an error line.
So line in that file where the error has happened.
And the context.
Well we can accept this argument or not.
It's up to us.
So maybe this is enough.
The first step is to construct a message that we're going to log.
So this is only for us.
We can say that the error with the error number.
Then let's display the message on line.
Next up we display the line in file.
And.
This is error file.
So this is a thing that we are about to log using error log.
That's a message.
And again here we're going to use the server error not to display too many info about what has happened.
Remember this is an unexpected thing.
So something probably gone terribly wrong.
So we just say an error occurred.
Please try again later.
So we display the message here.
And then to the user to the visitor.
We just call the server error function with some message that is very generic.
That unexpected error occurred.
Please try again later.
Now, even if we have a notice or warning, this is typically something that can really go terribly
wrong.
Previously, PHP ignored that by either logging this info or displaying it on page and trying to continue.
But I think that you should always fix all the issues and all the errors, like accessing a non-existing
key in array or using a non-existing variable.
I don't think you should be leaving those errors unattended and ignore them.
And this returns a boolean, because now we are just telling PHP whether this concludes the error handling.
If you return true.
PHP won't do anything, won't handle this internally with the default behavior, but if you return false.
PHP will also handle this error internally by doing how it is configured to behave, either displaying
this on screen Sunscreen are just logging the error.
So finally we need to jump to bootstrap and register this function.
This is error handler.
And then let's jump to our page where we trigger the errors.
Comment out this and try to echo a non-existing variable.
Now refresh this page.
We see the error, the generic error, and in the console we've got more info.
We've got the error the error number what's the message and where it happened.
So now we can comment out this error because we just wanted to trigger something to see how this would
behave.
But I consider the error handling more or less done for this project.
We can obviously improve error handling by handling exceptions, but I'm gonna leave it as an optional
thing for the end of this project.