After using Yii‘s command-line and Gii tools to build an application’s base structure, and then to create its Models and crud functionality, there’s still quite a bit of customizing to do (although Yii really does perform the bulk of the work). Previous posts discuss some of the common changes one makes to Models and Views at this point in the development stage; here I’ll discuss Controllers. I have personally found that I don’t make nearly the level of alterations to my auto-generated Controllers as I do to my Models and Views. This makes sense, as the Model should have the bulk of the code, the View is the interface the end user sees, and the Controller is largely an agent between the two (see my series on the MVC architecture for more on this).
(Note: In October 2010, I’ve updated this entire series to reflect changes in Yii since this series was written, and to take into account feedback provided through the comments. Some outdated material will be crossed out, but left in to reflect how things have changed since the series was begun in June 2009.)
Edit for Yii 1.1: The $defaultAction line is no longer present. Also, the names of some of two of the action methods have changed to match the new names of the corresponding View files: actionView() and actionIndex().
The Controller represents the actions a user takes with a site: views a specific record, updates a record, lists all the records, etc. A user request (i.e., the loading of a URL) is handled by the Yii application, then passed off to the corresponding Controller. It’s the Controller’s duty to perform any necessary work, likely involving the loading or manipulation of some Models, then pass data off to the View. As with any class definition, all of the tasks are performed within methods.
The first thing you’ll encounter within a Controller class is a variable called $layout:
public $layout='//layouts/column2';
As explained in the post on Views, this variable dictates which of the two built-in layouts—one column or two column—the Controller uses. You can change this value to change the layout for the entire Controller, or you can change $this->layout within any of the methods.
Another class variable, which used to be written into the class but now has to be added is:
public $defaultAction='admin';
As just stated, Controllers are the actions one takes, listing information, showing particular records, handling form submissions, and so forth. For each action there is a corresponding method in the Controller class: actionIndex(), actionView(), actionCreate(), etc. The above line dictates which method is called if not otherwise specified. So with that line, the URL www.example.com/index.php/employee calls the actionAdmin() method whereas www.example.com/index.php/employee/create calls actionCreate(). The default value, if you don’t use that line, is to call actionIndex().
Your Controllers should also have several non-action methods, including accessRules(). This method is a key part of the security picture, dictating who can do what. For the “what” options, you have your actions: list, show, create, update, and delete. Your “who” depends upon the situation, but to start there’s at least logged-in and not logged-in users, represented by * (anyone) and @ (logged-in users), accordingly. Depending upon the login system in place, you may also have levels of users, like admins. So the accessRules() method uses all this information and returns an array of values. The values are also arrays, indicating permissions (allow or deny), actions, and users:
public function accessRules()
{
return array(
array('allow', // allow all users to perform 'index' and 'view' actions
'actions'=>array('index','view'),
'users'=>array('*'),
),
array('allow', // allow authenticated user to perform 'create' and 'update' actions
'actions'=>array('create','update'),
'users'=>array('@'),
),
array('allow', // allow admin user to perform 'admin' and 'delete' actions
'actions'=>array('admin','delete'),
'users'=>array('admin'),
),
array('deny', // deny all users
'users'=>array('*'),
),
);
}That’s the default setting, where anyone can perform index and view actions, meaning that anyone can list all records or view individual records in the associated Model. The next section allows any logged-in user to perform create and update actions. Next, only administrators can perform admin and delete actions. Finally, a global deny for all users is added, to cover any situation that wasn’t explicitly defined. This is just a good security practice. Note that these rules just apply to this Controller; each Controller needs its own rules.
You’ll want to customize the rules to each Controller and situation. For example, I did a site with a subscription system, represented by a Contact Model. In that case, anyone had to be allowed to create new Contact records but only the admin was allowed to list or show Contact records. Generally, though, I think most Controllers would allow everyone to perform show and list actions.
You can also create more sophisticated conditionals to create permissions, but that will be a subject for another post. For example, on one project I did, any logged-in user could create certain types of content but they could only update and delete records that they themselves created. Or you could allow users show permission only on their own Contact record.
Finally, you may need to change your Controllers so that the retrieval of Model records is handled differently. There are a few methods that load records to be used in a View. Some of the methods, like actionView() and actionUpdate(), call a loadModel() method whose job it is to retrieve a single record. Other methods, like actionIndex() and actionAdmin() retrieve every Model record (using a different approach). In these methods, there are a couple of changes you may want to make. For starters, if the Model in question is related to another Model, as defined in the Model class’s relations() method (see my post on Models), you can invoke that relation when you retrieve the record(s). For example, this code will retrieve an employee, plus the department for that employee:
$model=Employee::model()->with('department')->findByPk((int)$id);You only want to do this if you’ll use the related records, of course.
You might also tweak the criteria applied to these methods, but that is a big topic. It basically involves adding WHERE SQL conditions to a query. I’ll address it in another post but you can also see the Yii documentation, of course.
So this makes the eighth post in a series on using the Yii framework, from start to kinda-finish. I’ve got a bunch of miscellaneous topics on the subject to post about, but I won’t write those up formally as part of this series. To find those, or any other posting on Yii, use the tags at right.
As always, thanks for reading and let me know if you have any comments or questions.
Larry

