In Yii, the error handling is very flexible, so we can create our own error handler for errors of specific type. Here, we will handle a 404 not found error in a smart way; We will show a custom 404 page that will suggest the content based on what was entered in the address bar.
Set up our Yii web application, Configure a database and import the following SQL:
Done! Now Generate an Article model and an Article crud using Gii followed by creating few sample articles.
|Yii framework||yii-framework||Yii framework is good.|
|Why Yii||why-yii||Why should I use Yii?|
|PHP is a good tool||php-is-a-good-tool||PHP is nice!|
|Yii as a tool for apps||yii-as-a-tool-for-apps||Yii is a good tool for apps.|
Let’s do it:
1. Try to run http://your.application/yii. You should get a standard 404-error page. Now we need to somehow change this page, but leave it as it is for other error types. In order to achieve this, we will use the application’s onException event. Let’s configure it to be handled by the handle static method of the NotFoundHandler class. We will do it by using protected/config/main.php as follows:
2. Now we need to implement the error handling itself. Create protected/components/NotFoundHandler.php as follows:
3. Also, we will need a view named protected/views/error/404.php:
That’s all, now try the following URLs
Each time, you will get several links to related articles.
How it works?
By using the configuration file, we attach an event handler to the onException event as follows:
‘onException’ => array(‘NotFoundHandler’, ‘handle’),
This means that we will use NotFoundHandler::handle(). Every event handler method accepts a single parameter named $event with event data inside. The exception handler parameter accepts the CExceptionEvent instance. As it contains the original exception, we can check for its type and error code as follows:
If the exception doesn’t match, the Yii works as before and if it does match, Yii executes our custom code:
We get the last URL segment as it will most probably contain the article alias if the URL is in path format. Then, form DB criteria and get models as follows:
Then, we render a view in the following way:
Note that we are creating a new CController instance because 404 can be reached before the application will initialize a controller.
$event->handled = true;
Finally, we instruct Yii that the event is handled and there is no need to handle it further.