Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Free Learning
Arrow right icon
Yii2 Application Development Cookbook
Yii2 Application Development Cookbook

Yii2 Application Development Cookbook: Discover 100 useful recipes that will bring the best out of the Yii2 framework and be on the bleeding edge of web development today , Third Edition

Arrow left icon
Profile Icon Andrew Bogdanov Profile Icon Eliseev
Arrow right icon
$19.99 per month
Full star icon Full star icon Full star icon Full star icon Half star icon 4.5 (2 Ratings)
Paperback Nov 2016 584 pages 3rd Edition
eBook
$9.99 $43.99
Paperback
$54.99
Subscription
Free Trial
Renews at $19.99p/m
Arrow left icon
Profile Icon Andrew Bogdanov Profile Icon Eliseev
Arrow right icon
$19.99 per month
Full star icon Full star icon Full star icon Full star icon Half star icon 4.5 (2 Ratings)
Paperback Nov 2016 584 pages 3rd Edition
eBook
$9.99 $43.99
Paperback
$54.99
Subscription
Free Trial
Renews at $19.99p/m
eBook
$9.99 $43.99
Paperback
$54.99
Subscription
Free Trial
Renews at $19.99p/m

What do you get with a Packt Subscription?

Free for first 7 days. $19.99 p/m after that. Cancel any time!
Product feature icon Unlimited ad-free access to the largest independent learning library in tech. Access this title and thousands more!
Product feature icon 50+ new titles added per month, including many first-to-market concepts and exclusive early access to books as they are being written.
Product feature icon Innovative learning tools, including AI book assistants, code context explainers, and text-to-speech.
Product feature icon Thousands of reference materials covering every tech concept you need to stay up to date.
Subscribe now
View plans & pricing
Table of content icon View table of contents Preview book icon Preview Book

Yii2 Application Development Cookbook

Chapter 1. Fundamentals

In this chapter, we will cover the following topics:

  • Installing the framework
  • Application templates
  • Dependency injection container
  • Service locator
  • Code generation
  • Configuring components
  • Working with events
  • Using external code

Introduction

In this chapter we will cover how to install Yii Framework and about possible techniques of installation. We will introduce you to application templates: basic and advanced and their difference between them. Then you will learn about dependency injection container. This chapter contains info about model events, which trigger after some actions such as model saving, updating and others. We will learn how to use external code which will include ZendFramework, Laravel, or Symfony. We will also be learning about how to update your yii-1.x.x based application to yii2 step-by-step.

Installing the framework

Yii2 is a modern PHP framework provided as a Composer package. In this recipe, we will install the framework via the Composer package manager and configure the database connection for our application.

Getting ready

First of all, install the Composer package manager on your system.

Note

Note: If you use the OpenServer application on Windows, than the composer command already exists in the OpenServer terminal.

In Mac or Linux download the installer from https://getcomposer.org/download/ and install it globally by using the following command:

sudo php composer-setup.php --install-dir=/usr/local/bin --filename=composer

In Windows without OpenServer download and run Composer-Setup.exe from the https://getcomposer.org/doc/00-intro.md page.

If you do not have administrative privileges on the system then as an alternative you can just download the https://getcomposer.org/composer.phar raw file and use the php composer.phar call instead of single the composer command.

After installation run in your terminal:

composer

Or (if you just download archive) its alternative:

php composer.phar

When the installation succeeds you will see the following response:

   ______
  / ____/___  ____ ___  ____  ____  ________  _____
 / /   / __ \/ __ '__ \/ __ \/ __ \/ ___/ _ \/ ___/
/ /___/ /_/ / / / / / / /_/ / /_/ (__  )  __/ /
\____/\____/_/ /_/ /_/ .___/\____/____/\___/_/
                    /_/
Composer version 1.2.0 2016-07-18 11:27:19

Right now you can install any package from the https://packagist.org repository.

How to do it…

You can install basic or advanced application templates. In order to learn about the differences between the templates see the Application templates recipe.

Note

Note that during installation the Composer package manager gets a lot of information from the GitHub site. GitHub may limit requests for anonymous users. In this case Composer asks you to input your access token. You should just register the https://github.com site and generate a new token via the https://github.com/blog/1509-personal-api-tokens guide.

Installing a basic project template

Carry out the following steps for installing basic project template:

  1. As the first step open your terminal and install Bower-to-Composer adapter:
    composer global require "fxp/composer-asset-plugin:^1.2.0"
    

    It provides a simple way to load related non-PHP packages (JavaScript and CSS) from the Bower repository.

  2. Create a new application in the new basic directory:
    composer create-project --prefer-dist yiisoft/yii2-app-basic basic
    
  3. Check that your PHP contains the required extensions:
    cd basic
    php requirements.php
    

    Note

    Note: PHP in command-mode and in web-interface mode can use different php.ini files with different configurations and different extensions.

  4. Create a new database (if it is needed for your project) and configure it in the config/db.php file.
  5. Try to run application via the following console command:
    php yii serve
    
  6. Check in your browser that the application works by the http://localhost:8080 address:
    Installing a basic project template

For permanent working create a new host in your server (Apache, Nginx, and so on) and set the web directory as a document root of the host.

Installing advanced project template

Carry out the following steps for installing advanced project template:

  1. As the first step open your terminal install Bower-to-Composer adapter:
    composer global require "fxp/composer-asset-plugin:^1.2.0"
    

    It provides a simple way to load related non-PHP packages (JavaScript and CSS) from the Bower repository.

  2. Create a new application in the new basic directory:
    composer create-project --prefer-dist yiisoft/yii2-app-advanced advanced
    
  3. The new application does not contains local configuration files and index.php entry scripts yet. To generate the files just init a working environment:
    cd advanced
    php init
    

    During initialization select the Development environment.

  4. Check that your PHP contains the required extensions:
    php requirements.php
    

    Note

    Note: PHP in command-line mode and in web-interface mode can use different php.ini files with different configuration and different extensions.

  5. Create a new database and configure it in the generated common/config/main-local.php file.
  6. Apply the application migrations:
    php yii migrate
    

    This command will automatically create a user table in your database.

  7. Try to run a frontend application by the following console command:
    php yii serve --docroot=@frontend/web --port=8080
    

    Then run the backend in an other terminal window:

    php yii serve --docroot=@backend/web --port=8090
    
  8. Check in your browser that the application works via the http://localhost:8080 and http://localhost:8090 addresses:
    Installing advanced project template

