Mastering Yii

4.5 (6 reviews total)
By Charles R. Portwood II
  • Instant online access to over 8,000+ books and videos
  • Constantly updated with 100+ new titles each month
  • Breadth and depth in over 1,000+ technologies
  1. Composer, Configuration, Classes, and Path Aliases

About this book

The successor of Yii Framework 1.1, Yii2 is a complete rewrite of Yii Framework, one of the most popular PHP 5 frameworks for making modern web applications. The update embraces the best practices and protocols established with newer versions of PHP, while still maintaining the simple, fast, and extendable behavior found in its predecessor.

This book has been written to enhance your skills and knowledge with Yii Framework 2. Starting with configuration and how to initialize new projects, you’ll learn how to configure, manage, and use every aspect of Yii2 from Gii, DAO, Query Builder, Active Record, and migrations, to asset manager. You'll also discover how to automatically test your code using codeception.

With this book by your side, you’ll have all the skills you need to quickly create rich modern web and console applications with Yii2.

Publication date:
January 2016
Publisher
Packt
Pages
380
ISBN
9781785882425

 

Chapter 1. Composer, Configuration, Classes, and Path Aliases

Before diving into Yii Framework 2, we need to take a look at how it is installed, how it is configured, and what the core building blocks of the framework are. In this chapter, we'll go over how to install the framework itself and prebuilt applications via a package management tool called Composer. We'll also cover some common configurations of both Yii Framework 2 and our web server, including making our applications aware of the environment they are running on and responding appropriately to that environment.

Note

The most common ways to reference Yii Framework 2 are Yii Framework 2, YF2, and Yii2. We'll be using these terms interchangeably throughout the book.

 

Composer


