Book Image

Mastering Yii

By : Charles R. Portwood ll
Book Image

Mastering Yii

By: Charles R. Portwood ll

Overview of this book

The successor of Yii Framework 1.1, Yii 2 is a complete rewrite of Yii Framework, one of the most popular PHP 5 frameworks around 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 Yii 2.
Table of Contents (20 chapters)
Mastering Yii
Credits
About the Author
About the Reviewer
www.PacktPub.com
Preface
5
Modules, Widgets, and Helpers
13
Debugging and Deploying
Index

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.