Yii - Caching


Advertisements


Caching is an effective way to improve the performance of your application. Caching mechanisms store static data in cache and get it from cache when requested. On the server side, you may use cache to store basic data, such as a list of most recent news. You can also store page fragments or whole web pages. On the client side, you can use HTTP caching to keep most recently visited pages in the browser cache.

Preparing the DB

Step 1 − Create a new database. Database can be prepared in the following two ways.

  • In the terminal run mysql -u root –p

    .
  • Create a new database via CREATE DATABASE helloworld CHARACTER SET utf8 COLLATE utf8_general_ci;

Step 2 − Configure the database connection in the config/db.php file. The following configuration is for the system used currently.

<?php
   return [
      'class' => 'yii\db\Connection',
      'dsn' => 'mysql:host=localhost;dbname=helloworld',
      'username' => 'vladimir',
      'password' => '12345',
      'charset' => 'utf8',
   ];
?>

Step 3 − Inside the root folder run ./yii migrate/create test_table. This command will create a database migration for managing our DB. The migration file should appear in the migrations folder of the project root.

Step 4 − Modify the migration file (m160106_163154_test_table.php in this case) this way.

<?php
   use yii\db\Schema;
   use yii\db\Migration;
   class m160106_163154_test_table extends Migration {
      public function safeUp()\ {
         $this->createTable("user", [
            "id" => Schema::TYPE_PK,
            "name" => Schema::TYPE_STRING,
            "email" => Schema::TYPE_STRING,
         ]);
         $this->batchInsert("user", ["name", "email"], [
            ["User1", "user1@gmail.com"],
            ["User2", "user2@gmail.com"],
            ["User3", "user3@gmail.com"],
            ["User4", "user4@gmail.com"],
            ["User5", "user5@gmail.com"],
            ["User6", "user6@gmail.com"],
            ["User7", "user7@gmail.com"],
            ["User8", "user8@gmail.com"],
            ["User9", "user9@gmail.com"],
            ["User10", "user10@gmail.com"],
            ["User11", "user11@gmail.com"],
         ]);
      }
      public function safeDown() {
         $this->dropTable('user');
      }
   }
?>

The above migration creates a user table with these fields: id, name, and email. It also adds a few demo users.

Step 5 − Inside the project root run ./yii migrate to apply the migration to the database.

Step 6 − Now, we need to create a model for our user table. For the sake of simplicity, we are going to use the Gii code generation tool. Open up this url: http://localhost:8080/index.php?r=gii. Then, click the “Start” button under the “Model generator” header. Fill in the Table Name (“user”) and the Model Class (“MyUser”), click the “Preview” button and finally, click the “Generate” button.

Caching Preparing DB

The MyUser model should appear in the models directory.

Data Caching

Data caching helps you in storing PHP variables in cache and retrieve them later. Data caching relies on cache components, which are usually registered as application components. To access the application component, you may call Yii::$app → cache. You can register several cache application components.

Yii supports the following cache storages −

  • yii\caching\DbCache − Uses a database table to store cached data. Uou must create a table as specified in yii\caching\DbCache::$cacheTable.

  • yii\caching\ApcCache − Uses PHP APC extension.

  • yii\caching\FileCache − Uses files to store cached data.

  • yii\caching\DummyCache − Serves as a cache placeholder which does no real caching. The purpose of this component is to simplify the code that needs to check the availability of cache.

  • yii\caching\MemCache − Uses PHP memcache extension.

  • yii\caching\WinCache − Uses PHP WinCache extension.

  • yii\redis\Cache − Implements a cache component based on Redis database.

  • yii\caching\XCache − Uses PHP XCache extension.

All cache components support the following APIs −

  • get() − Retrieves a data value from cache with a specified key. A false value will be returned if the data value is expired/invalidated or not found.

  • add() − Stores a data value identified by a key in cache if the key is not found in the cache.

  • set() − Stores a data value identified by a key in cache.

  • multiGet() − Retrieves multiple data values from cache with the specified keys.

  • multiAdd() − Stores multiple data values in cache. Each item is identified by a key. If a key already exists in the cache, the data value will be skipped.

  • multiSet() − Stores multiple data values in cache. Each item is identified by a key.

  • exists() − Returns a value indicating whether the specified key is found in the cache.

  • flush() − Removes all data values from the cache.

  • delete() − Removes a data value identified by a key from the cache.