Create two new hosts for backend and frontend application in your server (Apache, Nginx, and so on) and set the backend/web and frontend/web directories as document roots of the hosts.

How it works…

First of all, we installed the Composer package manager and the Bower asset plugin.

After we installed the application via the composer create-project command, the command creates a new empty directory, clones the source code of application template and loads all its inner dependencies (framework and other components) into the vendor subdirectory.

If needed, we will initialize application configuration and set up a new database.

We can check system requirements via running the requirements.php script in console or browser mode.

And after cloning of the code we can configure our own PHP server to work with the web directories as the server's document roots.

See also

Application templates

Yii2 has two application templates for development: basic and advanced. What is the difference between basic and advanced templates?

The names are confusing. Some people in the end choose basic because advanced may sound repulsive. In this chapter we will look at the differences.

How to do it…

Please refer to the Installing the framework recipe's How to do it… section to understand and learn how to install different templates.

How it works…

The advanced template has a custom system of configurations. It is developed so that a team can work together on a project but each developer can customize their own configurations for development, testing, and other environments.

Configuration environments can be complicated and normally aren't used when you develop alone.

The advanced template has frontend and backend folders for the frontend and backend parts of the web application accordingly. So you can configure a separate host for each folder and thereby isolate the frontend and backend part.

This is a simple way to organize files into directories and configure the web server. You can easily do the same thing in the basic template.

Neither front/back-end separation nor user management is on its own a good reason to choose the advanced template. It's better to adapt these features to your app—you'll learn more and won't get the difficult config problem.

If you will be working on the project with a team and you might need configuration flexibility, use different environments to develop and in this case a better choice would be the advanced application template. If you will be working alone and your project is simple you should choose the basic application template.

Dependency injection container

Dependency Inversion Principle (DIP) suggests we create modular low-coupling code with the help of extracting clear abstraction subsystems.

For example, if you want to simplify a big class you can split it into many chunks of routine code and extract every chunk into a new simple separated class.

The principle says that your low-level chunks should implement an all-sufficient and clear abstraction, and high-level code should work only with this abstraction and not low-level implementation.

When we split a big multitask class into small specialized classes, we face the issue of creating dependent objects and injecting them into each other.

If we could create one instance before:

$service = new MyGiantSuperService();

And after splitting we will create or get all dependent items and build our service:

