As we dig in to the Yii Framework further, it seems like an in depth examination of controllers makes a good next step. In this episode we will take a closer look at the generated controller from our advanced installation. Since the code here is a result of what the Yii developers created for the starter template, we can be sure it is created in a best practice sort of way. Before we start modifying and changing any code to create our own custom applications, we need to understand how the base code working. By analyzing each of the sections of the base SiteController.php with links to the associating documentation, we’ll learn how things are working. Consider it a cheat sheet of sorts for working with controllers in Yii.
PHP Short Array Syntax
One thing to brush up on is your array syntax, specifically the shorthand form of arrays introduced in php5.4. In there is are two things you will see all the time in Yii, it is configurations, and arrays with short syntax. Almost everything in Yii is configured via an array in the shorthand bracket form.
Arrays can now be simply defined via square brackets.
$numbers = [9, 13, 15, 17];
$lunch = ['food' => 'Santa Fe Salad', 'drink' => 'Water With Lemon'];
instead of
$numbers = array(9, 13, 15, 17);
$lunch = array('food' => 'Santa Fe Salad', 'drink' => 'Water With Lemon');
While we’re on the topic of arrays, it’s worth mentioning that they now also support dereferencing, meaning you no longer need to assign the array to a temporary variable to access it.
$grub = explode(",", "chipoltle,five guys burger and fries,chillis,TGI Fridays");
echo $grub[3]; // TGI Fridays
Now you can simply do this:
echo explode(",", "chipoltle,five guys burger and fries,chillis,TGI Fridays")[3]; // TGI Fridays
PHP Namespaces
Namespaces are here, and they are in use across most modern codebases. Yii is no different, and makes use of namespaces as well. If you need to, you can brush up on namespaces at the official docs.
http://php.net/manual/en/language.namespaces.php
namespace frontendcontrollers;
use Yii;
use commonmodelsLoginForm;
use frontendmodelsPasswordResetRequestForm;
use frontendmodelsResetPasswordForm;
use frontendmodelsSignupForm;
use frontendmodelsContactForm;
use yiibaseInvalidParamException;
use yiiwebBadRequestHttpException;
use yiiwebController;
use yiifiltersVerbFilter;
use yiifiltersAccessControl;
The Yii Controller
When creating a controller in Yii, you extend the Controller class.
http://www.yiiframework.com/doc-2.0/guide-structure-controllers.html#controllers
class SiteController extends Controller { }
You now have a controller ready for use in Yii. We’re going to approach the way we review the controller based on the number of times various method calls happen in the generated code. First up, we have the render()
method which is called 7 times in the provided SiteController. Let’s see what this method does.
render()
http://www.yiiframework.com/doc-2.0/yii-base-controller.html#render%28%29-detail
The render method takes the name of the view to render as a string for the first parameter, and an array of key value pairs for the second parameter. Just like most MVC frameworks, the second parameter becomes the variables that hold the data to be accessed in the view. Note that that these values are not available in the layout file. A final tidbit to remember is that it is by the act of returning the render method that the output is actually generated. This is why calls to render look like this
return $this->render('index');
Redirection
Next up we have some utility type methods that get used a fair amount. To redirect a user to the home page, you can use return $this->goHome()
. To send a user to the page they were just visiting you would use return $this->goBack()
and to refresh the page you can use return $this->refresh()
, all quite handy and useful.
Flash Messages
There are several instances in the advanced application where flash messages are put to use. Flash messages are convenient messages that get displayed to the user for only one page load, they then automatically expire. We find these lines in the SiteController.php
to provide these messages.
$app->getSession()->setFlash('success', 'New password was saved.');
$app->getSession()->setFlash('error', 'Sorry, we are unable to reset password for email provided.');
$app->getSession()->setFlash('success', 'Check your email for further instructions.');
$app->session->setFlash('error', 'There was an error sending email.');
$app->session->setFlash('success', 'Thank you for contacting us. We will respond to you as soon as possible.');
An interesting thing to note is that some of the messages use the approach of $app->getSession()->setFlash()
while others are using $app->session->setFlash()
. It looks like two ways to do the same exact thing. Is one better than the other? I have no idea, test them out and see what you like best. This is the first part of using flash messages in Yii, which is to say you need to set the flash type, and flash message in the controller. You can see how that is done just above, i.e., setFlash() takes two parameters with the first being the type, and the second being the actual message. Now by practice, you typically fetch and render flash messages in your layout file. What’s really amazing is that all you have to do is simply have the code
<?= Alert::widget() ?>
present in your view file (or more commonly the main layout file) and your flash messages just simply work. No need to check for a flash message or anything like that. The alert widget is intelligent enough to simply display, remove, and otherwise manage alerts based on whether you called setFlash() in your controllers. That’s a really nice feature.
Calling on Models
Throughout this controller we can see that many new instances of models get created. Here are the ones we found.
new ResetPasswordForm($token);
new BadRequestHttpException($e->getMessage());
new PasswordResetRequestForm();
new SignupForm();
new ContactForm();
new LoginForm();
One note to remember is that it looks like the convention that is used here is that when new models are created, they get assigned to $model, no matter what type of model they actually are. Therefore, you need to pay attention to where you are to be sure you are dealing with the right object instance. This is probably quite obvious, but it’s something I noticed and figured it was worth mentioning. So what are the common uses of these model instances? Well, this scenario looks like it happens a bunch.
if ($model->load(Yii::$app->request->post()) && $model->validate())
If you are used to creating html forms by hand, then using native PHP to manage the submission process, you’ll know there are a bunch of steps to keep track of. Did the user provide data? Did they provide the right type of data? Did they submit the form? Did they try to hack the form? Is the data they submitted valid? The list goes on. With the simple line above, you pretty much take care of all those things in one shot. As long as you set up your models and forms correctly, like we did in the active form tutorial, things will just work. The slightly confusing thing with this is that the framework is certainly a “higher level” approach. It’s as if you’re pushing various buttons, and having faith that things will get taken care of. Or better yet, we can think of it like macros, or a set of related commands that get triggered when needed. The simple way of saying what the code above does is, “Did the user submit the form and is it valid?” The reality is that there are many more steps and logic involved than just this simple explanation.
Conclusion
Controllers in Yii are pretty straightforward, as they work like most other controllers might in a Model View Controller framework. In this episode we looked at some of the common methods that get used in the advanced template created when we first install Yii. It looks like this is a great way to learn Yii, i.e., build out small applications using the provided generation tools and then reverse engineer so to speak how those lines of code are actually working. As we get more comfortable with the framework, we start to see patterns, similarities of approach, and an overall sense of Zen.