There are several different ways to install Yii2, ranging from downloading the framework from source control (typically, from GitHub at https://github.com/yiisoft/yii2) to using a package manager such as Composer. With modern web applications, Composer is the preferred method to install Yii2 as it enables us to install, update, and manage all dependencies and extensions for our application in an automated fashion. Additionally, using Composer, we can ensure that Yii Framework 2 is kept up to date with the latest security and bug fixes. Composer can be installed by following the instructions on https://getcomposer.org. Typically, this process looks as follows:

curl -sS https://getcomposer.org/installer | php

Alternatively, if you don't have cURL available on your system, it can be installed through PHP itself:

php -r "readfile('https://getcomposer.org/installer');" | php

Once installed, we should move Composer to a more centralized directory so that we can call it from any directory on our system. Installing Composer from a centralized directory rather than on a per-project basis has several advantages:

  • It can be called anywhere from any project. When working with multiple projects, we can ensure that we use the same dependency manager each time and for every project.

  • In a centralized directory, Composer only needs to be updated once rather than in every project we are working on.

  • Dependency managers are rarely considered code that should be pushed to your DCVS repository. Keeping the composer.phar file out of your repository reduces the amount of code you need to commit and push and ensures that your source code remains isolated from your package manager code.

  • By installing Composer from a centralized directory, we can ensure that Composer is always available, which saves us a step each time we clone a project that depends on Composer.

A good directory to move Composer to is /usr/local/bin, as shown in the following example:

mv composer.phar /usr/local/bin/composer
chmod a+x /usr/local/bin/composer

Tip

Throughout this book, we'll be using Unix-style commands when referencing command-line arguments. Consequently, some commands may not work on Windows. If you decide to set up a Windows environment, you might need to use Composer-Setup.exe (available at https://getcomposer.org/Composer-Setup.exe) to get Composer configured for your system. If you have any issues getting Composer to run on your system, ensure that you check out the Composer documentation available at https://getcomposer.org/doc/.

Alternatively, if you have Composer installed on your system already, ensure that you update it to the latest version by running this:

composer self-update

Tip

The commands that we use through this book are based on the assumption that you have sufficient privileges to run them. On Unix-like systems, you may need to preface some commands with sudo in order to execute the command with a high permissions set. Alternatively if you are running these commands on Windows, you should ensure that you are running the listed commands in a command prompt that has elevated privileges. Ensure that you follow best practices when using sudo and when using elevated command prompts in order to ensure your system stays secure.

Once Composer is installed, we'll need to install a global plugin called The Composer Asset Plugin (available at https://github.com/francoispluchino/composer-asset-plugin). This plugin enables Composer to manage asset files for us without the need to install additional software (these programs are Bower, an asset dependency manager created by Twitter, and Node Package Manager, or NPM, which is a JavaScript dependency manager).

composer global require "fxp/composer-asset-plugin:1.0.0"

Tip

Due to the GitHub API's rate limiting, during installation, Composer may ask you to enter your GitHub credentials. After entering your credentials, Composer will request a dedicated API key from GitHub that can be used for future installations. Ensure that you check out the Composer documentation at https://getcomposer.org/doc/ for more information.

With Composer installed, we can now instantiate our application. If we want to install an existing Yii2 package, we can simply run the following:

composer create-project --prefer-dist <package/name> <foldername>

Using the Yii2 basic app as an example, this command will look like this:

composer create-project --prefer-dist yiisoft/yii2-app-basic basic

After running the command, you should see output similar to the following:

Installing yiisoft/yii2-app-basic (2.0.6)
  - Installing yiisoft/yii2-app-basic (2.0.6)
    Downloading: 100%
Created project in basic
Loading composer repositories with package information
Installing dependencies (including require-dev)
  - Installing yiisoft/yii2-composer (2.0.3)
  - Installing ezyang/htmlpurifier (v4.6.0)
  - Installing bower-asset/jquery (2.1.4)
  - Installing bower-asset/yii2-pjax (v2.0.4)
  - Installing bower-asset/punycode (v1.3.2)
  - Installing bower-asset/jquery.inputmask (3.1.63)
  - Installing cebe/markdown (1.1.0)
  - Installing yiisoft/yii2 (2.0.6)
  - Installing swiftmailer/swiftmailer (v5.4.1)
  - Installing yiisoft/yii2-swiftmailer (2.0.4)
  - Installing yiisoft/yii2-codeception (2.0.4)
  - Installing bower-asset/bootstrap (v3.3.5)
  - Installing yiisoft/yii2-bootstrap (2.0.5)
  - Installing yiisoft/yii2-debug (2.0.5)
  - Installing bower-asset/typeahead.js (v0.10.5)
  - Installing phpspec/php-diff (v1.0.2)
  - Installing yiisoft/yii2-gii (2.0.4)
  - Installing fzaninotto/faker (v1.5.0)
  - Installing yiisoft/yii2-faker (2.0.3)
Writing lock file
Generating autoload files
> yii\composer\Installer::postCreateProject
chmod('runtime', 0777)...done.
chmod('web/assets', 0777)...done.
chmod('yii', 0755)...done.

Note

Your output may differ slightly due to the data cached on your system and versions of subpackages.

This command will install the Yii2 basic app to a folder called basic. When creating a new Yii2 project, you'll typically want to use the create-project command to clone "yii2-app-basic" and then develop your application from there as the basic app comes prepopulated with just about everything you need to start a new project. However, you can also create a Yii2 project from scratch that, while more complicated, gives you more control over your application's structure.

Let's take a look at the composer.json file that was created when we ran the create-project command:

{
    "name": "yiisoft/yii2-app-basic",
    "description": "Yii 2 Basic Application Template",
    "keywords": ["yii2", "framework", "basic", "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": "*"
    },
    "require-dev": {
        "yiisoft/yii2-codeception": "*",
        "yiisoft/yii2-debug": "*",
        "yiisoft/yii2-gii": "*",
        "yiisoft/yii2-faker": "*"
    },
    "config": {
        "process-timeout": 1800
    },
    "scripts": {
        "post-create-project-cmd": [
            "yii\\composer\\Installer::postCreateProject"
        ]
    },
    "extra": {
        "yii\\composer\\Installer::postCreateProject": {
            "setPermission": [
                {
                    "runtime": "0777",
                    "web/assets": "0777",
                    "yii": "0755"
                }
            ],
            "generateCookieValidationKey": [
                "config/web.php"
            ]
        },
        "asset-installer-paths": {
            "npm-asset-library": "vendor/npm",
            "bower-asset-library": "vendor/bower"
        }
    }
}

While most of these items (such as the name, description, license, and require blocks) are rather self-explanatory, there are a few Yii2-specific items in here that we should take note of. The first section we want to look at is the "scripts" section:

"scripts": {
    "post-create-project-cmd": [
        "yii\\composer\\Installer::postCreateProject"
    ]
}

This script tells Composer that when the create-project command is run, it should run the postCreateProject static function. Looking at the the framework source code, we see that this file is referenced in the yii2-composer package (refer to https://github.com/yiisoft/yii2-composer/blob/master/Installer.php#L232). This command then runs several post-project creation actions, namely setting the local disk permissions, generating a unique cookie validation key, and setting some asset installer paths for composer-asset-plugin.

Next, we have the "extra" block:

"extra": {
    "yii\\composer\\Installer::postCreateProject": {
        "setPermission": [
            {
                "runtime": "0777",
                "web/assets": "0777",
                "yii": "0755"
            }
        ],
        "generateCookieValidationKey": [
            "config/web.php"
        ]
    },
    "asset-installer-paths": {
        "npm-asset-library": "vendor/npm",
        "bower-asset-library": "vendor/bower"
    }
}

This section tells Composer to use these options when it runs the postCreateProject command. These preconfigured options give us a good starting point to create our applications.

 

Configuration


With our basic application now installed, let's take a look at a few basic configuration and bootstrap files that Yii2 automatically generated for us.

Requirements checker

Projects created from yii2-app-basic now come with a built-in requirements script called requirements.php. This script checks several different values in order to ensure that Yii2 can run on our application server. Before running our application, let's run the requirements checker:

php requirements.php

You'll get output similar to the following:

Yii Application Requirement Checker
This script checks if your server configuration meets the requirements for running Yii application.
It checks if the server is running the right version of PHP,  if appropriate PHP extensions have been loaded, and if php.ini file settings are correct.
Check conclusion:
-----------------
PHP version: OK
[... more checks here ...]
-----------------------------------------
Errors: 0   Warnings: 6   Total checks: 21

In general, as long as the error count is set to 0, we'll be good to move forward. If the requirements checker notices an error, it will report it in the Check conclusion section for you to rectify.

Tip

As part of your deployment process, it is recommended that your deployment tool runs the requirements checker. This helps ensure that your application server meets all the requirements for Yii2 and that your application doesn't get deployed to a server or environment that doesn't support it.

Entry scripts

Like its predecessor, Yii Framework 2 comes with two separate entry scripts: one for web applications and the other for console applications.

Web entry script

In Yii2, the entry script for web applications has been moved from the root (/) folder to the web/ folder. In Yii1, our PHP files were stored in the protected/ directory. By moving our entry scripts to the web/ directory, Yii2 has increased the security of our application by reducing the amount of web server configuration we need to run our application. Furthermore, all public asset (JavaScript and CSS) files are now completely isolated from our source code directories. If we open up web/index.php, our entry script now looks as follows:

<?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();

Tip

Downloading the example code

The latest and most up to date copies of source code for this book is maintained on the Packt Publishing website, http://www.packtpub.com, and on GitHub at https://github.com/masteringyii, for each chapter where applicable.

While suitable for basic applications, the default entry script requires us to manually comment out and change the code when moving to different environments. Since changing the code in a nondevelopment environment doesn't follow best practices, we should change this code block so that we don't have to touch our code to move it to a different environment.

We'll start by creating a new application-wide constant called APPLICATION_ENV. This variable will be defined by either our web server or our console environment and will allow us to dynamically load different configuration files depending upon the environment that we're working in:

  1. After the opening <?php tag in web/index.php, add the following code block:

    // Define our application_env variable as provided by nginx/apache/console
    if (!defined('APPLICATION_ENV'))
    {
        if (getenv('APPLICATION_ENV') != false)
            define('APPLICATION_ENV', getenv('APPLICATION_ENV'));
        else 
           define('APPLICATION_ENV', 'prod');
    }

    Our application now knows how to read the APPLCATTION_ENV variable from the environment variable, which will be passed either though our command line or our web server configuration. By default, if no environment is set, the APPLICATION_ENV variable will be set to prod.

    Next, we'll want to load a separate environment file that contains several environmental constants that we'll use to dynamically change how our application runs in different environments:

    $env = require(__DIR__ . '/../config/env.php');

    Next, we'll configure Yii to set the YII_DEBUG and YII_ENV variables according to our application:

    defined('YII_DEBUG') or define('YII_DEBUG', $env['debug']);
    defined('YII_ENV') or define('YII_ENV', APPLICATION_ENV);
  2. Then, follow the rest of our index.php file under web/:

    require(__DIR__ . '/../vendor/autoload.php');
    require(__DIR__ . '/../vendor/yiisoft/yii2/Yii.php');
    (new yii\web\Application($config))->run();

With these changes, our web application is now configured to be aware of its environment and load the appropriate configuration files.

Note

Don't worry; later in the chapter, we'll cover how to define the APPLICATION_ENV variable for both our web server (either Apache or NGINX) and our command line.

Configuration files

In Yii2, configuration files are still split into console- and web-specific configurations. As there are many commonalities between these two files (such as our database and environment configuration), we'll store common elements in their own files and include those files in both our web and console configurations. This will help us follow the DRY standard, and reduce duplicate code within our application.

Note

The DRY (don't repeat yourself) principle in software development states that we should avoid having the same code block appear in multiple places in our application. By keeping our application DRY, we can ensure that our application is performant and can reduce bugs in our application. By moving our database and parameters' configuration to their own file, we can reuse that same code in both our web and console configuration files.

Web and console configuration files

Yii2 supports two different kinds of configuration files: one for web applications and another for console applications. In Yii2, our web configuration file is stored in config/web.php and our console configuration file is stored in config/console.php. If you're familiar with Yii1, you'll see that the basic structure of both of these files hasn't changed all that much.

Database configuration

The next file we'll want to look at is our database configuration file stored in config/db.php. This file contains all the information our web and console applications will need in order to connect to the database.

In our basic application, this file looks as follows:

<?php

return [
    'class' => 'yii\db\Connection',
    'dsn' => 'mysql:host=localhost;dbname=yii2basic',
    'username' => 'root',
    'password' => '',
    'charset' => 'utf8',
];

For an application that is aware of its environment, however, we should replace this file with a configuration that will use the APPLICATION_ENV variable that we defined earlier:

<?php return require __DIR__ . '/env/' . APPLICATION_ENV . '/db.php';

Tip

Right now, we're just setting things up. We'll cover how to set up our directories in the next section.

With this change, our application now knows that it needs to look in a file called db.php under config/env/<APPLICATION_ENV>/ to pull the correct configuration environment for that file.

Parameter configuration

In a manner similar to our database configuration file, Yii also lets us use a parameter file where we can store all of the noncomponent parameters for our application. This file is located at config/params.php. Since the basic app doesn't make this file aware of its environment, we'll change it to do that as follows:

<?php return require __DIR__ . '/env/' . APPLICATION_ENV . '/params.php';

Environment configuration

Finally, we have the environment configuration that we defined earlier when working with our entry scripts. We'll store this file in config/env.php, and it should be written as follows:

<?php return require __DIR__ . '/env/' . APPLICATION_ENV . '/env.php';

Most modern applications have several different environments depending upon their requirements. Typically, we'd break them down into four distinct environments:

  • The first environment we typically have is called DEV. This environment is where all of our local development occurs. Typically, developers have complete control over this environment and can change it, as required, to build their applications.

  • The second environment that we typically have is a testing environment called TEST. Normally, we'd deploy our application to this environment in order to make sure that our code works in a production-like setting; however, we normally would still have high log levels and debug information available to us when using this environment.

  • The third environment we typically have is called UAT, or the User Acceptance Testing environment. This is a separate environment that we'd provide to our client or business stakeholders for them to test the application to verify that it does what they want it to do.

  • Finally, in our typical setup, we'd have our PROD or production environment. This is where our code finally gets deployed to and where all of our users ultimately interact with our application.

As outlined in the previous sections, we've been pointing all of our environment configuration files to the config/env/<env> folder. Since our local environment is going to be called DEV, we'll create it first:

  1. We'll start by creating our DEV environment folder from the command line:

    mkdir –p config/env/dev
    
  2. Next, we'll create our dev database configuration file in db.php under config/env/dev/. For now, we'll stick with a basic SQLite database:

    <?php return [
        'dsn' => 'sqlite:/' . __DIR__ . '/../../../runtime/db.sqlite',
          'class' => 'yii\db\Connection',
        'charset' => 'utf8'
    ];
  3. Next, we'll create our environment configuration file in env.php under config/env/dev. If you recall from earlier in the chapter, this is where our debug flag was stored, so this file will look as follows:

    <?php return [ 
        'debug' => true
    ];
  4. Finally, we'll create our params.php file under config/env/dev/. As of now, this file will simply return an empty array:

    <?php return [];

Now, for simplicity, let's copy over this configuration to our other environments. From the command line, we can do that as follows:

cp –R config/env/dev config/env/test
cp –R config/env/dev config/env/uat
cp –R config/env/dev config/env/prod

Setting up our application environment

Now that we've told Yii what files and configurations it needs to use for each environment, we need to tell it what environment to use. To do this, we'll set custom variables in our web server configuration that will pass this option to Yii.

Setting the web environment for NGINX

With our console application properly configured, we now need to configure our web server to pass the APPLICATION_ENV variable to our application. In a typical NGINX configuration, we have a location block that looks as follows:

location ~ \.php$ {
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
        fastcgi_pass   127.0.0.1:9000;
        #fastcgi_pass unix:/var/run/php5-fpm.sock;
        try_files $uri =404;
    }

To pass the APPLICATION_ENV variable to our application, all we need to do is define a new fastcgi_param as follows:

fastcgi_param   APPLICATION_ENV "dev";

After making this change, simply restart NGINX.

Setting the web environment for Apache

We can also easily configure Apache to pass the APPLICATION_ENV variable to our application. With Apache, we typically have a VirtualHost block that looks as follows:

# Set document root to be "basic/web"
DocumentRoot "path/to/basic/web"

<Directory "path/to/basic/web">
    # use mod_rewrite for pretty URL support
    RewriteEngine on
    # If a directory or a file exists, use the request directly
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    # Otherwise forward the request to index.php
    RewriteRule . index.php

    # ...other settings...
</Directory>

To pass the APPLICATION_ENV variable to our application, all we need to do is use the SetEnv command as follows, which can be placed anywhere in our VirtualHost block:

SetEnv   APPLICATION_ENV dev

After making this change, simply restart Apache and navigate to your application.

At the most basic level, our application isn't doing anything different from what it was when we first ran the composer create-project command. Despite not doing anything different, our application is now significantly more powerful and flexible than it was before our changes. Later on in the book, we'll take a look at how these changes in particular can make automated deployments of our application a seamless and simple process.

 

Components and objects


There are two base classes that almost everything in Yii2 extends from: the Component class and the Object class.

Components

In Yii2, the Component class has replaced the CComponent class from Yii1. In Yii1, components act as service locators that host a specific set of application components that provide different services for the processing of requests. Each component in Yii2 can be accessed using the following syntax:

Yii::$app->componentID

For example, the database component can be accessed using this:

Yii::$app->db

The cache component can be accessed using this:

Yii::$app->cache

Yii2 automatically registers each component at runtime via the application configuration that we mentioned in the previous section by name.

To improve performance in Yii2 applications, components are lazy-loaded or only instantiated the first time they are accessed. This means that if the cache component is never used in your application code, the cache component will never be loaded. At times, however, this can be nonideal, so to force load a component, you can bootstrap it by adding it to the bootstrap configuration option in either config/web.php or config/console.php. For instance, if we want to bootstrap the log component, we can do that as follows:

<?php return [
    'bootstrap' => [
        'log'
    ],
    […]
]

The bootstrap option behaves in a manner similar to the preload option in Yii1—any component that you want or need to be instantiated on bootstrap will be loaded if it is in the bootstrap section of your configuration file.

Note

For more information on service locators and components, ensure that you read the Definitive Guide to Yii guide located at http://www.yiiframework.com/doc-2.0/guide-concept-service-locator.html and http://www.yiiframework.com/doc-2.0/guide-structure-application-components.html.

Objects

In Yii2, almost every class that doesn't extend from the Component class extends from the Object class. The Object class is the base class that implements the property feature. In Yii2, the property feature allows you to access a lot of information about an object, such as the __get and __set magic methods, as well as other utility functions, such as hasProperty(), canGetProperty(), and canSetProperty(). Combined, this makes objects in Yii2 extremely powerful.

Tip

The object class is extremely powerful, and many classes in Yii extend from it. Despite this, using the magic methods __get and __set yourself is not considered best practice as it is slower than a native PHP method and doesn't integrate well with your IDE's autocomplete tool and documentation tools.

 

Path aliases


In Yii2, path aliases are used to represent file paths or URL paths so that we don't hardcode paths or URLs directly into our application. In Yii2, aliases always start with the @ symbol so that Yii knows how to differentiate it from a file path or URL.

Aliases can be defined in several ways. The most basic way to define a new alias is to call \Yii::setAlias():

\Yii::setAlias('@path', '/path/to/example');
\Yii::setAlias('@example, 'https://www.example.com');

Aliases can also be defined in the application configuration file by setting the alias option as follows:

return [
    // ...
    'aliases' => [
        '@path => '/path/to/example,
        '@example' => 'https://www.example.com',
    ],
];

Also, aliases can be easily retrieved using \Yii::getAlias():

\Yii::getAlias('@path') // returns /path/to/example
\Yii::getAlias('@example') // returns https://www.example.com

Several places in Yii are alias-aware and will accept aliases as inputs. For example, yii\caching\FileCache accepts a file alias as an alias for the $cachePath parameter:

$cache = new FileCache([
    'cachePath' => '@runtime/cache',
]);

Note

For more information on path aliases, check out the Yii documentation at http://www.yiiframework.com/doc-2.0/guide-concept-aliases.html.

 

Summary


In this chapter, we went over how to create new Yii2 applications via composer. We also went over the basic configuration files that come with Yii2 as well as how to configure our web application to load environment-specific configuration files. Finally, we also covered components, objects, and path aliases, which are fundamental to gaining mastery over Yii.

In the next chapter, we'll cover everything you need to know in order to become a master of console commands and applications.

About the Author

  • Charles R. Portwood II

    Charles R. Portwood II has over 10 years of experience developing modern web applications and is well versed in integrating PHP with native mobile applications. An avid proponent of Yii Framework and open source software, Charles has contributed multiple guides, extensions, and applications to the Yii community. In addition to being a programmer, he is also a Linux system administrator.

    Browse publications by this author

Latest Reviews

(6 reviews total)
Nagyon korrekt ár, jó tartalom. Kezdőknek tökéletes.
I was looking for modern book about Yii 2 framework
Good book, I'm just amazed that in a few months time It's already sort of dated. Crazy how fast this stuff moves.
Book Title
Unlock this full book with a FREE 10-day trial
Start Free Trial