Yii 2 For Beginners
Yii 2 For Beginners
Bill Keck
This book is for sale at http://leanpub.com/yii2forbeginners
This is a Leanpub book. Leanpub empowers authors and publishers with the Lean
Publishing process. Lean Publishing is the act of publishing an in-progress ebook using
lightweight tools and many iterations to get reader feedback, pivot until you have the right
book and build traction once you do.
Contents
projects. Features
Some of the features you get with the install of the advanced template include:
If you don’t understand something in that list, don’t worry, we will be covering it in detail.
Just know that it really is amazing what Yii 2 does for you. But no matter how great a
framework is, you still need to do more to make it support a real application.
So to all the out-of-the-box features, will be adding:
Chapter One: Introduction 2
These are all things that your web application is likely to require, regardless of the type of
site it is. So, as you learn Yii 2 with this book, you will be building a template that you can
expand on for all of your future applications.
This book is perfect for beginning PHP programmers who are ready to move on to
framework development. The Yii 2 PHP framework is highly scalable and extensible, and
loaded with features. We introduce you to this wonderful framework and explain in detail
everything you need to know to get up and running. You will love Yii 2!
Advanced Php artisans will be able to zip through this book and get up and running quickly
on Yii 2, a phenomenal php framework. This will not only save them time on projects, but
also fully leverage the benefits of an open-source framework that has an entire community
behind it. And while I hope they get a lot out of it, I’m not really writing this book for them.
Instead, I’m writing it for the beginners. People who have some experience with PHP but
have not really jumped up to advanced object-oriented programming. I can tell you from
personal experience it’s not easy to learn OOP simply by online tutorials.
Typically you get examples of class Bear extending class Animals, which isn’t necessarily
bad for teaching the basic concept, but on the other hand, isn’t really going to give you a
feel for working with nested objects. Learning Yii 2 however, does give you hands on
experience with object-oriented programming with practical results. You end up with a
working website.
Not only do we get to leverage object-oriented programming to build a data-driven web
application, but we also get to use the latest version of PHP, which allows us to use cleaner
notation for arrays, namespaces, and some other efficiencies which are new to Yii in Yii 2.
And the really good news is that Yii 2 is now so strong as a framework, it is more accessible
to beginners than it ever has been before. And with it’s robust community support, it’s the
perfect framework to learn.
What Makes The Yii 2 Framework Special?
Programmers have to make decisions, it’s a fact that is at the heart of what programming is.
So one of the biggest decisions you will have to make as a programmer, and more likely, a
decision you will make as part of a team of programmers, is whether or not to use a
framework and if so, which one.
As to the question of using a PHP framework, there are so many benefits to doing so, it
becomes a no-brainer.
Chapter One: Introduction 3 Upsides
Downsides
There are a couple of downsides to using a framework that should be pointed out. First, all
the code that comprises the framework creates server overhead and this can be a real
problem. Luckily there are caching options available which will reduce the effects of this,
and for enterprise applications, you can use raw sql to minimize query time. So don’t let the
server overhead stop you from using a framework.
The other thing is that obviously when you are working with the framework, you are working
with a vast amount of code that you didn’t write and it takes time to figure out how it works.
Some of the framework code can be quite cryptic depending on your level of skill and
experience, so don’t expect to instantly understand everything. It’s not going to happen.
Of course you already knew that there was a learning curve, which is why you are reading
this book. And while it takes time to learn someone else’s code, which can be a pain, it
would be far more painful to have to write a custom framework from scratch. All things
considered, using a framework for enterprise development is a wise choice.
Ok, so the easy part is to figure out that utilizing a framework will help you develop a more
organized and robust project, but now comes the hard part. You have decide which
framework to use.
Anyway, we collectively researched everything we could find on the major PHP frameworks.
I personally read all of the documentation and we had long engineering discussions about
what we thought would work. You can’t imagine my frustration with the fact that I read all
this documentation and walked away from it feeling less knowledgeable than before I
started reading it.
Our team of programmers did have a preference however. They felt that Yii 1.1.14 was the
best choice. This was the version of Yii that was available at the time we were deciding this.
So the team adopted that framework and never looked back. They loved it.
I, on the other hand, remained frustrated. Since I was only a novice programmer, I really
struggled to learn it. I didn’t find it very intuitive. Especially after comparing it to other
frameworks, where they were trying so hard to make everything integrate beautifully, the
architecture of Yii just seemed ugly.
I got so frustrated at one point, that I started looking for another option.
Other Options
I would find some beautifully written documentation for a new framework and run it past the
team. I always got the same response. The team was happy with Yii.
They told me it might be difficult to learn, but it was easy to use, once you knew how it
worked. Because of that, I committed myself to learning it. It was slow going and a rough
ride. I wasn’t getting it. I was working through chapter 10 in a book on Yii 1.1.14, thinking I
would never really be able to build an application on my own in less than a hundred years.
Too many roads seemed to go nowhere.
Then a miracle happened.
Yii 2 Arrives
I found out about the Yii 2 alpha. I was curious to see what the differences were in Yii 2,
which had been 3 years in the making at that point. So I jumped in and to my utter and
complete surprise, I instantly connected with it. I understood the structures. I could write
code that actually worked! What a great feeling that was.
I have personally found Yii 2 to be the most intuitive and elegant of all the PHP frameworks
that I have studied. I have so much enthusiasm for it that I want to share it with every
programmer I know, and even those I don’t know, so it has motivated me to write this book.
With Yii 2, even as a beginner, I was able to stand up a working website that has a data-
driven user model, with both a frontend and a backend. Right out of the box, I get a working
user model, with forgot password functionality, which is also integrated with Bootstrap for
mobile-responsive design, without having to do any programming whatsoever. How cool is
that?
Although I was a beginning programmer when I was studying the PHP frameworks, I did
have experience working with databases and this is one area in my opinion where Yii 2
really shines.
Chapter One: Introduction 5 Gii
Yii 2 has a code generation tool called Gii. I pronounce that with a soft “g,” but I have no
idea if that is the right way to say it or not.
Anyway, Gii analyzes your database tables and automatically builds PHP models from
them. Not only that, but it analyzes the relationships between tables and automatically
generates the relational code into the models. For example, if you had a data structure with
30 tables, and half of them had a user_id column that was meant to reference id of the user
table, Gii would build the appropriate relationships for you, all in one go. Not only is this a
time-saver, but this also gives you very consistent code because it is always done the same
way and it helps you adopt this discipline.
It’s worth mentioning that other frameworks work exactly the opposite way. With them, you
build the model first, then do a migration to the database to create the table and
corresponding columns. So the big difference is that you are building your data structure
piecemeal as you go along, whereas in Yii 2 you have the option of having a more complete
data structure to begin with.
Both approaches work, however they represent drastically different workflows. In my
opinion, the migration/piecemeal approach to data structure only really works for a single
developer or a very small team working on a small project. The reason why I say this is that
although democracy is probably the best system politically, imagine a world where each
developer makes up their own data structure and implements it. How consistent would that
be? What if the right hand didn’t know what the left hand was doing? In larger teams, this is
a recipe for chaos. This is why enterprise development teams usually have a database
administrator, also known as the DB, and only they can create or delete data structure.
DB-First Approach
Since Yii 2 allows you to essentially import the models from the data structure, you can start
your project by really thinking through your data structure. Overall I like to avoid talking
about too much theory because the time is better spent working through hands-on
examples, but I think it’s worth taking a moment to think about what a well thought-out data
structure really means.
Whether you are a single developer or part of an enterprise level team, you are essentially
being given the same task, the same overall mission. You have to serve data from a
database into a browser friendly format, typically using PHP, HTML, and Javascript. We use
a PHP framework to make this task easier, and by saying that, we are admitting upfront that
it’s not an easy task. Why is that?
The database is a very reliable and consistent piece of software, which allows us to create a
relational data structure.
MySql
Throughout this book we use Mysql as the database, which, in addition to being free, is
capable of powering enterprise data for web applications.
Chapter One: Introduction 6
Because of the structure of the database, with its indexes and primary keys, a database can
serve data very efficiently. In the simplest terms, this means it is very fast. It’s also very
deep. It can hold millions of records, which can be retrieved, if structured properly, in
milliseconds.
Another key aspect of the database is that it allows us to structure the data in such a way as
to connect things like the user’s address and their username as if they were one record, but
hold them in separate tables as separate records. The more you can break down the data
structure into discrete components like that, the more powerful it is. This is called
normalization of data.
The problem is that the more refined the database is, the more effectively normalized it is,
the more complex it is to deal with in PHP. You end up having to connect a lot of PHP
models together to represent the data correctly.
Now this might be getting too heavy on theory for a beginning book, so we won’t take this
much further for now, but the point is to understand the nature of the problem that the
framework helps to solve. The easier it is for you to connect the models via the framework,
the more power you derive from your database.
Improved Workflow
In my opinion, Yii 2 stands alone in how it helps you connect the models to the database,
leading to improved workflow, efficiency, and overall design capabilities. It frees you to build
a detail-rich data structure that will ultimately result in the end user being more engaged. I
believe that Yii 2 does this more efficiently and deeply than any of the other PHP
frameworks, that is why I’m so committed to it and so interested in sharing it.
which has 200 videos on PHP. Great for an introduction, but not much more. I followed that
up with a quick read of Richard Reese’s book on Java, which helped me understand object-
oriented programming better, since everything in Java involves a class. Also, when I looked
at PHP again, it seemed simpler. I also went through the basics at:
W3 Schools¹
W3schools.com is a great learning resource. You can play with the code online at that site.
And then of course there is Php.net² itself which is where we find all the docs for the
language and sometimes very complicated examples. I learned a lot there and got lost a lot
too, that’s the way it goes. Try it, you’ll see what I mean.
At any rate, to be able to work with Yii 2, you should understand the basics about objects,
arrays, and control structures like foreach loops. You should know the components of a
class, properties and methods, etc. Take a look at:
OOP for Beginners³
You should be able to get through that tutorial very easily. If not, go back and study it before
trying to tackle Yii 2. Also, Yii 2 uses PHP 5.4 and above, which supports new array syntax
and namespaces, both of which will be utilized extensively.
If you are light on programming experience, but full of enthusiasm, you should do well, as
long as you are willing to do the work and are patient. At any point, if you don’t understand
something, you can stop and take the time to research it on Google⁴ or stackoverflow⁵ or
PHP.net⁶. PHP is a well-documented and well-supported language, used by countless
programmers who will try to help you.
Also, I took a lot of care to label the sub-sections of this book, so you can easily find what
you are looking for, if you need to refer back to it. Many times you will want to return to a
section to reference something and I’ve done my best to make that as intuitive as possible.
Sometimes the most difficult part of a project is setting up the development environment.
Because I use it personally, we will be using xampp up on a windows machine. Xampp
includes PHP, Mysql, Apache, and PhpMyadmin, so it’s perfect to create a development
environment for project. It’s also free.
Download Xammp⁷
Install Video for Xammp and PhpMyadmihn⁸
Any alternative that will let you run those programs is fine, you do not need Xammp to follow
this book. On the other hand, it’s pretty easy to get up and running with Xammp, one reason
why I use it. The tricky part is setting up environment variables on a Windows machine, but
that is well documented and I will provide download and setup links for your convenience,
so you can check those out if you need to.
Even though everything for Mysql can be done in PhpMyadmin, I also recommend setting
up Mysql workbench. Workbench’s EER (Enhanced Entity Relationship) Diagrams help you
see the relationships and make creating tables and foreign keys a snap. We will use photos
of Mysql Workbench to show you table structure later in the book.
Download Mysql Workbench⁹
You should familiarize yourself with how to create a database, how sync a diagram model to
a database, and obviously how to create tables and columns. To build a database-driven
application, you need a basic understanding of sql, nothing too deep, but you should know
basic queries work and the concept of joining tables for queries. And since we use MySql,
you need to be familiar with it. If any of that is new to you, the good news is that you can
google up some tutorials and find everything you need for free. W3 Resources MySql
tutorial¹⁰ are a great reference.
For my IDE, I use PhpED. IDE stands for Integrated Development Environment, and helps
you organize projects and code. Most developers use some form of IDE as opposed to just
a text editor. I’m recommending Eclipse or Netbeans for this project, however, because both
are free whereas PhpEd is a paid IDE. In order to install Eclipse, you will have to install the
Java sdk first.
Download Eclipse¹¹
Download Netbeans¹²
You will also need to install Composer, which we will do after installing xampp, which
means after PHP is installed. In order to run Composer, you must first enable curl in your
PHP build. You will also need to set an environment variable for it if you are using windows.
Download composer¹³
⁷https://www.apachefriends.org/index.html
⁸https://www.youtube.com/watch?v=dV3JjLhi4Jk
⁹http://dev.mysql.com/downloads/workbench/
¹⁰http://www.w3resource.com/mysql/mysql-tutorials.php
¹¹https://www.eclipse.org/
¹²https://netbeans.org/
¹³https://getcomposer.org/download/
Chapter One: Introduction 9
Enable Curl¹⁴
I also recommend using git, which provides version control. Version control is a handy way
of saving your work so you can step backward easily if you need to. When you are dealing
with a large number of files that are constantly being updated, this is a great help. Git also
protects you in a team environment from someone overwriting your work because you can
simply step back to a previous version.
Download Git¹⁵
Lastly, I recommend console2 for Windows users, which is a command line tool that is a
little prettier than the standard windows prompt. This makes it easier on the eyes and just a
little easier to work with.
Download Console 2¹⁶
In order to get your development environment working with Yii 2, you will need to add both a
vhost entry into Apache and a local host entry into your hosts file. We will go through each
step for that in detail.
Like I said earlier, if you prefer to use different tools or, for example, a linux machine for
devel, that is your choice.
I will provide reference pages for installation, but for beginners, this may prove to be
difficult. You can use the installation of the development environment as one of the tests to
see if you are ready to tackle Yii 2. Just don’t give up easily. If it doesn’t go well, you can
always get help from a more experienced programmer.
Tip
Also, and this is a tip for beginners, almost everything you will go through as a
programmer has been gone through by other programmers before you and this is
especially true for configuration errors. Don’t be afraid to use Google¹⁷ for help in
troubleshooting setup. You will end up using it more often than not.
Once you’ve got everything up and running, spend a little time learning your way around the
tools. It will make your efforts developing in Yii 2 go a lot smoother.
Errata
Although I have poured over every line of code in this book at least a hundred times and
built the examples from scratch twice just to make sure I could follow the directions,
mistakes are bound to happen, such is the nature of technical writing.
¹⁴http://www.tomjepson.co.uk/enabling-curl-in-php-php-ini-wamp-xamp-ubuntu/
¹⁵http://git-scm.com/downloads
¹⁶http://sourceforge.net/projects/console/
¹⁷http://www.google.com
Chapter One: Introduction 10
Formatting Tip
In certain cases, I had to format my code using two lines where one would be
appropriate, in order to avoid line breaks from the wordwrapping in PDF and other
formats. The wordwrapping in PDF causes special characters to appear, which
break the code, so I had to avoid that the best I could. As a result, I’m not
recommending you follow the code examples as an example of style. I would
recommend following the PSR-2 Guide, available here: PSR-2 Coding Style
Guide¹⁸
You can format your code with a formatter at Php Formatter¹⁹, if you want to make it more
readable. Obviously be careful not to break the code.
Summary
I know it can be a little intimidating at first, especially when you realize that Yii 2 is not just
some trivial set of library files that you can master in a few days, but hang in there and be
patient. We are
¹⁸https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md
¹⁹http://beta.phpformatter.com/
²⁰http://yii2framework.wordpress.com/
Chapter One: Introduction 11
See chapter 1 for links to free downloads on the above tools, if you have not already installed them.
If you are not at this stage, you need to go back to the introduction and make sure you have
all the required tools installed.
Hate Windows or Xammp? Not a problem. Obviously, you do not need to follow on
Windows to read this book. If you are working directly on a LAMP stack or something else,
you just need to know the linux commands. I don’t provide them here, but you can easily
google them. Just to reiterate, these instructions are xammp on Windows, but there are only
minor differences, so you should be able to figure it out if you are using a different system.
For your convenience, I’m also listing a link to the Yii 2 guide for Advanced App
installation: Yii 2 Advanced App Setup²¹
Ok, let’s get started:
²¹http://www.yiiframework.com/doc-2.0/guide-tutorial-advanced-app.html
Go to the directory that stores the project roots, in my case it’s \var\www and create a new
folder named yii2build. So you should have a \var\www\yii2build folder.
Notepad will open. Select file open and the path to vhosts, in my case:
C://xampp/apache/conf/extra/
select all Files for file types:
Chapter Two: Yii 2 Advanced Template Installation 14
Notepad All File Types
Then select:
httpd-vhosts.conf
NameVirtualHost *
<VirtualHost yii2build.com>
DocumentRoot "C:\var\www\yii2build\frontend\web"
ServerName localhost
ServerAlias www.yii2build.com
</VirtualHost>
<VirtualHost yii2build.com>
DocumentRoot "C:\var\www\yii2build\backend\web"
ServerName backend.yii2build.com
ServerAlias www.yii2build.com
</VirtualHost>
127.0.0.1 backend.yii2build.com
Chapter Two: Yii 2 Advanced Template Installation 15 Step 4 - Restart Apache
Note that we are running MySql as a service, but not apache. If you did not set up xammp
yet, obviously, you will need to do so before continuing. I recommend that you have all your
tools set up and configured before proceeding and that you take some time to familiarize
yourself with them. I included a xammp video link in chapter 1 that you can refer to as well.
<?PHP
phpinfo();
?>
yii2build/frontend/web/index.php
yii2build/backend/web/index.php
Folder Structure for Test Host
If you type yii2build.com and backend.yii2build into your browser, they should both return
the phpinfo output, which also conveniently gives you a chance to check to see if you have
PHP 5.4 or greater, which is what you need to run Yii 2.
Chapter Two: Yii 2 Advanced Template Installation 17
Php Info
If the page does not resolve, go back and check your hosts file and/or your httpd-
vhosts.conf. Make sure to restart Apache after making changes. Make sure you have local
host entries for the domain, yii2build. Refer back to step 2 and 3 if necessary.
At this point, you should be able to see that your host entries are correct and that you are
running the correct version of Php. This is independent of Yii 2 and composer, so
successfully implementing step 5 gives you a test point for the first part of our setup.
If this all checks out, you have successfully tested your host entries and you should delete
these test web folders and their contents. Obviously leave the root folder, yii2build, in place.
Chapter Two: Yii 2 Advanced Template Installation 18 Step 6 - Find Command Line
Path
From the windows command line, go to your yii2build folder. First cd\, then cd\var\www\
yii2build if you have yii2build in \var\www. I know this can be a little confusing, so let me just
reiterate. \var is a folder on my c: drive, within that is a folder named www, and inside www,
I created a folder named yii2build, where the project will reside.
You don’t have to follow this exactly, you just need to know where your root folder is and
make sure you have the appropriate host entries.
composer self-update
If you get an error message, check your installation of composer. If you don’t have
composer installed, Google it for instructions on installation into windows and xampp.
You will also need to make sure the following plugin is installed into composer. Issue the
following command from the same directory where you did self-update:
composer global require "fxp/composer-asset-plugin:1.0.*@dev"
Chapter Two: Yii 2 Advanced Template Installation 19
Asset Plugin
If the above plugin is not installed, composer will not act correctly. The good news is that as
long as you have composer working, the plugin is easy to install with the one simple
command from above.
Tip
I checked the Yii 2 Guide and the latest recommended version of the plugin is
“fxp/composer-asset-plugin:1.0.0-beta3” If for whatever reason, that version of the
plugin is out of date, use Google to find the correct version. You can also try @dev,
which should work, but you never know. I will do my best to keep the book up-to-
date, but these are the kinds of things that will be hard to keep track of. When
going through setup in programming books, these are common problems, so this is
just a heads up.
Tip
The directions in the guide are slightly different in that you can set the root folder by
the install. I don’t like to do it this way which is why I’m recommending that you
follow these directions, which has an extra step, but allows you to check to see if
the host entries are working before you install Yii 2.
Folder
Using windows explorer, open this folder, and you will see all the framework files. Select all
files and copy them one level up to the root yii2build folder, then delete the yii2-app-
advanced folder. So, just to make it perfectly clear, now you should have the root folder, in
this case yii2build, with the framework files inside it on the first level. There should be no
yii2-app-advanced folder at this point. It should look like this after you deleted it:
App Folders
It will ask you if you wish to initialize in development or production. Select 0 for
development. Then confirm Yes.
Chapter Two: Yii 2 Advanced Template Installation 21
Devel Setup
'db' => [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=yii2build',
'username' => 'root',
'password' => 'yourpassword',
'charset' => 'utf8',
],
Obviously substitute your actual password into the config. Don’t forget to
Back to the command line. You might have a different path, if so, it should be path to\rootfolder\
yii2build>yii migrate. In my setup, it’s \var\www\yii2build, run yii migrate. Looks like:
\var\www\yii2build>yii migrate
Migrate
Confirm yes.
Confirm Yes
This will build the necessary tables in your database. You can check PhpMyadmin and you
should have the following tables in the yii2build:
migrations
user
Chapter Two: Yii 2 Advanced Template Installation 23
Migrate Success
Commit in Git
You have to stage changes before committing. You may have to unlock index or click
continue from a pop up dialog box. You will also need to enter a comment before
committing.
To view the repository from the repository menu, select visualize all branch history. This will
show you the current master branch and it’s history, great for tracking your changes and
stepping back if you need to. Version control is very important on a project of this size. It is
unlikely that you could get through the project without it, so don’t skip this step. Remember
to save, at minimum, a commit at the end of every chapter of this book. You should probably
do it more often than that.
Chapter Two: Yii 2 Advanced Template Installation 24 Step 15 - Confirm App Is
Working
Confirm the advanced application works by typing yii2build.com into your browser. You
should get the advanced app template which will allow you to register a user and login with
that user.
You should register a user and login to test that the application is working. Once you create
a user, you can test the backend as well.
Yii 2 Build
Since no access control is differentiated at this point from frontend to backend, you can log
into backend by going to backend.yii2build.com and logging in. In both cases, login will
simply return the index page and in the nav bar display the user name and the logout link.
Trouble-Shooting
If it’s not resolving, then check your hosts file and httpd-vhosts.conf. Make sure Apache is
running in xampp and has been restarted after making changes to the host files. Make sure
your version of PHP is 5.4 or higher, that is required for Yii 2.
If you are seeing a directory tree, instead of the homepage, you did not successfully run the
init, go back to step 10. If you can see the homepage, but get a DB error when you try to
register, make sure in PhpMyAdmin that the yii2build database exists, that you have the
correct password for it, and that you have entered those settings in yii2build\common\
config\main-local.php. Also make sure Mysql is running in xammp, see photo in step 4 for
reference.
If you still can’t get it to work, start over or at least from the point where you confirmed host
entries are working and that you are running PHP 5.4.
Chapter Two: Yii 2 Advanced Template Installation 25 Summary
Congratulations, the hardest part of the book is over. Hopefully, this went smoothly for you.
If you did have problems with setup, repeat the steps until you get it right. If you are sure
everything is right, but it’s still not working, consult with the individual docs of the
components to see if something changed since this book was written. Google is typically
very effective for this, when called to serve.
In the next chapters, we will begin working our way into development with Yii 2. We start
with a brief tour of the MVC architecture, but we don’t spend a lot of time on theory, unless
we can use it to code. Instead, we dive in quickly in the subsequent chapters.
I’ve learned through personal experience that explanations of the broader concepts work
better when they are coupled with practical implementation, which is why I learned almost
nothing from most of my online OOP lessons, just vague impressions of interfaces and
class inheritances. Not to worry. One of the great things about Yii 2 is that it pulls together
so many of the principles and concepts of OOP in such an intuitive way, that you will
understand the theories as you go. At least you will see them demonstrated.
directory Structure
You can see the application is divided between backend, common, console, environments,
frontend, tests, and vendor folders.
MVC Pattern
Yii 2 follows the MVC design pattern, where M stands for Model, V stands for view, and C
stands for controller. We’re going to discuss this briefly, but just for an overview. The best
way to understand it is to work with the code and the directory structures directly, which we
will do shortly. Here is another view of the structure with some of the folders open:
Chapter Three: Welcome to the MVC 27
App Structure
You can see that the backend and frontend folders have folders named models, controllers,
and views. The common folder has models, but no controller or views. You might want to
take a few moments to look in all the folders to see what is there.
In Yii 2, the model is responsible for entering and retrieving data from the database. This
includes any relationships that it needs from connected models, for example, a user and a
user profile.
When a web request comes in, the controller typically routes it to the model, where it
communicates with the database, then returns its results for display in the view. This allows
for a separation of logic and presentation. You get fat models full of php, skinny controllers
that mostly just do routing, and views that are light on PHP and deal more with HTML and
javascript for presentation.
That’s probably all we need to say about it as abstract theory. It works well and we will see
how Yii 2 implements this pattern and how easy it is to understand in practice.
Chapter Three: Welcome to the MVC 28 Index.php
There are exactly two points that should be accessible from the web in this application. Both
backend and frontend have a folder named web within them and within that folder is file
named index.php. If you recall, we set our hosts entries to look for this file, so that
backend.yiibuild.com goes to the backend folder version and yiibuild.com goes to the
frontend one. Each of these files is identical and looks like this:
<?php
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'dev');
require(__DIR__ . '/../../vendor/autoload.php');
require(__DIR__ . '/../../vendor/yiisoft/yii2/Yii.php');
require(__DIR__ . '/../../common/config/bootstrap.php');
require(__DIR__ . '/../config/bootstrap.php');
$config = yii\helpers\ArrayHelper::merge(
require(__DIR__ . '/../../common/config/main.php'),
require(__DIR__ . '/../../common/config/main-local.php'),
require(__DIR__ . '/../config/main.php'),
require(__DIR__ . '/../config/main-local.php')
);
The first two lines check to see if the constants exist or define it for debug and dev.
Then come the require statements for files necessary to run the app, including the autoloader:
require(__DIR__ . '/../../vendor/autoload.php');
require(__DIR__ . '/../../vendor/yiisoft/yii2/Yii.php');
require(__DIR__ . '/../../common/config/bootstrap.php');
require(__DIR__ . '/../config/bootstrap.php');
$config is set by the ArrayHelper merge method and requires the files specified in the array:
Chapter Three: Welcome to the MVC 29
$config = yii\helpers\ArrayHelper::merge(
require(__DIR__ . '/../../common/config/main.php'),
require(__DIR__ . '/../../common/config/main-local.php'),
require(__DIR__ . '/../config/main.php'),
require(__DIR__ . '/../config/main-local.php')
);
You can see it goes up 2 directories to find the common folder for that config. Then it goes
up one directory to find the configure for frontend or backend, depending on which
index.php file is doing the calling.
Then finally, we create a new instance of the application model, using the config for a
dependency injection, which now becomes the container for the application. Then we fire off
it’s run method:
Routing
So let’s get back to index.php, the file acts as a doorway to the application, creating the
instance of it. When we are typing in a url for our application, we will always be calling
index.php. Yii 2 handles all the routing for us, so when we want to get to the site home page
for example, the route looks like this:
yiibuild.com/index.php?r=site/index
That’s not very pretty. You can set the urls to be pretty in the config, which helps their
search engine friendliness and you can also eliminate the need to show index.php in the url,
but we won’t be doing this with our project. By waiting on that, we eliminate having to debug
the url or apache, if a problem with the page should arise.
After we’re done, you can easily consult with the Yii 2 guide to set pretty urls if you wish:
Chapter Three: Welcome to the MVC 30
Pretty Urls²²
Ok, let’s get back to routing:
The r=site/index tells Yii 2 that we want the site controller and the index action. If an
incoming request does not specify a route, which happens when someone just types in
yiibuild.com for example, then, the route specified by yii\webApplication::$defaultRoute will
be used. The default is set to site/index, which, as we mentioned above, specifies the site
controller and the index action.
If no action is specified, the controller assumes you want the index action.
Example: yiibuild.com/index.php?r=site
This returns the index action of the site controller. In most cases, the action will render an
associated view, a view with the same name as the controller action. Common actions and
views are index, view, create, update, delete.
We often refer to the create, read, update, and delete actions as CRUD.
Using Gii
We will be using Yii 2’s built-in rock star module, Gii, the all-time greatest code generation
tool ever built, to help us make a lot of CRUD. And when we use Gii to create CRUD, we
are often creating the controller at the same time, so we can generically expect the CRUD
to include the controller. Don’t worry if this is a little fuzzy now, it will make a lot more sense
later when we are creating our files. And yes, I worship Gii, and I’m pretty sure by the time
we’re done, you will too.
If you look in the views folder under frontend, you can see a folder named site, which has
an index.php file in it. This is the view page rendered by the index action of the site
controller. The site controller itself is located at frontend\controllersSiteController.php
Browse around the folders. Inside of backend, you will find controllers, models, views. You
will find the same in the frontend folder. In the common folder, you see config, mail, and
models. Overall, you can see the consistency in the naming conventions and they make Yii
2 easy to understand from an MVC point of view.
So obviously, this is quite different from simple web applications where you would have a url
like samplesite.com/about.php. If you are tempted to skip learning Yii 2 because your
current application requirements do not need to be so robust, keep in mind that over time,
applications requirements tend to grow.
If today your client doesn’t need a form with robust validation rules, it doesn’t mean that he
won’t need it tomorrow.
²²http://www.yiiframework.com/doc-2.0/guide-runtime-url-handling.html#customizing-urls
Also, with Yii 2, you get the frontend framework Bootstrap integrated out-of-the-box. If you
are unfamiliar with Twitter’s Bootstrap framework, I recommend you check it out, it has fast
become the industry standard. You can check it out here:
Get Bootstrap²³
You don’t need to download or do anything though, because like I said before, Yii 2 comes
with it already integrated as a default. That means you get a platform-responsive css that
scales to the device, allowing you to create mobile-first design from the start. And that, my
friends, is just the cherry on top of the cake!
One day your client wants a nothing website and the next day he wants mobile css. You
can deliver because you are already there. Anyway, I’m not trying to sound like a salesman.
I truly love this platform and it shows.
In our previous projects, we might have created header and footer files that we could
require in our individual pages, simple but inefficient. What if you forgot to include the file or
made a typo to a previous version? What about theming and other advanced approaches?
Yii 2 has a cool solution for this by using layouts. Views are injected into the layout and
there are methods available at the site config level or the controller level to specify which
layout to use. A default layout is already there, so you don’t need to do anything if you don’t
want to change it. You can also use nested layouts, if you feel that is necessary.
For our purposes, we are going to stick with the default layout, which is located at fron tend\
views\layouts\main.php. The only thing we are going to note at this time is that this tag in
the middle of the page:
<?= $content ?>
This is where the view page gets injected. So now you know the header is above $content
and footer is below it. Don’t worry, we will be making changes to this file and will be coming
back to it later in the project.
Debugger
One other thing we should mention is the rather conspicuous Yii Debugger tool that sits at
the bottom of the page, when you view the advanced template in the browser. This has
many useful utilities, such as
• Configuration
• Logs
²³http://getbootstrap.com/
Chapter Three: Welcome to the MVC 32
• Profiling
• Database
• Asset Bundles
• Mail
We don’t spend time on it in this book, but in your programming workflow, this is incredibly
handy. You can check to see which queries are being executed, how long they took and
many other helpful details about how your application is working. Take some time to
familiarize yourself with it. You’ll get it just by playing with it. If you are not using it, you can
click the arrow at the bottom right of the browser and hide it.
Summary
As we said in the introduction, Yii 2 is not a trivial implementation of the MVC pattern. It’s an
extensive framework that is robust and easy to use, once you are familiar with it. The
learning curve for beginners can be steep, but stick with it, it’s worth it.
I’m going to do everything I can to help you along, method by method. It will be a little fuzzy
at first, but as we go along, and we get deeper into the project, it will begin to make sense,
and the pieces will start to fit.
So, what shall we build as our sample application? What would demonstrate useful features
that many projects would share? And can we actually use anything we build here in a real
project?
Asking myself those questions led me to conclude that this book should build an application
template named Yii 2 Build. Now wait a minute, isn’t the advanced application installation
itself a template? Yes it is. But we are going to take things a little further.
We are going to create a basic RBAC system with UI that allows us to set roles, statuses,
and user types to control access to both the frontend and backend of the application. We
are going to build an upgrade controller, so that if we want a paid area of our application, we
can enforce that rule.
We are also going to create a user profile model that can be extended or modified to suit
your needs, but one that shows us how to control access to views that should be private to
the user who owns them.
Our goal will be to create a working application that you can use as a model for future
projects, one that is much further along in development than the advanced application
template. As cool as the out-of-the-box template is, we can do a lot more, and learn the ins
and outs of the framework along the way. Let’s get to it and let’s have some fun!
Also note, at the end of chapters, you will see:
Chapter Three: Welcome to the MVC 33
Commit To Git
This is a reminder to commit your changes to version control. No need to do it now, since
we didn’t change anything. But stay on top of that, it will be a big help to you if you need to
step backwards for any reason.
powerful approach to authorization. It will take us through multiple model setups and step us
into relationships. Most of the code is really, really simple.
You’ll also see how easy it is to create all this with Gii, Yii’s built-in code generator. You’ve
probably heard about Gii and it is an amazing tool, but we’re not ready to use that just yet,
we will come back to it next chapter.
Instead, we just need to start with some modifications to what we already have. The user
table and User model were created for us automatically by the advanced application when
we installed it, and while it’s close to what we need, we have to make some important
changes.
Also make sure the created_at and updated_at fields are of the type DATETIME. For some
reason the initial build is set to save as int for those fields, but we are going to work with
behaviors on the User model to make sure they are saved correctly as DATETIME.
Don’t forget to sync to the database:
Chapter Four: Modifying the User Model 37
Synchronize to Database
Once we make the change, don’t bother testing the site, nothing is going to work. We are
going to have to change the User model before we test the site again.
Tip
Before we start, a quick tip in case you didn’t notice. Only view files have closing ?
> tags. Do not include closing ?> tags in your models and controllers.
<?php
namespace common\models;
use Yii;
use yii\base\NotSupportedException;
use yii\behaviors\TimestampBehavior;
use yii\db\ActiveRecord;
use yii\db\Expression;
use yii\web\IdentityInterface;
use yii\helpers\Security;
/**
* User model
*
* @property integer $id
* @property string $username
* @property string $password_hash
* @property string $password_reset_token
* @property string $email
* @property string $auth_key
* @property integer $role_id
* @property integer $status_id
* @proprty integer $user_type_id
* @property integer $created_at
* @property integer $updated_at
* @property string $password write-only password
*/
class User extends ActiveRecord implements IdentityInterface
{
/**
* behaviors
*/
/**
* validation rules
*/
];
}
/**
* @findIdentity
*/
/**
* @findIdentityByAccessToken
*/
/**
* Finds user by username
* broken into 2 lines to avoid wordwrapping * @param string $username
* @return static|null
*/
self::STATUS_ACTIVE]);
}
/**
* Finds user by password reset token
*
* @param string $token password reset token
* @return static|null
*/
return static::findOne([
'password_reset_token' => $token,
'status_id' => self::STATUS_ACTIVE,
]);
}
/**
Chapter Four: Modifying the User Model 42
* @getId
*/
/**
* @getAuthKey
*/
/**
* @validateAuthKey
*/
public function validateAuthKey($authKey)
{
return $this->getAuthKey() === $authKey;
}
/**
* Validates password
*
* @param string $password password to validate
* @return boolean if password provided is valid for current user
*/
/**
* Generates password hash from password and sets it to the model
*
* @param string $password
*/
/**
* Generates "remember me" authentication key
*/
/**
* Generates new password reset token
* broken into 2 lines to avoid wordwrapping
*/
}
Chapter Four: Modifying the User Model 44
/**
* Removes password reset token
*/
Tip
The code for User.php is not formatted exactly like you would want it in your file.
There are a few instances of two lines being used when there should be one. The
reason is that PDF and other formats break the line with a wordwrap and insert
special characters that mess up the code, so I have to proactively format the code
so the line doesn’t break. It doesn’t always look pretty, but at least the code will
function. You should find these instances and convert them to a single line by
removing the white space. The public static function findByUsername($username)
and public function generatePasswordResetToken() have the extra line in the body
of the function. If you wish, you can use phpformatter.com²⁴ to format your code,
it’s a handy tool.
• Role
• Status
• UserType
• Profile
• Gender
In the next chapter, we are going to create the database tables for these models, and then
the actual models themselves.
A lot of programmers will create database structure one table at a time and feel their way
forward. Typically they use migrations to accomplish this. Other than the initial migration
that created the original user model, we are not using migrations.
I’m a big believer in thinking through the data structure and creating it all at once, as
opposed to an adhoc approach. That’s not to say you can’t refine and change as you go,
but a little forethought goes a long way. You are of course free to use migrations if you wish,
especially if you are comfortable using them. See the Yii 2 Guide for details:
Yii 2 Migrations²⁵
Constants
One thing that might pop out at you from that list of new models, especially with Role,
Status, and UserType, is that these data structures could alternatively be handled by
constants. While that would be probably easier to implement, I favor putting things like
status values in the DB. The reason for this is that I can then create an Admin UI that allows
me to update and create new values, without having to go into the code.
Take Role for example. Let’s say that you have a role called admin, which grants access to
the backend. It has a value of 20. You set up your constant as follows:
const ROLE_ADMIN_VALUE = 20;
But then you decide that you need an even more expansive role, let’s call it SuperUser. You
would have to go back to the code, find every instance where you are using the constant,
create another constant, and add it to all the supporting methods that will populate the
names of the Roles for dropdown lists, etc. It’s easy enough to do, but in my opinion, not the
best way.
²⁵http://www.yiiframework.com/doc-2.0/guide-db-migrations.html
Chapter Four: Modifying the User Model 46
I would rather have UI in the backend that allows me to simply add a DB record that defines
the new role and gives it a value. Then, if I have coded my methods correctly, I have it
available to me everywhere. As we progress in this book, you will see how this plays out.
Now if you check under our class declaration, you will see we left one constant in
place: const STATUS_ACTIVE = 10;
I kept the constant there for a good reason, even though it violates DRY (as far as for what
we are going to build), because the status value active is vital to the registration and recover
password system. I leave the constant in place, so that we can get the site up and running.
The site needs this value to work and it’s one of those cases where I’m willing to duplicate
for ease of use. You can replace this later with a method if you choose to do so, though that
is not covered in this book. It’s a trivial matter in later stages to make the change if you
wish.
Identity Interface
Going back to the class declaration for a moment:
This is Yii 2 class structure that I didn’t write, but it’s not a problem, we can still note a few
things about the model.
In this case, we extend ActiveRecord and implement IdentityInterface, which means we
have to create the interface’s methods in our User class. The comments provide details on
what the methods should do. It will give you some idea of how it works, but don’t worry if
you don’t instantly know how to write the methods, and you will see why that is in a
moment.
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\web;
interface IdentityInterface
{
Chapter Four: Modifying the User Model 47
/**
* Finds an identity by the given ID.
* @param string|integer $id the ID to be looked for
* @return IdentityInterface the identity object that
*matches the given ID.
* Null should be returned if such an identity cannot be found
* or the identity is not in an active state
*(disabled, deleted, etc.)
*/
/**
* Returns an ID that can uniquely identify a user identity.
* @return string|integer an ID that uniquely identifies a user identity.
*/
/**
Chapter Four: Modifying the User Model 48
* Returns a key that can be used to check the validity of a given identity ID.
*
* The key should be unique for each individual user, and should be persistent
* so that it can be used to check the validity of the user identity. *
* The space of such keys should be big enough to defeat potential identity atta\
cks.
*
* This is required if [[User::enableAutoLogin]] is enabled.
* @return string a key that is used to check the validity of a given identity I\
D.
* @see validateAuthKey()
*/
/**
* Validates the given auth key.
*
* This is required if [[User::enableAutoLogin]] is enabled.
* @param string $authKey the given auth key
* @return boolean whether the given auth key is valid.
* @see getAuthKey()
*/
An Interface is like a contract with the subclass. It says if you wish to use my interface, you
must have the following methods. If you don’t include them all, it will return an error.
Programmers use Interfaces to control the architecture.
So this IdentityInterface is the contract our User model needs to implement. Ok, so I said
we didn’t have to worry about the interface, why is that? Fortunately for us, the advanced
template already implements it for us, and you can find these methods already on our User
model, so you don’t need to write a single line of code. Thank you Yii 2 Advanced Template!
The basic template does not come with this implementation, so this is one reason why the
advanced template is actually easier to implement than the basic template. It’s one of the
primary reasons we
Chapter Four: Modifying the User Model 49
Hopefully this one is rather self-evident. I wish they were all this easy!
Behaviors
The next method is:
I find the concept of behaviors in Yii 2 very intuitive, written with clear syntax and beautiful
code. The method tells the model how to behave, given certain events.
The first element in the array, ‘timestamp’ identifies the behavior, and we tell it what class
we want to use. Then we define the events that will affect the attributes, in this case
ActiveRe cord::EVENT_BEFORE_INSERT and ActiveRecord::EVENT_BEFORE_INSERT.
These point to the attributes, ‘created_at’ and ‘updated_at’, which are also represented as
fields in the user table.
Chapter Four: Modifying the User Model 50
Note that we are also defining the value and it will use:
'value' => new Expression('NOW()'),
It hands the string ‘NOW()’ to Mysql, which is a Mysql syntax for the current DateTime.
Without that, it would insert an integer, which is not the behavior we want. So this method
will fire off whenever a record is created or updated and put the appropriate entry into the
database in the correct DateTime format.
The concept of behaviors is used extensively on Controllers and we will be looking at that
later. Also note that in order to use Expression, we have to include the appropriate use
statement:
use yii\db\Expression;
Ok, on to our next method:
Rules
public function rules()
{
return [
];
}
Chapter Four: Modifying the User Model 51
This is how easy Yii 2 makes it to enforce validation rules on the model. It’s an array format,
where the first value is the attribute, the second is the validator being called, and then come
parameters or conditions. You can check the guide for a more complete list of validators
and how to use them:
Yii 2 guide on Rules²⁶
The first 3 rules deal with setting defaults and allowable range. The white space in between
rows is simply cosmetic to make it easier to work on rules for a particular attribute, the order
they are in doesn’t really matter.
If we look at the last set of rules, the ones for email, we see that make sure we trim spaces
out, email is required, email is of email type, and email is unique. Yii 2 does all of this for
you with this simple syntax, how awesome is that?
Identity Methods
The next method on the User model is findIdentity, which is an implementation of
IdentityInterface, which we covered previously.
This is one of the places where we changed ‘status’ to ‘status_id’. This is followed by:
²⁶http://www.yiiframework.com/doc-2.0/guide-input-validation.html
Chapter Four: Modifying the User Model 52
/*
*broken into two lines to avoid wordwrapping
* line break to avoid wordwrap
* body should be single line in your IDE
*/
Here again we have used the ‘status_id’ attribute instead of ‘status’. Another method from
the IdentityInterface, with the same change to ‘status_id’ attribute:
return static::findOne([
'password_reset_token' => $token,
'status_id' => self::STATUS_ACTIVE,
]);
}
And the last two methods from the Interface provided by the Advanced Template:
Chapter Four: Modifying the User Model 53
Since the advanced app template provides the Interface methods for us, we will not cover
them in greater detail. If you wish to read more on them, you can check out:
Yii 2 Security Authentication²⁷
Boilerplate Methods
The next few classes are all part of the boilerplate, which we did not change. The comments
provide the explanation better than I can, since these are deep framework methods that I
didn’t write:
/**
* Validates password
*
* @param string $password password to validate
* @return boolean if password provided is valid for current user
*/
/**
* Generates password hash from password and sets it to the model
*
* @param string $password
*/
²⁷http://www.yiiframework.com/doc-2.0/guide-security-authentication.html
Chapter Four: Modifying the User Model 54
/**
* Generates "remember me" authentication key
*/
/**
* Generates new password reset token
* line break to avoid wordwrap
* body should be single line in your IDE
*/
/**
* Removes password reset token
*/
If all went well with updating the user table and copying the new User model, you should be
able to use the application again to register a user. Any old users were likely dropped when
you made the changes to the schema. If for some reason it doesn’t work, retrace your steps
and check your spelling carefully. Make sure the DB is updated with the correct fields.
Note: Since we changed our field to status_id, the out-of-the-box forgot password
functionality is now broken. Don’t worry, we will fix it later.
SignupForm Model
Let’s take a look at the SingupForm model, you see there are only 3 attributes:
The reason why there are no attributes or rules for role_id, status_id, user_type_id, for
example, is that we are setting those by default in the background, not from the form, so
they are not needed. Remember, we set the default value of user_id to 10, and it
automatically gets recorded that way when a user record is created.
Often, user data will be handed to a form model to enforce validation rules or other
methods. The data comes in from a controller, which gives the model the post data from a
view that is typically a form. This sounds more complicated than it actually is.
It’s important to know how a user is created in your application, so we may as well take a
quick peek, and see how this works by looking at the actionSignup() method on the fron
tend\controllersSiteController:
Chapter Four: Modifying the User Model 56
return $this->render('signup', [
'model' => $model,
]);
}
You can see the method calls an instance of the SignupForm model. The main method of
SingupForm is signup(), which creates an instance of the User model if the form has passed
validation:
return null;
}
It will try to validate, and if it can validate, it calls an instance of the user class, so it can set
the user properties to what was handed in via form, create the hashed password, generate
the auth key, save and return $user. It’s important to note that a return statement, when
exectued, terminates the function, so you don’t need an else statment here. If there is a
$user, it gets returned and the code never executes return null. If the if statement evaluates
false, it will return null. It will be false if validation fails or if there were some other problem.
Right now somebody’s head is probably exploding because I explained something so basic.
But just keep in mind this is a beginner’s book and we want to refresh and grow our
programming skills as we move along.
Chapter Four: Modifying the User Model 57
Ok, back to the action on the SiteController, where we get a nice nested if statement, which
we can break apart to understand:
if ($model->load(Yii::$app->request->post())) {
If the model (SignupForm) can load the post data from Yii::$app->request->post(), which
only happens if there is post data. The syntax for getting the post data is clear and concise:
Yii::$app->request->post()
This brings all the form attributes along as long as the form and form model are built
correctly. The post data can only come from someone filling out the signup form on the view
and being passed along by the action of the view. If that happens, then continue. In this
case the view is signup.php under frontend\views\site\signup.php. We won’t go into detail
on the form now, but you can check it out for yourself if you want to.
Next if:
if ($user = $model->signup()) {
Call the signup method of SignupForm. The first thing the signup method does is validate,
so if we don’t get past the rules, it will not signup the user and it will return an error message
to the user, based on rule behavior. If all is well and we get an instance of $user, it
continues:
Then the third if:
if (Yii::$app->getUser()->login($user)) {
We are accessing getuser and login user from an application instance of Yii, which has
access to those methods. We talked about creating the application instance from Index.php
in chapter 3, so here it is being used to called a couple of chained methods.
tip
Note, for us to be able to use Yii::$app, we need to have the use statement, use
Yii; at the top of the file.
return $this->render('signup', [
'model' => $model,
]);
And with all the validation and internal methods of Yii 2, if you tried to signup and something
was wrong, it will display the error messages as well.
The login method from SiteController is similar:
Chapter Four: Modifying the User Model 58
First it tests to see if you are logged in or not by calling the isGuest method. We are using
the ! in front, so if not a guest, you are already logged in and you go to the home page.
Then it uses a different model, the LoginForm model and either logs you in and takes you
back to the page you were on previously, but in a logged in state, or it shows you the login
form, again with errors if you tried to login in and did it incorrectly.
Ok, so we took a quick detour from the User model to give you an idea of how users are
created and to give you a look at the models moving user data through the site. We didn’t
really go into too much depth on the controller, we will cover controllers more in detail later,
this was more about the models that are controlling the user. Here we had 3 distinct
models, User, SignupForm, and LoginForm that controlled the user’s data.
Chapter Four: Modifying the User Model 59 Summary
Ok, that was a lot to absorb. If this is all new to you and you are struggling with it a bit, don’t
worry, it will become more clear over time as you get used to seeing the same types of
methods used to move data around the site. We will see all this in detail again.
So we are building a reusable template and starting by modifying the User model, which
has a lot of methods on it that reach deep into the framework.
The User model is always drastically different than other models because of things like the
set password method and the other methods that are unique to users. We also touched on
the fact that controllers can sometimes use other models to create and change user
records.
The other models we are going to build, such as Role, Status, UserType, etc., tend to be
more straightforward and easier to understand, not to mention, a lot shorter in size.
In the next section, we will use Gii, Yii 2’s code generation tool, and you will see how
amazing this really is and how much faster the workflow is.
• Role
• Status
• Gender
• UserType
• Profile
Note that in the list above, since we are talking about models, we use uppercase, and you
can see on UserType, that I used the format that Gii will create from the convention where
the table name is user_type. We will understand that better later in the book when we
create the UserType CRUD.
Creating Tables
Now it’s time for us to create the rest of the tables. I’m going to provide screenshots from
Mysql workbench, which will give us an easy reference for not only what fields we need, but
also the constraints and data types.
Tip
MySQL CONSTRAINTS are used to define rules to allow or restrict what values
can be stored in columns.
MySQL CONSTRAINTS enforce the integrity of database.
MySQL CONSTRAINTS are declared at the time of creating a table.
• NOT NULL
Chapter Five: Creating New Models with Gii 61
• UNIQUE
• PRIMARY KEY
• FOREIGN KEY
• CHECK
• DEFAULT
Role Table
Here is the table for role:
role table
Notice that we have used lower case to name the table. If a table name requires two words,
we will separate them with an underscore. We will also use underscore to separate words in
column names as you can see above.
The role table is very simple. Pk stands for primary key, NN means Not Null, and AI is auto
increment. We auto-increment the record ids. We use varchar for role_name and integer for
role_value. You can probably use small int for role_value, I will leave that choice up to you.
Sometimes when you building even trivial data structure, you will want created_at and
updated_at, plus created_by and updated_by, just to keep track of who is doing what and
when. But since this is only holding the names and values of roles, we don’t need those
fields.
²⁸http://www.w3resource.com/mysql/creating-table-advance/constraint.php
Status Table
This is identical to role, only it’s for status. On both tables we have created so far, we are
selecting PK for primary key on the first column, which is id. We also set it to NN, which is
not null, meaning it is not allowed to be null.
That’s the same type of data structure as the first two tables we created, only we have a
table name with an underscore in it. Gii creates a specific naming convention to handle this,
which we will see later when we create the model, controller, and views.
Gender Table
Here we have gender:
Chapter Five: Creating New Models with Gii 63
Gender Table
This one is even simpler, just id and gender_name.
Profile Table
And lastly, the profile table:
Profile Table
Our plan is to allow each user to create a single profile, so these will have a one to one
relationship with the User model. This is why on the User model we are going to add the
following method:
You can see in this case the id of the user is set to the user_id on the profile record. And
this establishes the link between the two models. We’ll do that in a few minutes, after we
have set up our new models. Then we can update the User model with the relationship
methods it needs to talk to the other models.
Note that on the profile int columns, I checked off UN, which stands for unsigned and does
not allow negative numbers.
Chapter Five: Creating New Models with Gii 64
You can also see there is a red diamond on the gender_id column and this represents a
foreign key. Foreign keys are set to tie 2 tables together and Gii can read this data and
setup the relationship for you when it creates the model. We will see this in action later.
Right now all you need to know, is that the foreign key for gender_id on the profile table is
mapped to id on the gender table.
Synchronize
Don’t forget to synchronize the model with the actual DB:
Synchronize
PhpMyAdmin
And that’s it. All in all, it’s a very simple data structure and we’re going to have a lot of fun
with it. We’re going to use Gii to create models, controllers, and views, lots of code that it
will generate for us.
Chapter Five: Creating New Models with Gii 65 Configuring Gii
Of course we need to make sure we have Gii installed. Go to the following url in your
browser: yii2build.com/index.php?r=gii
If that does not resolve, then you need to check your composer.json file to see if you have
the Gii module required. composer.json is in your root directory and should be visible in
your IDE.
This is what my file looks like:
{
"name": "yiisoft/yii2-app-advanced",
"description": "Yii 2 Advanced Application Template",
"keywords": ["yii2", "framework", "advanced", "application template"],
"homepage": "http://www.yiiframework.com/",
"type": "project",
"license": "BSD-3-Clause",
"support": {
"issues": "https://github.com/yiisoft/yii2/issues?state=open",
"forum": "http://www.yiiframework.com/forum/",
"wiki": "http://www.yiiframework.com/wiki/",
"irc": "irc://irc.freenode.net/yii",
"source": "https://github.com/yiisoft/yii2"
},
"minimum-stability": "stable",
"require": {
"php": ">=5.4.0",
"yiisoft/yii2": "*",
"yiisoft/yii2-bootstrap": "*",
"yiisoft/yii2-swiftmailer": "*",
"kartik-v/yii2-social": "dev-master",
"yiisoft/yii2-authclient": "*",
"fortawesome/font-awesome": "4.2.0"
},
"require-dev": {
"yiisoft/yii2-codeception": "*",
"yiisoft/yii2-debug": "*",
"yiisoft/yii2-gii": "*",
"yiisoft/yii2-faker": "*",
"yiisoft/yii2-jui": "*"
},
"config": {
Chapter Five: Creating New Models with Gii 66
"process-timeout": 1800
},
"extra": {
"asset-installer-paths": {
"npm-asset-library": "vendor/npm",
"bower-asset-library": "vendor/bower"
}
}
}
You can see under “require-dev”, I have the line for gii. I have a few extensions included for
use later, including Karitk social, authclient, font-awesome and others. It makes sense to
just copy this version of composer.json into your file, so go ahead and do that, then run
composer update from the command line:
Composer Update
<?php
namespace backend\models;
/**
* This is the model class for table "role".
*
* @property integer $id
* @property string $role_name
* @property integer $role_value
* @property User[] $users
*/
/**
* @inheritdoc
*/
return [
[['role_value'], 'integer']
];
}
/**
* @inheritdoc
*/
];
}
So there it is in backend\models. It looks very familiar at this point. I’ve already explained in
detail what the rules do on the User model, and rules function the same way here. This is
such a simple model, that we don’t have much to talk about.
The attributeLabels method just sets the attributes to label names that will be visible on the
application.