A data value stored in a cache will remain there forever unless it is removed. To change this behavior, you can set an expiration parameter when calling the set() method to store a data value.

Cached data values can also be invalidated by changes of the cache dependencies

  • yii\caching\DbDependency − The dependency is changed if the query result of the specified SQL statement is changed.

  • yii\caching\ChainedDependency − The dependency is changed if any of the dependencies on the chain is changed.

  • yii\caching\FileDependency − The dependency is changed if the file's last modification time is changed.

  • yii\caching\ExpressionDependency − The dependency is changed if the result of the specified PHP expression is changed.

Now, add the cache application component to your application.

Step 1 − Modify the config/web.php file.

<?php
   $params = require(__DIR__ . '/params.php');
   $config = [
      'id' => 'basic',
      'basePath' => dirname(__DIR__),
      'bootstrap' => ['log'],
      'components' => [
         'request' => [
            // !!! insert a secret key in the following (if it is empty) - this
               //is required by cookie validation
            'cookieValidationKey' => 'ymoaYrebZHa8gURuolioHGlK8fLXCKjO',
         ],
         'cache' => [
            'class' => 'yii\caching\FileCache',
         ],
         'user' => [
            'identityClass' => 'app\models\User',
            'enableAutoLogin' => true,
         ],
         'errorHandler' => [
            'errorAction' => 'site/error',
         ],
         'mailer' => [
            'class' => 'yii\swiftmailer\Mailer',
            // send all mails to a file by default. You have to set
            // 'useFileTransport' to false and configure a transport
            // for the mailer to send real emails.
            'useFileTransport' => true,
         ],
         'log' => [
            'traceLevel' => YII_DEBUG ? 3 : 0,
            'targets' => [
               [
                  'class' => 'yii\log\FileTarget',
                  'levels' => ['error', 'warning'],
               ],
            ],
         ],
         'db' => require(__DIR__ . '/db.php'),
      ],
      'modules' => [
         'hello' => [
            'class' => 'app\modules\hello\Hello',
         ],
      ],
      'params' => $params,
   ];
   if (YII_ENV_DEV) {
      // configuration adjustments for 'dev' environment
      $config['bootstrap'][] = 'debug';
      $config['modules']['debug'] = [
         'class' => 'yii\debug\Module',
      ];
      $config['bootstrap'][] = 'gii';
      $config['modules']['gii'] = [
         'class' => 'yii\gii\Module',
      ];
   }
   return $config;
?>

Step 2 − Add a new function called actionTestCache() to the SiteController.

public function actionTestCache() {
   $cache = Yii::$app->cache;
   // try retrieving $data from cache
   $data = $cache->get("my_cached_data");
   if ($data === false) {
      // $data is not found in cache, calculate it from scratch
      $data = date("d.m.Y H:i:s");
      // store $data in cache so that it can be retrieved next time
      $cache->set("my_cached_data", $data, 30);
   }
   // $data is available here
   var_dump($data);
}

Step 3 − Type http://localhost:8080/index.php?r=site/test-cache in the address bar of the web browser, you will see the following.

Test Cache

Step 4 − If you reload the page, you should notice the date has not changed. The date value is cached and the cache will expire within 30 seconds. Reload the page after 30 seconds.

Date Value Cached

Query Caching

Query caching provides you caching the result of database queries. Query caching requires a DB connection and the cache application component.

Step 1 − Add a new method called actionQueryCaching() to the SiteController.

public function actionQueryCaching() {
   $duration = 10;
   $result = MyUser::getDb()->cache(function ($db) {
      return MyUser::find()->count();
   }, $duration);
   var_dump($result);
   $user = new MyUser();
   $user->name = "cached user name";
   $user->email = "cacheduseremail@gmail.com";
   $user->save();
   echo "==========";
   var_dump(MyUser::find()->count());
}

In the above code, we cache the database query, add a new user, and display user count.

Step 2 − Go to the URL http://localhost:8080/index.php?r=site/query-caching and reload the page.

Query Caching

When we open the page for the first, we cache the DB query and display all users count. When we reload the page, the result of the cached DB query is the same as it was because the database query is cached.

You can flush the cache from the console using the following commands −

  • yii cache − Shows the available cache components.

  • yii cache/flush cache1 cache2 cache3 − Flushes the cache components cache1, cache2, and cache3.

  • yii cache/flush-all − Flushes all cache components.

Step 3 − Inside the project root of your application run ./yii cache/flush-all.

Running Project Root Application

Advertisements