$service = new MyService(
    new Repository(new PDO('dsn', 'username', 'password')),
    new Session(),
    new Mailer(new SmtpMailerTransport('username', 'password', host')),
    new Cache(new FileSystem('/tmp/cache')),
);

Dependency injection container is a factory that allows us to not care about building our objects. In Yii2 we can configure a container only once and use it for retrieving our service like this:

$service = Yii::$container->get('app\services\MyService')

We can also use this:

$service = Yii::createObject('app\services\MyService')

Or we ask the container to inject it as a dependency in the constructor of an other service:

use app\services\MyService;
class OtherService
{
    public function __construct(MyService $myService) { … }
}

When we will get the OtherService instance:

$otherService = Yii::createObject('app\services\OtherService')

In all cases the container will resolve all dependencies and inject dependent objects in each other.

In the recipe we create shopping cart with storage subsystem and inject the cart automatically into controller.

Getting ready

Create a new application by using the Composer package manager, as described in the official guide at http://www.yiiframework.com/doc-2.0/guide-startinstallation.html.

How to do it…

Carry out the following steps:

  1. Create a shopping cart class:
    <?php
    namespace app\cart;
    
    use app\cart\storage\StorageInterface;
    
    class ShoppingCart
    {
        private $storage;
    
        private $_items = [];
    
        public function __construct(StorageInterface $storage)
        {
            $this->storage = $storage;
        }
    
        public function add($id, $amount)
        {
            $this->loadItems();
            if (array_key_exists($id, $this->_items)) {
                $this->_items[$id]['amount'] += $amount;
            } else {
                $this->_items[$id] = [
                    'id' => $id,
                    'amount' => $amount,
                ];
            }
            $this->saveItems();
        }
    
        public function remove($id)
        {
            $this->loadItems();
            $this->_items = array_diff_key($this->_items, [$id => []]);
            $this->saveItems();
        }
    
        public function clear()
        {
            $this->_items = [];
            $this->saveItems();
        }
    
        public function getItems()
        {
            $this->loadItems();
            return $this->_items;
        }
    
        private function loadItems()
        {
            $this->_items = $this->storage->load();
        }
    
        private function saveItems()
        {
            $this->storage->save($this->_items);
        }
    }
  2. It will work only with own items. Instead of built-in storing items to session it will delegate this responsibility to any external storage class, which will implement the StorageInterface interface.
  3. The cart class just gets the storage object in its own constructor, saves it instance into private $storage field and calls its load() and save() methods.
  4. Define a common cart storage interface with the required methods:
    <?php
    namespace app\cart\storage;
    
    interface StorageInterface
    {
        /**
        * @return array of cart items
        */
        public function load();
    
        /**
        * @param array $items from cart
        */
        public function save(array $items);
    }
  5. Create a simple storage implementation. It will store selected items in a server session:
    <?php
    namespace app\cart\storage;
    
    use yii\web\Session;
    
    class SessionStorage implements StorageInterface
    {
        private $session;
        private $key;
    
        public function __construct(Session $session, $key)
        {
            $this->key = $key;
            $this->session = $session;
        }
    
        public function load()
        {
            return $this->session->get($this->key, []);
        }
    
        public function save(array $items)
        {
            $this->session->set($this->key, $items);
        }
    }
  6. The storage gets any framework session instance in the constructor and uses it later for retrieving and storing items.
  7. Configure the ShoppingCart class and its dependencies in the config/web.php file:
    <?php
    use app\cart\storage\SessionStorage;
    
    Yii::$container->setSingleton('app\cart\ShoppingCart');
    
    Yii::$container->set('app\cart\storage\StorageInterface', function() {
        return new SessionStorage(Yii::$app->session, 'primary-cart');
    });
    
    $params = require(__DIR__ . '/params.php');
    
    //…
  8. Create the cart controller with an extended constructor:
    <?php
    namespace app\controllers;
    
    use app\cart\ShoppingCart;
    use app\models\CartAddForm;
    use Yii;
    use yii\data\ArrayDataProvider;
    use yii\filters\VerbFilter;
    use yii\web\Controller;
    
    class CartController extends Controller
    {
        private $cart;
    
        public function __construct($id, $module, ShoppingCart $cart, $config = [])
        {
            $this->cart = $cart;
            parent::__construct($id, $module, $config);
        }
    
        public function behaviors()
        {
            return [
                'verbs' => [
                    'class' => VerbFilter::className(),
                    'actions' => [
                        'delete' => ['post'],
                    ],
                ],
            ];
        }
    
        public function actionIndex()
        {
            $dataProvider = new ArrayDataProvider([
                'allModels' => $this->cart->getItems(),
            ]);
    
            return $this->render('index', [
                'dataProvider' => $dataProvider,
            ]);
        }
    
        public function actionAdd()
        {
            $form = new CartAddForm();
    
            if ($form->load(Yii::$app->request->post()) && $form->validate()) {
                $this->cart->add($form->productId, $form->amount);
                return $this->redirect(['index']);
            }
    
            return $this->render('add', [
                'model' => $form,
            ]);
        }
    
        public function actionDelete($id)
        {
            $this->cart->remove($id);
    
            return $this->redirect(['index']);
        }
    }
  9. Create a form:
    <?php
    namespace app\models;
    
    use yii\base\Model;
    
    class CartAddForm extends Model
    {
        public $productId;
        public $amount;
    
        public function rules()
        {
            return [
                [['productId', 'amount'], 'required'],
                [['amount'], 'integer', 'min' => 1],
            ];
        }
    }
  10. Create the views/cart/index.php view:
    <?php
    use yii\grid\ActionColumn;
    use yii\grid\GridView;
    use yii\grid\SerialColumn;
    use yii\helpers\Html;
    
    /* @var $this yii\web\View */
    /* @var $dataProvider yii\data\ArrayDataProvider */
    
    $this->title = 'Cart';
    $this->params['breadcrumbs'][] = $this->title;
    ?>
    <div class="cart-index">
        <h1><?= Html::encode($this->title) ?></h1>
    
        <p><?= Html::a('Add Item', ['add'], ['class' => 'btn btn-success']) ?></p>
    
        <?= GridView::widget([
            'dataProvider' => $dataProvider,
            'columns' => [
                ['class' => SerialColumn::className()],
    
                'id:text:Product ID',
                'amount:text:Amount',
    
                [
                    'class' => ActionColumn::className(),
                    'template' => '{delete}',
                ]
            ],
        ]) ?>
    </div>
  11. Create the views/cart/add.php view:
    <?php
    use yii\helpers\Html;
    use yii\bootstrap\ActiveForm;
    
    /* @var $this yii\web\View */
    /* @var $form yii\bootstrap\ActiveForm */
    /* @var $model app\models\CartAddForm */
    
    $this->title = 'Add item';
    $this->params['breadcrumbs'][] = ['label' => 'Cart', 'url' => ['index']];
    $this->params['breadcrumbs'][] = $this->title;
    ?>
    <div class="cart-add">
        <h1><?= Html::encode($this->title) ?></h1>
    
        <?php $form = ActiveForm::begin(['id' => 'contact-form']); ?>
            <?= $form->field($model, 'productId') ?>
            <?= $form->field($model, 'amount') ?>
            <div class="form-group">
                <?= Html::submitButton('Add', ['class' => 'btn btn-primary']) ?>
            </div>
        <?php ActiveForm::end(); ?>
    </div>
  12. Add link items into the main menu:
    ['label' => 'Home', 'url' => ['/site/index']],
    ['label' => 'Cart', 'url' => ['/cart/index']],
    ['label' => 'About', 'url' => ['/site/about']],
    // …
  13. Open the cart page and try to add rows:
    How to do it…

How it works…

In this case we have the main ShoppingCart class with a low-level dependency, defined by an abstraction interface:

class ShoppingCart
{
    public function __construct(StorageInterface $storage) { … }
}

interface StorageInterface
{
   public function load();
   public function save(array $items);
}

And we have some an implementation of the abstraction:

class SessionStorage implements StorageInterface
{
    public function __construct(Session $session, $key) { … }
}

Right now we can create an instance of the cart manually like this:

$storage = new SessionStorage(Yii::$app->session, 'primary-cart');
$cart = new ShoppingCart($storage)

It allows us to create a lot of different implementations such as SessionStorage, CookieStorage, or DbStorage. And we can reuse the framework-independent ShoppingCart class with StorageInterface in different projects and different frameworks. We must only implement the storage class with the interface's methods for needed framework.

But instead of manually creating an instance with all dependencies, we can use a dependency injection container.

By default the container parses the constructors of all classes and recursively creates all the required instances. For example, if we have four classes:

class A {
     public function __construct(B $b, C $c) { … }
}

class B {
    ...
}

class C {
    public function __construct(D $d) { … }
}

class D {
    ...
}

We can retrieve the instance of class A in two ways:

$a = Yii::$container->get('app\services\A')
// or
$a = Yii::createObject('app\services\A')

And the container automatically creates instances of the B, D, C, and A classes and injects them into each other.

In our case we mark the cart instance as a singleton:

Yii::$container->setSingleton('app\cart\ShoppingCart');

This means that the container will return a single instance for every repeated call instead of creating the cart again and again.

Besides, our ShoppingCart has the StorageInterface type in its own constructor and the container does know what class it must instantiate for this type. We must manually bind the class to the interface like this:

Yii::$container->set('app\cart\storage\StorageInterface', 'app\cart\storage\CustomStorage',);

But our SessionStorage class has non-standard constructor:

class SessionStorage implements StorageInterface
{
    public function __construct(Session $session, $key) { … }
}

Therefore we use an anonymous function to manually creatie the instance:

Yii::$container->set('app\cart\storage\StorageInterface', function() {
    return new SessionStorage(Yii::$app->session, 'primary-cart');
});

And after all we can retrieve the cart object from the container manually in our own controllers, widgets, and other places:

$cart = Yii::createObject('app\cart\ShoppingCart')

But every controller and other object will be created via the createObject method inside the framework. And we can use injection of cart via the controller constructor:

class CartController extends Controller
{
    private $cart;

    public function __construct($id, $module, ShoppingCart $cart, $config = [])
    {
        $this->cart = $cart;
        parent::__construct($id, $module, $config);
    }

    // ...
}

Use this injected cart object:

public function actionDelete($id)
{
    $this->cart->remove($id);
    return $this->redirect(['index']);
}

See also

Service locator

Instead of manually creating instances of different shared services (application components) we can get them from a special global object, which contains configurations and instances of all components.

A service locator is a global object that contains a list of components or definitions, uniquely identified by an ID, and allow us to retrieve any needed instance by its ID. The locator creates a single instance of the component on-the-fly at the first call and returns a previous instance at the subsequent calls.

In this recipe, we will create a shopping cart component and will write a cart controller for working with it.

Getting ready

Create a new application by using the Composer package manager, as described in the official guide at http://www.yiiframework.com/doc-2.0/guide-start-installation.html.

How to do it…

Carry out the following steps to create a shopping cart component:

  1. Create a shopping cart component. It will store selected items in a user session:
    <?php
    namespace app\components;
    
    use Yii;
    use yii\base\Component;
    
    class ShoppingCart extends Component
    {
        public $sessionKey = 'cart';
    
        private $_items = [];
    
        public function add($id, $amount)
        {
            $this->loadItems();
            if (array_key_exists($id, $this->_items)) {
                $this->_items[$id]['amount'] += $amount;
            } else {
                $this->_items[$id] = [
                    'id' => $id,
                    'amount' => $amount,
                ];
            }
           $this->saveItems();
        }
    
        public function remove($id)
        {
            $this->loadItems();
            $this->_items = array_diff_key($this->_items, [$id => []]);
            $this->saveItems();
        }
    
        public function clear()
        {
            $this->_items = [];
            $this->saveItems();
        }
    
        public function getItems()
        {
            $this->loadItems();
            return $this->_items;
        }
    
        private function loadItems()
        {
            $this->_items = Yii::$app->session->get($this->sessionKey, []);
        }
    
        private function saveItems()
        {
            Yii::$app->session->set($this->sessionKey, $this->_items);
        }
    }
  2. Register the ShoppingCart in service locator as an application component in the config/web.php file:
    'components' => [
        …
        'cart => [
            'class' => 'app\components\ShoppingCart',
            'sessionKey' => 'primary-cart',
        ],
    ]
  3. Create a cart controller:
    <?php
    namespace app\controllers;
    
    use app\models\CartAddForm;
    use Yii;
    use yii\data\ArrayDataProvider;
    use yii\filters\VerbFilter;
    use yii\web\Controller;
    
    class CartController extends Controller
    {
        public function behaviors()
        {
            return [
                'verbs' => [
                    'class' => VerbFilter::className(),
                    'actions' => [
                        'delete' => ['post'],
                    ],
                ],
            ];
        }
    
        public function actionIndex()
        {
            $dataProvider = new ArrayDataProvider([
                'allModels' => Yii::$app->cart->getItems(),
            ]);
    
            return $this->render('index', [
                'dataProvider' => $dataProvider,
            ]);
        }
    
        public function actionAdd()
        {
            $form = new CartAddForm();
    
            if ($form->load(Yii::$app->request->post()) && $form->validate()) {
                Yii::$app->cart->add($form->productId, $form->amount);
                return $this->redirect(['index']);
            }
    
            return $this->render('add', [
                'model' => $form,
            ]);
        }
    
        public function actionDelete($id)
        {
            Yii::$app->cart->remove($id);
    
            return $this->redirect(['index']);
        }
    }
  4. Create a form:
    <?php
    namespace app\models;
    
    use yii\base\Model;
    
    class CartAddForm extends Model
    {
        public $productId;
        public $amount;
    
        public function rules()
        {
            return [
                [['productId', 'amount'], 'required'],
                [['amount'], 'integer', 'min' => 1],
            ];
        }
    }
  5. Create the views/cart/index.php view:
    <?php
    use yii\grid\ActionColumn;
    use yii\grid\GridView;
    use yii\grid\SerialColumn;
    use yii\helpers\Html;
    
    /* @var $this yii\web\View */
    /* @var $dataProvider yii\data\ArrayDataProvider */
    
    $this->title = 'Cart';
    $this->params['breadcrumbs'][] = $this->title;
    ?>
    <div class="site-contact">
        <h1><?= Html::encode($this->title) ?></h1>
    
        <p><?= Html::a('Add Item', ['add'], ['class' => 'btn btn-success']) ?></p>
    
        <?= GridView::widget([
            'dataProvider' => $dataProvider,
            'columns' => [
                ['class' => SerialColumn::className()],
    
                'id:text:Product ID',
                'amount:text:Amount',
    
                [
                   'class' => ActionColumn::className(),
                   'template' => '{delete}',
                ]
            ],
        ]) ?>
    </div>
  6. Create the views/cart/add.php view:
    <?php
    use yii\helpers\Html;
    use yii\bootstrap\ActiveForm;
    
    /* @var $this yii\web\View */
    /* @var $form yii\bootstrap\ActiveForm */
    /* @var $model app\models\CartAddForm */
    
    $this->title = 'Add item';
    $this->params['breadcrumbs'][] = ['label' => 'Cart', 'url' => ['index']];
    $this->params['breadcrumbs'][] = $this->title;
    ?>
    <div class="site-contact">
        <h1><?= Html::encode($this->title) ?></h1>
    
        <?php $form = ActiveForm::begin(['id' => 'contact-form']); ?>
            <?= $form->field($model, 'productId') ?>
            <?= $form->field($model, 'amount') ?>
            <div class="form-group">
                <?= Html::submitButton('Add', ['class' => 'btn btn-primary']) ?>
            </div>
        <?php ActiveForm::end(); ?>
    </div>
  7. Add a link item into the main menu:
    ['label' => 'Home', 'url' => ['/site/index']],
    ['label' => 'Cart', 'url' => ['/cart/index']],
    ['label' => 'About', 'url' => ['/site/about']],
    // …
  8. Open the cart page and try to add rows:
    How to do it…

How it works…

First of all we created our own class with a public sessionKey option:

<?php
namespace app\components;
use yii\base\Component;

class ShoppingCart extends Component
{
    public $sessionKey = 'cart';

    // …
}

Secondly, we added the component definition into the components section of the configuration file:

'components' => [
    …
    'cart => [
        'class' => 'app\components\ShoppingCart',
        'sessionKey' => 'primary-cart',
    ],
]

