Yii2 is a complete rewrite of the first version of one of the most famous PHP frameworks. It is a well-documented framework with a very active community.
Officially, we can find three types of support: a guide, for a complete navigation through framework topics at http://www.yiiframework.com/doc-2.0/guide-index.html, a reference to explore all classes that compose the framework at http://www.yiiframework.com/doc-2.0/index.html, and finally forum support at http://www.yiiframework.com/forum/.
In this chapter, we will go through the following:
Requirements and tools
Installing Yii2 with Composer
Application structure
Application properties
Common application components
Handling application events
Pattern MVC in Yii2
Naming convention
Configuring debug toolbar
Using logger
Example – hello world from scratch with the Yii basic template and bootstrap template
The basic requirements for Yii2 are a web server (local or remote) and PHP v.5.4 (or newer). It is recommended to have a shell (or command line) access to the machine (local or remote) where we store the code, as there are scripts that it will be very beneficial to use in the development of complex applications. We can also develop the application locally and upload it to the web server when we wish to test it.
For remote hosting, there are multiple options. We can use a simple web hosting service (with PHP v.5.4 support) or we can opt for virtual or dedicated server hosting. Keep in mind that with the former option, if the server doesn't meet the PHP requirements, it can be difficult to change whatever is wrong.
Yii2 has a script, requirements.php
, which checks whether our hosting meets the requirements to run Yii2 application.
Composer is a tool for dependency management in PHP. Yii2 uses it to install itself and other vendors' modules (for example, bootstrap).
It is also possible to install Yii2 in the old way, by downloading the complete package and transferring it to the host, local or remote, where the framework will be installed. However, Composer will give us many benefits, like the ability to easily update the framework and ensure that all package dependencies are satisfied. Composer is de facto the new way to install and maintain projects, so I recommend using it from the start. If you are unsure about using Composer, it's worth mentioning that most users will need to learn two or three commands at most, so it's not a steep learning curve.
Yii2 has two available templates to start with: basic and advanced. We will start with the basic template, but we will also see in the next chapters how to use advanced templates.
So, let's look at how to install Yii2 with Composer. We need to access the folder through the console, where the web server's httpdocs point to and launch these commands:
curl -s http://getcomposer.org/installer | php php composer.phar global require "fxp/composer-asset-plugin:1.0.0" php composer.phar create-project --prefer-dist yiisoft/yii2-app-basic basic
These commands are useful if we are in the Linux or Mac environment. On Windows, you need to download Composer-Setup.exe
from Composer's official website and run it.
The first command gets the http://getcomposer.org/installer URL and passes it to PHP to create the composer.phar
file.
The second command installs the Composer asset plugin, which allows us to manage bower and npm package dependencies through Composer.
The third and final command installs Yii2 in a directory named basic
. If you want, you can choose a different directory name.
Note
During the installation, Composer may ask for our GitHub login credentials and this is normal because Composer needs to get enough API rate limit to retrieve the dependent package information from GitHub. If you don't have a GitHub account, this is the right moment to create a new one!
If we are using Windows, we need to download it from https://getcomposer.org and run it. The last two commands will be the same.
We have installed Yii2!
To test it, point to http://hostname/basic/web
and we should see the My Yii Application page.
Yii2's application structure is very clear, precise, and redundant (for advanced applications).
The contents of the basic
folder should be as follows:
Open web/index.php
to view content:
<?php // comment out the following two lines when deployed to production 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'); $config = require(__DIR__ . '/../config/web.php'); (new yii\web\Application($config))->run();
Here, the first two constant definitions are very important.
YII_DEBUG
defines whether you are in debug mode or not. If we set this, we will have more log information and will see the detail error call stack.
YII_ENV
defines the environment mode we are working in, and its default value is prod
. The available values are test
, dev
, and prod
. These values are used in configuration files to define, for example, a different DB connection (local database different from remote database) or other values, always in configuration files.
Since we are at the start of our project, it is recommended to set YII_DEBUG
to true
, in order to have more detailed information in case we make a mistake in our code, instead of the unhelpful, blank.
The following table contains a list of all Yii2's objects:
A Yii2 application can be configured through several properties.
The properties that need to be configured in any application are listed in the following table:
The other common properties are listed in the following table:
Here's a list of the most-used application components:
request
: This component handles all client requests and provides methods to easily get parameters from server global variables, such as$_SERVER
,$_POST
,$_GET
, and$_COOKIES
.The default state has
enableCookieValidation
set to true, so you need to setcookieValidationKey
parameter as shown in this example:'request' => [ 'cookieValidationKey' => 'hPpnJs7tvs0T4N2OGAY', ],
cache
: This component helps you handle cache data. Yii2 defaults to theFileCache
instance for the cache, but we can also configure anApcCache
,DbCache
,MemCache
, and so on.The following is a standard installation of Yii2:
'cache' => [ 'class' => 'yii\caching\FileCache', ],
user
: This component deals with user authentication in the app. The most important parameter is theidentityClass
parameter, which defines the class that contains the user's model data, in order to have a specific method to log in or log out a user from the app.Consider the following example:
'user' => [ 'identityClass' => 'app\models\User', 'enableAutoLogin' => true, ],
errorHandler
: This component provides functionalities to handle uncaught errors and exceptions. It can be configured by specifying the action to run.Consider the following example:
'errorHandler' => [ 'errorAction' => 'site/error', ],
mailer
: This component configures mailer connection parameters to the system that will send an e-mail. Usually, it is the same machine hosting our website, so the default values are probably correct.Consider the following example:
'mailer' => [ 'class' => 'yii\swiftmailer\Mailer', // send all mails to a file by default. You have to set // 'useFileTransport' to false and configure a transport // for the mailer to send real emails. 'useFileTransport' => true, ],
log
: This component is mainly used in the debug environment to log the app execution. We can set the debug level and destination.Consider the following example:
'log' => [ 'traceLevel' => YII_DEBUG ? 3 : 0, 'targets' => [ [ 'class' => 'yii\log\FileTarget', 'levels' => ['error', 'warning'], ], ], ],
db
: This component handles a database connection. We can have several db configuration in our app; in this case, we can define more components with theConnection
class located atyii\db\
.Consider the following example:
db => [ 'class' => 'yii\db\Connection', 'dsn' => 'mysql:host=localhost;dbname=yii2basic', 'username' => 'dbuser'', 'password' => 'dbpassword', 'charset' => 'utf8', ],
During its lifecycle, an application can trigger many events. These events can be declared in application configuration or programmatically. Common triggers are beforeRequest
, afterRequest
, beforeAction
, and afterAction
, but every object can have its own events.
For example, a common use of events is to set mysql db timezone
.
To set the time zone to UTC in db component configuration, we must define a handler for the afterOpen
event:
'db' => [ 'class' => 'yii\db\Connection', 'dsn' => 'mysql:host=localhost;dbname=mydb', 'username' => 'dbuser', 'password' => 'dbpassword', 'charset' => 'utf8', 'on afterOpen' => function($event) { $event->sender->createCommand("SET time_zone = '+00:00'")->execute(); } ],
An anonymous function, attached to on afterOpen
event handlers, has an $event
parameter, which is an instance of the yii\base\ActionEvent
class. This class has a $sender
object that refers to the sender of the event. In this case, $sender
refers to the instance of database components (db). This property may also be null when this event is a class-level event.
Yii2 is built according to the Model-View-Controller (MVC) design pattern.
Models, representing logic, are objects extended from \yii\base\Model
, which offer many features such as attribute, attribute labels, massive assignment (to fill object attributes directly for an array), validation rules, and data exporting.
Normally, in common apps, a Model will be generated from the database, extending yii\db\ActiveRecord
that implements the Active Record design pattern, with many methods to manipulate data. Yii2 provides Gii, a tool used to generate Model classes directly from the database's table structure.
Controllers, the bridge between view and model, are class instances extending from yii\base\Controller
, used to process requests and generate responses.
Controllers mainly contain functions whose name starts with the action prefix that allows the framework to recognize those functions as routes, which can be requested.
Finally, we will look at views that deal with displaying data to end users that are mainly rendered in the page layout from controllers.
In order to allow auto-loading, Yii2 uses a simple standard to set names.
Routes that refer respectively to module, controller, and the action requested take the following format:
ModuleID/ControllerID/ActionID
We will look at each element in detail as follows:
The ModuleID is optional, so often the format is ControllerID/ActionID
The ModuleID must be specified in the module's configuration property, under the same name
The ControllerID and ActionID should contain only English characters in lowercase, digits, underscores, dashes, and forward slashes
An example of route is http://hostname/index.php?r=site/index
, where site
is the ControllerID and index
is the ActionID.
Starting from ControllerID, it is very easy to create the Controller class name. Just turn into uppercase the first letter of each word separated by dashes, then remove dashes and append the suffix Controller. If ControllerID contains slashes, just apply the rules to the part after the last slash in the ID. This is possible because controllers can be collected in subfolders, starting from app\controllers
.
The following are some examples:
Shop points to
app\controllers\ShopController
Preferred number points to
app\controllers\PreferredNumberController
Admin/users account points to
app\controllers\admin\UsersAccountController
Routes are passed to entry script basic/web/index.php
through the r
parameter.
Note
The default page http://hostname/basic/web/index.php
is equivalent to http://hostname/basic/web/index.php?r=site/index
.
It is important to have a rich collection of tools to make development easier in displaying some useful information about requests and responses.
For this purpose, Yii2 provides a toolbar that displays several types of info.
A common way to activate the debug toolbar is to set in config/web.php
:
'bootstrap' => ['debug'], 'modules' => [ 'debug' => 'yii\debug\Module', ]
Now you can set the following values:
debug
tobootstrap
config nodedebug
tomodules
config node, using theModule
class underyii\debug\
The default installation of the Yii2 basic template already enables the debug toolbar, as we can see at the bottom of the config/web.php
configuration file. The Gii module is also enabled as well, but we will work with it later.
if (YII_ENV_DEV) { // configuration adjustments for 'dev' environment $config['bootstrap'][] = 'debug'; $config['modules']['debug'] = 'yii\debug\Module'; $config['bootstrap'][] = 'gii'; $config['modules']['gii'] = 'yii\gii\Module'; }
This config entry is only valid in the YII_ENV_DEV
mode. So, we must check whether the web/index.php YII_ENV
variable has the dev
value (as shown in the default installation).
If we try to reload the web page at basic/web/index.php
after these checks, we should see the following screenshot:
The right arrow reports that the debug toolbar is active but closed. If we click on it, the complete toolbar will open. Now, click on any item, the debug panel will be displayed.
By default, the debug toolbar can be used only in localhost. However, if we are using Yii2 in the remote hosting environment, we set the allowedIPs
property of the debug
module.
$config['modules']['debug'] = [ 'class' => 'yii\debug\Module', 'allowedIPs' => [ '127.0.0.1', '::1'] ];
In allowedIPs
there is only localhost (in the IPv4 and IPv6 forms). We need to put our Internet connection and IP source address here, which can be easily found using any my IP
service on the Internet, such as http://www.whatismyip.com/.
If our IP source is, for example, 1.2.3.4
, we must add this entry to allowedIPs
, in this way:
$config['modules']['debug'] = [ 'class' => 'yii\debug\Module', 'allowedIPs' => [ '127.0.0.1', '::1', '1.2.3.4'] ];
Remember that if we do not have an Internet connection with a static IP, this IP might change. So we need to check whether allowedIPs
contains our current IP.
You could also use an asterisk *
to allow all IP addresses, so you do not have to deal with dynamic IP issues. If you do this, you need to remember to remove the asterisk before deployment. Finally, at the bottom of our current configuration config/web.php
, you will see the following code:
if (YII_ENV_DEV) { // configuration adjustments for 'dev' environment $config['bootstrap'][] = 'debug'; $config['modules']['debug'] = [ 'class' => 'yii\debug\Module', 'allowedIPs' => [ '127.0.0.1', '::1', '1.2.3.4'] ]; $config['bootstrap'][] = 'gii'; $config['modules']['gii'] = 'yii\gii\Module'; }
Let's return to the basic/web/index.php
webpage and take a look at the debug info panel.
The debug information is distributed in the menu:
Configuration: This is the installed PHP version and configuration and also the installed Yii2 framework version.
Request: This is the info about the request just sent, displaying parameters of the request, headers of the request and other useful data as response and session data.
Logs: This involves the actions performed by Yii2 during the execution. There are additional filters in this section to select the types of logs to be displayed.
Performance Profiling: This includes info about timing and duration of process.
Database: This includes info about all database query occurred; we can filter for type of query to locate a specific query.
It is possible to filter all data using internal grid filter or to filter for all, latest or selecting among the last 10 rows of the log on top of the content pane.
In the Yii2 application, the debug info is stored using the log component. We can use this tool both in the development and production environment, but for reasons of performance and security in production, we should log only the important messages.
The default configuration file of the Yii2 basic template provides log entry in the components
property of config/web.php
:
'log' => [ 'traceLevel' => YII_DEBUG ? 3 : 0, 'targets' => [ [ 'class' => 'yii\log\FileTarget', 'levels' => ['error', 'warning'], ], ], ],
It is now time to code our first project using Yii2.
If we have not installed Yii2 yet, we will to do it now using Composer as follows:
Open Command Prompt to the web server.
Go to the document root of the web server (
/var/www
in a Linux machine).Launch these commands (as described in the Installing Yii with Composer section):
curl -s http://getcomposer.org/installer | php php composer.phar global require "fxp/composer-asset-plugin:1.0.0" php composer.phar create-project --prefer-dist yiisoft/yii2-app-basic basic
Now, we need a fresh installation of Yii2 in the basic folder of the web server document root. Point the browser to http:/hostname/basic/web
and we should see Yii2's congratulations page:
We will create our first action to display a memorable hello world
on the screen.
We know from the Application properties section, in the defaultRoute entry, that the SiteController
controller will be called when no route is specified in request.
So, we enter basic/controllers
and open SiteController.php
, which is the default controller.
In the SiteController
class definition, we add a new method at the top, called actionHelloWorld
, without parameters.
public function actionHelloWorld() { echo 'hello world' }
Let's save the file and point to http://hostname/basic/web/index.php?r=site/hello-world
.
You should see a blank page with hello world
.
Note
Pay attention when using the name route convention. Uppercase letters are translated to lowercase and dashes.
This is fantastic, but now we just want to put hello world
within the page template.
We must now create a view with the content of response hello world!. In order to do this, we need to create a file named helloWorld.php
as the name of the action under views/site
. The naming convention need not necessarily be the same here because the view file is not automatically called from the framework.
This file only contains the hello world
text.
We update SiteController
with the following code:
public function actionHelloWorld() { return $this->render('helloWorld'); }
In the actionHelloWorld()
method, $this
refers to the SiteController's instance, and render()
will insert the views/helloWorld.php
file content in the main content layout page.
The extension of the view file, .php
, is automatically added from the framework to view the name parameter passed to the render method.
What if we want to pass a parameter, such as name, to actionHelloWorld()
? Formally, we need to add just one parameter to actionHelloWorld()
in SiteController as follows:
public function actionHelloWorld($nameToDisplay) { return $this->render('helloWorld', [ 'nameToDisplay' => $nameToDisplay ] ); }
Then, under view/site/helloWorld.php
add the following code:
Hello World <?php echo $nameToDisplay ?>
With the update of actionHelloWorld()
, we will pass as a second parameter, an array of variables, that will be visible and used in View.
When we use parameters in the action function, we must remember that they will be mandatory and we must respect the order when passing it to the request.
To avoid this obligation, we can use the old method, parsing parameters into the function:
public function actionHelloWorld() { $nameToDisplay = Yii::$app->request->get('nameToDisplay'); // Equivalent to // $nameToDisplay = isset($_GET['nameToDisplay'])?$_GET['nameToDisplay']:null; return $this->render('helloWorld', [ 'nameToDisplay' => $nameToDisplay ] ); }
With this solution, we can decide whether to pass the nameToDisplay
parameter to request. The default value of the nameToDisplay
parameter will be null, but we can decide to assign a different value.
The following is a URL example passing the nameToDisplay
parameter Foo
:
http://hostname/basic/web/index.php?r=site/hello-world&nameToDisplay=Foo
In this chapter, we looked at a basic understanding of the Yii2 framework, starting from requirements to explain the main features. Then we used debugging and logging tools to trace our code and were able to find errors. Finally, we wrote our first project based on the basic template.
Next, you will learn how to create our controllers and views, to create custom interaction with frontend users.