I was able to finish my first YII web application within a short time thanks to this tutorial.
Thanks Larry.
I’m glad to hear that. Congrats! Let me know if there’s anything in particular you’d like me to write about (I have a few Yii-specific topics lined up for December).
Very nice tutorial! Thank you!
You’re quite welcome. Thanks for the nice words and let me know if there’s anything specific you’d like me to write about.
Your tutorial is great and simple. Put me up and running with the basics of yii in no time. I would like to know if you plan to do a I18N tut?
Thanks!
Thanks for the nice words. I appreciate it! As for l18N, I’ll consider that. I’m writing one on FCKEditor and Yii now, and will be doing one on Zend_Lucene (search engine) and Yii soon.
Very well put together tutorial, thanks for the hard work.
A co-developer and I are just starting to explore Yii for an upcoming project, and this series was a great lead in for me
Thanks for the nice words. I’m glad it’s been helpful. Let me know if there’s anything specific you’d like me to write about.
Larry, I think it’d be usefull for me and probably others to see an example of creating a search form with all it’s controllers, safe sql queries to db and probably something else related to search in your future tutorials (not Lucene, but some kind of a simple search). Thanks again for your articles!
Thanks for your suggestions, Vic. I’ll see what I can do!
I’m new to yii and where this code $models=Department::model()->with(‘employees’)->findAll();
could be placed to show department name when listing employees?
Well, that’s the code for retrieving every department and employee, and it would go in the Controller, like in the actionList() method. The code for actually showing the department name would be in the View. In the list View, you would have a foreach loop going through the $models array, assigning each to $model. Then you could print out $model->name, which would be the department name.
Thanks this blog really help me lot to understand framework basics. Will move for next tutorial now… thank you…
Thanks for the nice words. Much appreciated!
Thanks for taking the time to write up this quality series. You’ve helped to get me up to speed very quickly, and Yii is now my favourite PHP framework too.
Thanks for the nice words. I’m glad the posts have been helpful and that you now like Yii, too!
Excellent tutorial. Thank you! I was up and limping within a couple of hours.
You’re quite welcome. Thanks for the nice words.
这个教程确实很新,看来要好好学习一下yii,谢了
(Roughly translates to “This course is truly very new, looks like must study well yii, thanked” according to Yahoo! Babel Fish).
You’re welcome!
Larry is there a screencast or video-tutorial about yii? I liked this one very much, and I understand everything but if I wanted to do a totally different webpage I wouldn’t know how to do it. What do you recommend me in order to enlarge my knowledge about this framework? Thank you!
Thanks for the nice words. On the Yii framework’s docs page, there’s a link to a screencast. Other than that, I would recommend the blog tutorial (also part of the Yii documentation), which walks through creating a reasonably-sophisticated application using Yii.
Dear Larry,
Thanks.. thank you very much….
Its an excellent tutorial on Yii…
Regards,
Rejeesh
Thank you for the nice words. Much appreciated.
Great tutorial.
Thank you very much.
You’re welcome. Thanks for saying so.
Here is my problem. I got code, theme, the works. It works! Why and how would I integrate that into yii? What do I get, that I don’t have now?
OK, simpler question. I got a bunch of classes. Where do I put them in yii?
Most people I talked to about this said I don’t need a framework. If so, who does?
In other words, what’s it in it for me?
I never understood agility.
I’m not into convincing people of things, especially those that don’t want to be convinced. From what it sounds like, you’ve got a system that works for you, so you’ve got no need to use a framework. Who does? Well, people that don’t have an established system already, for one. And people interested in learning new things and seeing if there’s not a better way out there, for two. When we stop learning, we shut down progress.
Thank you very much for writing this tutorial. It has been a great introduction to yii programming.
You’re quite welcome. Thanks for the feedback!
I have a plan to use yii framework for one of my project.
Thanks for this great informations.
You’re quite welcome. Thanks for the nice words and good luck with your project.
Thanks for the this great tutorial!
I’m starting in the PHP and Yii development and your posts guided me through the first steps.
Thanks for the nice words and for the feedback. I’m glad it was useful. Good luck with your Yii projects!
You have made a fine tutorial. The one thing that I don’t see is how I should add links to the main page, that might appear if an admin logs in that I could have appear where I could edit the employees and department table. Oh my first guess is it would be simple for me to drop in some links in the first page and some function like isAdmin to tell the page to display these links, but like so many other times I end up guessing I usually guess wrong. This MVC is too new for me to trust my guesses. Could I get a hint or two about how I should go about this. Sign me, need to be hit by a clue by four. thanks!
Thanks, Garry. Two ways of handling this: first, show or don’t show a login link. I normally don’t if only an admin would login (don’t want to confuse others); instead I just have the admin bookmark the login URL. Then this is something I put in my views/layouts/main.php script:
widget('UserMenu',array('visible'=>(!Yii::app()->user->isGuest))); ?>That says to show the UserMenu widget should the user not be a guest (i.e., be logged in). The UserMenu widget would then show admin-specific links. That’s pre-Yii 1.1 code, so I forget offhand if it’d be slightly different in Yii 1.1 or later.
Larry, thank you
You are most welcome!
It’s a dear experience to learn Yii from your tutorials [and comments!]. ..
Didn’t make it with the ‘foreach’ you suggested to show department’s name instead of its id. Should I try it in which View? index, view or _view? (I’m using Yii 1.1)
Again, thank you very much for this.
[I wish I could properly translate(pt-BR) a few lines from this Yii series and share it with my peps, you mind?]
Thank you very much for the nice words and do feel free to translate this so long as you give me credit, of course. You could also reference my books, if you’d like (I’ve written several on PHP, Web development, et al.) I’m glad you feel the content is worth sharing.
The foreach you’re referring to, I think, is on the basic View edits page. It goes in the Departments.php Model file.
Superb article on Yii startup. Good tutorial for beginners and ZCEs(myself) alike.
Thanks for the nice words! You’re a Zend Certified Engineer? What are your initial thoughts on Yii compared with the Zend Framework?
Very useful tutorials to understand the basics of this framework, which we are just starting to use. But here’s the thing, I am not doing the YII and php and database stuff, I am just responsible for tweaking the css that controls the look and feel.
I see that there are several copies of styles.css (in our case for detailview, listview and gridview. There are single copies of form.css, main.css, pager.css.
I’d love a tutorial (or pointer to one) that explains how to manage the css for a YII project. Thanks.
Thanks for your post. I don’t know of any tutorial on this particular subject but I find the CSS files pretty apparent to use (they’re well documented). Also, in my experience, normally designers use a new HTML design with its own CSS files, making those Yii-created CSS files irrelevant.
Sir…
i am beginner with YII.
i want to display record with different two tables.
display employee..
CHtml::encode($data->departmentId);
insted of departmentid i want to write name(from table department)
-BhavikChauhan
No problem. You just need to identify the relationship between the two in the two Model definitions, then select the employees with the departments in your Controller.
thanks for reply,,
your language is so easy..
really useful blog..
plz give me some more hint abt “identify the relationship”and “select the employees with the departments”..
Thanks for the nice words. Could you please clarify what your questions are?
I Have done…
thank you very much.
Hi,
Thanks for the nice tutorial! It really helped me in starting with Yii!
You’re welcome. Thanks for the feedback!
Dear Larry,
I have been following all ur 8 posts.
& a big thank u.
After reading some documentation(Yii definitive guide), I was trying to understand how all the pieces work together. But, it seemed to me as complex.
But, ur tutorial was a big help for me.
once again, thank u.
Thank you very much. Very nice of you to say. Good luck with your Yii work!
hi Larry,
i am your fan..
i need help..
i have 3 models(staff,clients,user)
mysite.com/staff/admin
mysite.com/clients/admin
mysite.com/user/admin
But, i want only one “admin-page” which manage all models.
e.g.mysite.com/admin
a panel having menu(or,link)with we can manage all models.
Regards,
Bhavik Chauhan
I’m not sure what you mean by manage, but if you just want to put all those admin pages onto one page, I’d create an actionAdmin() method in another Controller, load all three Models into three different variables and pass them to an admin page. On that admin page create three CGridViews, one for each Model.
hi,
thanks for reply,
i have created admin controller and its works..
thank u very much..
love yii and u also..
-Bhavik Chauhan
You’re welcome. Glad it’s working and thanks for the nice words.
Brilliant tutorial, looking forward to learning more about Yii.
Thnx!
Thanks and good luck!
This post really helped me in understanding each file in detail. Thanks sooo much for your time in explaining things to starters like me.
Thnx!
You’re quite welcome. Thanks for the feedback.
Tutorial about Zend Lucene and Yii sounds like a very good idea
I hope it will see light some day
I’m actually working on a more complicated use of Zend_Search_Lucene and Yii right now, so I should be doing a follow-up post on that subject. Thanks for the interest!
Hi Larry,
I’m new to PHP Frameworks. After doing some tutorials
in Zend, Symfony, Prado and some others, I only can say:
Yii is great and your tutorial is even better.
Thanks a lot for this nice work.
greetings uwe
Thanks. Very nice of you to say. I hope you continue to appreciate Yii!
Hi Larry,
Thanks a lot for this tutorial !!
I liked it a lot and it is the best tutorial on Yii I have
read so far.
Tons of thanks and best wishes, Keep writing.
Regards
Satyesh
You’re quite welcome. Thank you for the nice words and good luck with Yii!
Hi,
as mentioned above: great tutorial, thx!!!
I’ve got still one question…
I put the “$model=Employee::model()->with(‘department’)->findByPk((int)$id);” in my loadModel from EmployeeController, replacing “$model=Employee::model()->findByPk((int)$id);” with it.
But still the id of the department is shown. I would like to see the name of the department.
I’ve also tried to change the employee-view and _view to show “departmentName” (also tried “department”) in place of “departmentId”… won’t work.
In actionIndex and actionAdmin the code $model=Employee::… seems not to fit.
Because no other readers asked that before i assume some kind of blindness for me
I had the same confusion until I realized the last 2 articles in this series are the wrong way around. This is actually meant to be part 8 of 8 (Basic Controller Edits in Yii) not part 7. If you run through the last article (Basic View Edits in Yii) THEN this one it’s all in the tutorial and the $model=Employee::model()->with(‘department’)->findByPk((int)$id); now makes sense and not totally out of context.
Sorry about that. I must have messed up the order when I made my major site overhaul. Thanks for pointing it out and I’ve corrected the order.
got the entry for views/employee/_view.php
$data->department->name
in place of $data->departmendId
still searching how to pass the departmentName do the widget zii.widgets.CDetailView inside view.php…
‘department.name’ does it in view.php…
Thanks for your comments and kudos for figuring out your solution (and thanks for sharing). Let me know if you have any other questions. Larry
Larry, refer to item# 70, where do I put ‘department.name’ in view.php.
Wherever you want the department name to appear?
hi, thanks for your answer.
indeed, i have one question open.
i would like to search in the “manage employe” view for the department-name, not the id.
to display the name of the department i put department.name in the right place, but the colum is disabled for searching.
therefore i’ve tried to modify the model-search to get extra compares
$criteria->compare(‘department.name’,$this->department->name);
but the error :Trying to get property of non-object
appears.
what’s wrong?
Sorry for the delayed reply; I was busy transitioning the site over the weekend. I think I know what you’re trying to do and I believe I’ve done it before myself, but I don’t recall that code off the top of my head. I’ll see if I can find it.
In view detail page.
Yeah, that wasn’t really a question (I was asking). Just put the reference to department.name where ever in your view.php script you want the department name to appear.
i want to always show the department-name to the user, rather then the department-id (which is of no interest for the user).
i can “display” the department-name in every view.
my problem is that in “manage employees” i cannot search for the department-name.
below the column of the department-name, there is no search-form-field!
or does the widget not support relations like that?
if so, how can i modify the widget like that?
Hi Larry,
sorry for posting my question again. I thought the answer to Chakaphan would be adressed to me…
I’m wondering that my question is so rarely beeing discussed. I think it’s the normal way to present related table-entrys to the master-entry in form of its value rather than its ID.
i hope you find the code (in your head or archive
)
by the way, the new threaded-layout for the post’s (missing the # of the entry) is a bit of confusing.
Well, let me just get this straight: if you’re looking at the manage employee page, there’s a table of employees with a dynamic search at the top. And you’ve replaced the employee’s department ID with the department name but are trying to figure out how to search using that value? If that’s the case, it’s not surprising that you’re not seeing other discussions of it. That’s all accomplished using the GridView widget, which is relatively new to Yii (at least as a formal extension). So you’re talking about customizing the behavior of this widget, which uses an Ajax search, which is tied to a Model scenario. That’s not the most common or easy thing to implement. But I think I’ve done it before.
Funny you should mention the threaded comments. I actually thought it was more confusing previously, where threads were not indicated. I’ll see if I can get these to be numbered and threaded as I know others have referenced comment numbers in their comments.
Thanks for this very helpful introduction to the Yii framework. You make this stuff more accessible and thus it is a great place to start!
You’re welcome, Bob. Thanks for the nice words.
Great tutorial, but I think that post about relations in model and creating dropDown in post about View were a little complicated.
Okay. Thanks for the feedback.
It is an excellent tutorial, and I read the one of MVC too. Very enlightening. I only regret that you could have been a little bit less lazy, and in such way you could have done a larger tutorial. No, I’m kidding, many, many thanks for these useful small course.
Thanks! And for a minute there, I thought you were being serious about me being lazy!
Hi!
Yii tutorial is great. I appreciate overall tutorial.
I want to make 2 separate module, one for front end and another for backend (adminpanel) so that it can be reuse easily.
Can you give me idea how to manage it?
Thanks. I’d recommend you start with the manual’s section on modules.
Thanks
This is very good stuff. I have read a lot about frameworks, about choosing the right one, but this framework developers have a big problem in creating start up documentation. I have read a lot about yii and now when i decided to read more and get familiar with it i did not know from where to start. This post show me a lot of stuff and a very good starting point. Congratulations for Larry for putting all together in such a clear manner . Thanks a lot !
Thank you very much for the nice and detailed feedback! Good luck with your projects!
Hi Larry,
You have written the best tutorial and helped me a lot in creating my first web app using yii.
Thnak a lot.
Thanks for saying so! Good luck with Yii!
Excellent tutorial . Thanks Larry 谢谢
You’re welcome. Thanks for saying so!
Great stuff Larry!
Is it possible to write something about RBAC. This is one topic which has resources but some how lacks eloquence.
Thanks for the suggestion. I’ll see what I can do.