Right now we can retrieve the component instance in two ways:

$cart = Yii::$app->cart;
$cart = Yii::$app->get('cart');

And we can use this object in our own controllers, widgets, and other places.

When we call any component such as cart:

Yii::$app->cart

We call the virtual property of the Application class instance in the Yii::$app static variable. But the yii\base\Application class extends the yii\base\Module class, which extends the yii\di\ServiceLocator class with the __get magic method. This magic method just calls the get() method of the yii\di\ServiceLocator class:

namespace yii\di;

class ServiceLocator extends Component
{
    private $_components = [];
    private $_definitions = [];

    public function __get($name)
    {
        if ($this->has($name)) {
            return $this->get($name);
        } else {
            return parent::__get($name);
        }
    }
    // …
}

As a result it is an alternative to directly calling the service via the get method:

Yii::$app->get('cart);

When we get a component from the get method of service locator, the locator finds needed definition in its _definitions list and if successful it creates a new object by the definition on the fly, registers it in its own list of complete instances _components and returns the object.

If we get some component, multiplying the locator will always return the previous saved instance again and again:

$cart1 = Yii::$app->cart;
$cart2 = Yii::$app->cart;
var_dump($cart1 === $cart2); // bool(true)

It allows us to use the shared single cart instance Yii::$app->cart or single database connection Yii::$app->db instead of creating one large set from scratch again and again.

See also

Code generation

Yii2 provides the powerful module Gii to generate models, controllers, and views, which you can easily modify and customize. It's a really helpful tool for fast and quick development.

In this section we will explore how to use Gii and generate code. For example you have a database with one table named film and you would like to create an application with CRUD operations for this table. It's easy.

Getting ready

  1. Create a new application by using composer as described in the official guide at http://www.yiiframework.com/doc-2.0/guide-start-installation.html.
  2. Download the Sakila database from http://dev.mysql.com/doc/index-other.html.
  3. Execute the downloaded SQLs: first the schema then the data.
  4. Configure the database connection in config/main.php to use the Sakila database.
  5. Run your web-server by ./yii serve.

How to do it…

  1. Go to http://localhost:8080/index.php?r=gii and select Model Generator.
  2. Fill out Table Name as actor and Model Class as Actor and press button Generate at the bottom of page.
    How to do it…
  3. Return tothe main Gii menu by clicking the yii code generator logo on the header and choose CRUD Generator.
  4. Fill out the Model Class field as app\models\Actor and Controller Class as app\controllers\ActorController.
    How to do it…
  5. Press the Preview button at the bottom of page and then press green button Generate.
  6. Check the result via http://localhost:8080/index.php?actor/create.
    How to do it…

How it works…

If you check your project structure you will see autogenerated code:

How it works…

Firstly we've created an Actor model. Gii automatically creates all model rules which depends on mysql field types. For example, if in your MySQL actor table's fields first_name and last_name have IS NOT NULL flag then Yii automatically creates rule for it required and sets max length 45 symbols because in our database max length of this field is set up as 45.

public function rules()
{
    return [
        [['first_name', 'last_name'], 'required'],
        [['last_update'], 'safe'],
        [['first_name', 'last_name'], 'string', 'max' => 45],
    ];
}

Also Yii creates relationship between models automatically, based on foreign keys you added to your database. In our case two relations were created automatically.

public function getFilmActors()
{
    return $this->hasMany(FilmActor::className(), ['actor_id' => 'actor_id']);
}

public function getFilms()
{
    return $this->hasMany(Film::className(), ['film_id' => 'film_id'])->viaTable('film_actor', ['actor_id' => 'actor_id']);
}

This relationship has been created because we have two foreign keys in our database. The film_actor table has foreign key fk_film_actor_actor which points to actor table fields actor_id and fk_film_actor_film which points to film table field film_id.

Notice that you haven't generated FilmActor model yet. So if you would develop full-app versus demo you had to generate Film, FilmActor models also. For the rest of the pieces, refer to http://www.yiiframework.com/doc-2.0/guide-start-gii.html.

Configuring components

Yii is a very customizable framework. Moreover, as in all customizable code, there should be a convenient way to set up different application parts. In Yii, this is provided through configuration files located at config.

Getting ready

Create a new application by using the Composer package manager as described in the official guide at http://www.yiiframework.com/doc-2.0/guide-startinstallation.html.

How to do it…

If you have worked with Yii before, then you have probably configured a database connection:

return [
    …
    'components' => [
        'db' => [
            'class' => 'system.db.CDbConnection',
            'dsn' => 'mysql:host=localhost;dbname=database_name',
            'username' => 'root',
            'password' => '',
            'charset' => 'utf8',
        ],
        …
    ],
    …
];

This way of configuring components is used when you want to use a component across all application parts. With the preceding configuration, you can access a component by its name, such as Yii::$app->db.

How it works…

When you are using the Yii::$app->db component for the first time directly or through an Active Record model, Yii creates a component and initializes its public properties with the corresponding values provided in db array under the components section of the application configuration file. In the preceding code, dsn value will be assigned to yii\db\Connection::dsn, username will be assigned to Connection::username, and so on.

If you want to find out what charset stands for or want to know what else you can configure in the db component, then you need to know its class. In the case of the db component, the class is yii\db\Connection. You can just open the class and look for its public properties, which you can set from config.

In the preceding code, the class property is a bit special because it is used to specify the component class name. It does not exist in the yii\db\Connection class. Therefore, it can be used to override a class as follows:

return [
    …
    'components' => [
        'db' => [
            'class' => app\components\MyConnection',
            …
        ],
        …
    ],
     …
);

This way, you can override each application component; this is very useful whenever a standard component does not fit your application.

Built-in components

Now, let's find out which standard Yii application components you can configure. There are two application types bundled with Yii:

  • Web application (yii\web\Application)
  • Console application (yii\console\Application)

Both are extended from yii\base\Application, so both console and web applications share its components.

You can get the component names from the source code of the coreComponents() application's method.

You can add your own application components (classes extended from yii\base\Component) by simply adding new configuration items and pointing their class properties to your custom classes.

See also

Working with events

Yii's events provide a simple implementation, which allows you to listen and subscribe to various events that occur in your web-application. For example, you may wish to send a notification about a new article to followers each time you publish new material.

Getting ready

  1. Create a new application by using the Composer package manager, as described in the official guide at http://www.yiiframework.com/doc-2.0/guide-start-installation.html.
  2. Execute the following SQL code on your server to create the article table:
    CREATE TABLE `article` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `name` varchar(255) DEFAULT NULL,
    `description` TEXT,
    PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  3. Generate the Article model using Gii.
  4. Run your webserver by ./yii serve command.

How to do it…

  1. Add an action test to \controllers\SiteController:
    public function actionTest()
    {
        $article = new Article();
        $article->name = 'Valentine\'s Day\'s coming? Aw crap! I forgot to get a girlfriend again!';
        $article->description = 'Bender is angry at Fry for dating a robot. Stay away from our women.
        You\'ve got metal fever, boy. Metal fever';
    
        // $event is an object of yii\base\Event or a child class
        $article->on(ActiveRecord::EVENT_AFTER_INSERT, function($event) {
            $followers = ['john2@teleworm.us', 'shivawhite@cuvox.de', 'kate@dayrep.com' ];
            foreach($followers as $follower) {
                Yii::$app->mailer->compose()
                    ->setFrom('techblog@teleworm.us')
                    ->setTo($follower)
                    ->setSubject($event->sender->name)
                    ->setTextBody($event->sender->description)
                    ->send();
            }
            echo 'Emails has been sent';
        });
    
        if (!$article->save()) {
            echo VarDumper::dumpAsString($article->getErrors());
        };
    }
  2. Update the config/web.php component mailer using the following code.
    'mailer' => [
        'class' => 'yii\swiftmailer\Mailer',
        'useFileTransport' => false,
    ],
  3. Run this URL in your browser: http://localhost:8080/index.php?r=site/test.
  4. Also check http://www.fakemailgenerator.com/inbox/teleworm.us/john2/.
    How to do it…

How it works…

We've created an Article model and added a handler for the ActiveRecord::EVENT_AFTER_INSERT event to our Article model. It means that every time we save a new article an event is triggered and our attached handler will be called.

In the real-world, we would like to notify our blog followers each time we publish a new article. In a real application we would have a follower or user table and with different blog sections not only single blog. In this example, after saving our model we notify our followers john2@teleworm.us, shivawhite@cuvox.de, and kate@dayrep.com. In the last step we just prove that users have received our notifications, particularly john2. You can create your own event with any name. In this example we use a built-in event called ActiveRecord::EVENT_AFTER_INSERT, which is called after each insert to the database.

For example, we can create our own event. Just add a new actionTestNew with the following code:

public function actionTestNew()
{
    $article = new Article();
    $article->name = 'Valentine\'s Day\'s coming? Aw crap! I forgot to get a girlfriend again!';
    $article->description = 'Bender is angry at Fry for dating a robot. Stay away from our women.
    You've got metal fever, boy. Metal fever';

    // $event is an object of yii\base\Event or a child class
    $article->on(Article::EVENT_OUR_CUSTOM_EVENT, function($event) {
        $followers = ['john2@teleworm.us', 'shivawhite@cuvox.de', 'kate@dayrep.com' ];
        foreach($followers as $follower) {
            Yii::$app->mailer->compose()
                ->setFrom('techblog@teleworm.us')
                ->setTo($follower)
                ->setSubject($event->sender->name)
                ->setTextBody($event->sender->description)
                ->send();
        }
        echo 'Emails have been sent';
    });

    if ($article->save()) {
        $article->trigger(Article::EVENT_OUR_CUSTOM_EVENT);
    }
}

Also add the EVENT_OUR_CUSTOM_EVENT constant to models/Article as:

class Article extends \yii\db\ActiveRecord
{
    CONST EVENT_OUR_CUSTOM_EVENT = 'eventOurCustomEvent';
…
}

Run http://localhost:8080/index.php?r=site/test-new.

You should see the same result and all notifications to followers will be sent again. The main difference is we used our custom event name.

After the save, we've triggered our event. Events may be triggered by calling the yii\base\Component::trigger() method. The method requires an event name, and optionally an event object that describes the parameters to be passed to the event handlers.

See also

For more information about events refer to http://www.yiiframework.com/doc-2.0/guide-concept-events.html

Using external code

Package repositories, PSR standards, and social coding provide us with lots of high-quality reusable libraries and other components with free licenses. We can just install any external component in project instead of reengineering them from scratch. It improves development performance and makes for higher-quality code.

Getting ready

Create a new application by using the Composer package manager as described in the official guide at http://www.yiiframework.com/doc-2.0/guide-start-installation.html.

How to do it…


In this recipe we will try to attach some libraries manually and via Composer.

Installing a library via Composer

When you use NoSQL or other databases without autoincrement primary keys, you must generate unique identifiers manually. For example, you can use Universally Unique Identifier (UUID) instead of a numerical one. Let's do it:

  1. Install https://github.com/ramsey/uuid component via Composer:
    composer require ramsey/uuid
    
  2. Create a demonstration console controller:
    <?php
    namespace app\commands;
    
    use Ramsey\Uuid\Uuid;
    use yii\console\Controller;
    
    class UuidController extends Controller
    {
        public function actionGenerate()
        {
            $this->stdout(Uuid::uuid4()->toString() . PHP_EOL);
            $this->stdout(Uuid::uuid4()->toString() . PHP_EOL);
            $this->stdout(Uuid::uuid4()->toString() . PHP_EOL);
            $this->stdout(Uuid::uuid4()->toString() . PHP_EOL);
            $this->stdout(Uuid::uuid4()->toString() . PHP_EOL);
        }
    }
  3. And just run it:
    ./yii uuid/generate
  4. If successful, you'll see the following output:
    25841e6c-6060-4a81-8368-4d99aa3617dd
    fcac910a-a9dc-4760-8528-491c17591a26
    4d745da3-0a6c-47df-aee7-993a42ed915c
    0f3e6da5-88f1-4385-9334-b47d1801ca0f
    21a28940-c749-430d-908e-1893c52f1fe0
  5. That's it! Now you can use the Ramsey\Uuid\Uuid class in your project.

Installing libraries manually

We can install a library automatically when it is provided as a Composer package. In other cases we must install it manually.

For example, create some library examples:

  1. Create the awesome/namespaced/Library.php file with the following code:
    <?php
    namespace awesome\namespaced;
    
    class Library
    {
        public function method()
        {
            return 'I am an awesome library with namespace.';
        }
    }
  2. Create the old/OldLibrary.php file:
    <?php
    class OldLibrary
    {
        function method()
        {
            return 'I am an old library without namespace.';
        }
    }
  3. Create a set of functions as an old/functions.php file:
    <?php
    function simpleFunction()
    {
        return 'I am a simple function.';
    }

    And now set up this file in our application:

  4. Define the new alias for the awesome library namespace root in the config/web.php file (in aliases section):
    $config = [
        'id' => 'basic',
        'basePath' => dirname(__DIR__),
        'bootstrap' => ['log'],
        'aliases' => [
            '@awesome' => '@app/awesome',
        ],
        'components' => [
            // …
        ],
        'params' => // …
    ];

    or via the setAlias method:

    Yii::setAlias('@awesome', '@app/awesome');
  5. Define a simple class file path at the top of the config/web.php file:
    Yii::$classMap['OldLibrary'] = '@old/OldLibrary.php';
  6. Configure autoloading of the functions.php file in composer.json:
    "require-dev": {
        ...
    },
    "autoload": {
        "files": ["old/functions.php"]
    },
    "config": {
        ...
    },

    And apply the changes:

    composer update
    
  7. And now create an example controller:
    <?php
    namespace app\controllers;
    
    use yii\base\Controller;
    
    class LibraryController extends Controller
    {
        public function actionIndex()
        {
            $awesome = new \awesome\namespaced\Library();
            echo '<pre>' . $awesome->method() . '</pre>';
    
            $old = new \OldLibrary();
            echo '<pre>' . $old->method() . '</pre>';
    
            echo '<pre>' . simpleFunction() . '</pre>';
        }
    }

    And open the page:

    Installing libraries manually

Using Yii2 code in other frameworks

If you want to use Yii2 framework code with other frameworks just add Yii2-specific parameters in composer.json:

{
    ...
    "extra": {
        "asset-installer-paths": {
            "npm-asset-library": "vendor/npm",
            "bower-asset-library": "vendor/bower"
        }
    }
}

And install the framework:

composer require yiisoft/yii2

Now open the entry script of your application (on ZendFramework, Laravel, Symfony, and many more), require the Yii2 autoloader, and create the Yii application instance:

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

That's it! Now you can use Yii::$app instances, models, widgets and other components from Yii2.

How it works…

In the first case we just install a new Composer package in our project and use it, because its composer.json file defines all aspects of autoloading library files.

But in the second case we did not have Composer packages and registered the files in the autoloading mechanism manually. In Yii2 we can use aliases and Yii::$classMap for registering the roots of PSR-4 namespaces and for single files.

But as an alternative we can use Composer autoloader for all cases. Just define an extended autoload section in the composer.json file like this:

"autoload": {
    "psr-0": { "": "old/" },
    "psr-4": {"awesome\\": "awesome/"},
    "files": ["old/functions.php"]
}

Apply the changes using this command:

composer update

Right now you can remove aliases and $classMap definitions from your configuration files and ensure the example page still works correctly:

How it works…

This example completely uses Composer's autoloader instead of the framework's autoloader.

See also

Left arrow icon Right arrow icon

Key benefits

  • • Learn how to use Yii2 efficiently through clear examples and core features, and see how to use tests, create reusable code snippets, core widgets, deployment, and more
  • • This book provides you with a wide space for practice approaches and helps you to learn about the new Yii2 framework.
  • • Understand the difference between the Yii 1.x.x versions using useful examples from real web applications

Description

Yii is a free, open source web application development framework written in PHP5 that promotes clean DRY design and encourages rapid development. It works to streamline your application development time and helps to ensure an extremely efficient, extensible, and maintainable end product. Being extremely performance optimized, Yii is a perfect choice for any size project. However, it has been built with sophisticated, enterprise applications in mind. You have full control over the configuration from head-to-toe (presentation-to-persistence) to conform to your enterprise development guidelines. It comes packaged with tools to help test and debug your application, and has clear and comprehensive documentation. This book is a collection of Yii2 recipes. Each recipe is represented as a full and independent item, which showcases solutions from real web-applications. So you can easily reproduce them in your environment and learn Yii2 fast and without tears. All recipes are explained with step-by-step code examples and clear screenshots. Yii2 is like a suit that looks great off the rack, but is also very easy to tailor to fit your needs. Virtually every component of the framework is extensible. This book will show how to use official extensions, extend any component, or write a new one. This book will help you create modern web applications quickly, and make sure they perform well using examples and business logic from real life. You will deal with the Yii command line, migrations, and assets. You will learn about role-based access, security, and deployment. We’ll show you how to easily get started, configure your environment, and be ready to write web applications efficiently and quickly.

Who is this book for?

This book is for developers with good PHP5 knowledge and MVC-frameworks who have tried to develop applications using the Yii 1.x.x version. This book will very useful for all those who would like to try Yii2, or those who are afraid to move from Yii 1.x.x. to Yii2. If you have still not tried Yii2, this book is definitely for you!

What you will learn

  • •See the new version of the Yii2 framework and application development practices
  • •Write your applications more efficiently using shortcuts, Yii's core functionality, and the best practices in Web 2.0
  • •Get data from a database, and deal with Active Record, migrations, widgets, and core features
  • •Easily update your skills from the previous version of the framework
  • •Explore how to use Yii with different JavaScript frameworks and libraries such as WebSockets, Angular, Ember, Backbone and React
  • •Learn how to keep your application secure according to the general web application security principle "filter input, escape output.
  • •Write RESTfull Web Services using Yii2 and built-in features
  • •Correctly install and use official extensions in your projects
  • •Effectively create and implement your own Yii extension, and also ensure your extension is reusable and useful for the community

Product Details

Country selected
Publication date, Length, Edition, Language, ISBN-13
Publication date : Nov 09, 2016
Length: 584 pages
Edition : 3rd
Language : English
ISBN-13 : 9781785281761
Languages :
Tools :

What do you get with a Packt Subscription?

Free for first 7 days. $19.99 p/m after that. Cancel any time!
Product feature icon Unlimited ad-free access to the largest independent learning library in tech. Access this title and thousands more!
Product feature icon 50+ new titles added per month, including many first-to-market concepts and exclusive early access to books as they are being written.
Product feature icon Innovative learning tools, including AI book assistants, code context explainers, and text-to-speech.
Product feature icon Thousands of reference materials covering every tech concept you need to stay up to date.
Subscribe now
View plans & pricing

Product Details

Publication date : Nov 09, 2016
Length: 584 pages
Edition : 3rd
Language : English
ISBN-13 : 9781785281761
Languages :
Tools :

Packt Subscriptions

See our plans and pricing
Modal Close icon
$19.99 billed monthly
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Simple pricing, no contract
$199.99 billed annually
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just $5 each
Feature tick icon Exclusive print discounts
$279.99 billed in 18 months
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just $5 each
Feature tick icon Exclusive print discounts

Frequently bought together


Stars icon
Total $ 158.97
Yii2 Application Development Cookbook
$54.99
Mastering Yii
$54.99
Yii2 By Example
$48.99
Total $ 158.97 Stars icon
Banner background image

Table of Contents

13 Chapters
1. Fundamentals Chevron down icon Chevron up icon
2. Routing, Controllers, and Views Chevron down icon Chevron up icon
3. ActiveRecord, Model, and Database Chevron down icon Chevron up icon
4. Forms Chevron down icon Chevron up icon
5. Security Chevron down icon Chevron up icon
6. RESTful Web Services Chevron down icon Chevron up icon
7. Official Extensions Chevron down icon Chevron up icon
8. Extending Yii Chevron down icon Chevron up icon
9. Performance Tuning Chevron down icon Chevron up icon
10. Deployment Chevron down icon Chevron up icon
11. Testing Chevron down icon Chevron up icon
12. Debugging, Logging, and Error Handling Chevron down icon Chevron up icon
Index Chevron down icon Chevron up icon

Customer reviews

Rating distribution
Full star icon Full star icon Full star icon Full star icon Half star icon 4.5
(2 Ratings)
5 star 50%
4 star 50%
3 star 0%
2 star 0%
1 star 0%
MARCUS ANTONIO MARTINHO E SILVA Oct 29, 2019
Full star icon Full star icon Full star icon Full star icon Full star icon 5
The author demonstrate concepts one by one so we can focus on and explore them deeply.
Amazon Verified review Amazon
alfa Mar 10, 2023
Full star icon Full star icon Full star icon Full star icon Empty star icon 4
Very good reference of, in my opinion the best PHP framework. The writer don't take you up in a story of his experiances, but the topics are clear and there is a download of the code from the book available.
Amazon Verified review Amazon
Get free access to Packt library with over 7500+ books and video courses for 7 days!
Start Free Trial

FAQs

What is included in a Packt subscription? Chevron down icon Chevron up icon

A subscription provides you with full access to view all Packt and licnesed content online, this includes exclusive access to Early Access titles. Depending on the tier chosen you can also earn credits and discounts to use for owning content

How can I cancel my subscription? Chevron down icon Chevron up icon

To cancel your subscription with us simply go to the account page - found in the top right of the page or at https://subscription.packtpub.com/my-account/subscription - From here you will see the ‘cancel subscription’ button in the grey box with your subscription information in.

What are credits? Chevron down icon Chevron up icon

Credits can be earned from reading 40 section of any title within the payment cycle - a month starting from the day of subscription payment. You also earn a Credit every month if you subscribe to our annual or 18 month plans. Credits can be used to buy books DRM free, the same way that you would pay for a book. Your credits can be found in the subscription homepage - subscription.packtpub.com - clicking on ‘the my’ library dropdown and selecting ‘credits’.

What happens if an Early Access Course is cancelled? Chevron down icon Chevron up icon

Projects are rarely cancelled, but sometimes it's unavoidable. If an Early Access course is cancelled or excessively delayed, you can exchange your purchase for another course. For further details, please contact us here.

Where can I send feedback about an Early Access title? Chevron down icon Chevron up icon

If you have any feedback about the product you're reading, or Early Access in general, then please fill out a contact form here and we'll make sure the feedback gets to the right team. 

Can I download the code files for Early Access titles? Chevron down icon Chevron up icon

We try to ensure that all books in Early Access have code available to use, download, and fork on GitHub. This helps us be more agile in the development of the book, and helps keep the often changing code base of new versions and new technologies as up to date as possible. Unfortunately, however, there will be rare cases when it is not possible for us to have downloadable code samples available until publication.

When we publish the book, the code files will also be available to download from the Packt website.

How accurate is the publication date? Chevron down icon Chevron up icon

The publication date is as accurate as we can be at any point in the project. Unfortunately, delays can happen. Often those delays are out of our control, such as changes to the technology code base or delays in the tech release. We do our best to give you an accurate estimate of the publication date at any given time, and as more chapters are delivered, the more accurate the delivery date will become.

How will I know when new chapters are ready? Chevron down icon Chevron up icon

We'll let you know every time there has been an update to a course that you've bought in Early Access. You'll get an email to let you know there has been a new chapter, or a change to a previous chapter. The new chapters are automatically added to your account, so you can also check back there any time you're ready and download or read them online.

I am a Packt subscriber, do I get Early Access? Chevron down icon Chevron up icon

Yes, all Early Access content is fully available through your subscription. You will need to have a paid for or active trial subscription in order to access all titles.

How is Early Access delivered? Chevron down icon Chevron up icon

Early Access is currently only available as a PDF or through our online reader. As we make changes or add new chapters, the files in your Packt account will be updated so you can download them again or view them online immediately.

How do I buy Early Access content? Chevron down icon Chevron up icon

Early Access is a way of us getting our content to you quicker, but the method of buying the Early Access course is still the same. Just find the course you want to buy, go through the check-out steps, and you’ll get a confirmation email from us with information and a link to the relevant Early Access courses.

What is Early Access? Chevron down icon Chevron up icon

Keeping up to date with the latest technology is difficult; new versions, new frameworks, new techniques. This feature gives you a head-start to our content, as it's being created. With Early Access you'll receive each chapter as it's written, and get regular updates throughout the product's development, as well as the final course as soon as it's ready.We created Early Access as a means of giving you the information you need, as soon as it's available. As we go through the process of developing a course, 99% of it can be ready but we can't publish until that last 1% falls in to place. Early Access helps to unlock the potential of our content early, to help you start your learning when you need it most. You not only get access to every chapter as it's delivered, edited, and updated, but you'll also get the finalized, DRM-free product to download in any format you want when it's published. As a member of Packt, you'll also be eligible for our exclusive offers, including a free course every day, and discounts on new and popular titles.