TAN'S Blog

if you obey all the rules you miss all the fun…


Leave a comment

Caching using zend framework(1sT sTEP tOWARDS zERO tO hERO)

In this blog we will discuss how to cache your whole project. When we run our project, php interpreter enters into the public/index.php file and after interpreted the project source code, again it comes out through index.php file.

ppt

 

As in above image we can see index.php is entry point and exit point so if we will start Caching and end Caching in index.php file then our whole project will be cached. We will see how it can be possible through demo.

DEMO

1st Step: 

You should have created project using zend framework. Here we are using zend framework 1.12 for easy understanding. If you want to install framework and create project so check these 2 links.

1. https://www.digitalocean.com/community/tutorials/how-to-install-zend-framework-on-an-ubuntu-12-04-vps

2. http://framework.zend.com/manual/1.12/en/learning.quickstart.create-project.html

2nd Step:

Create clone of the project from https://github.com/tbiswal/quickstart which we will use for demo.

3rd Step:

As we are caching whole project so we will follow #Zend_Cache_Frontend_Output method.

4th Step:

Create directory called cache inside public directory and give full read write permission to cache directory.

5th Step:

Add below code in mentioned files:-

1. quickstart/public/index.php

Add this code before $application->bootstrap()->run();


// auto loader
require_once 'Zend/Loader/Autoloader.php';
$autoloader = Zend_Loader_Autoloader::getInstance();
$autoloader->setFallbackAutoloader(true);

// config
$config = new Zend_Config_Ini(APPLICATION_PATH . '/configs/application.ini', 'production');
$registry = Zend_Registry::getInstance();
$registry->set('config', $config);

// Setup caching option
$frontendOptions = array(
    'lifetime' => 7200, // cache lifetime of 2 hours
    'automatic_serialization' => true
);
$backendOptions = array(
    'cache_dir' => 'cache/' // Directory where to put the cache files
);
$cache = Zend_Cache::factory('Output',
    'File',
    $frontendOptions,
    $backendOptions
);
$registry->set('appCacheObj', $cache);

$appCache = Zend_Registry::get('appCacheObj');

$cacheId = 'myCacheId'.str_replace("/", "_", $_SERVER['REQUEST_URI']);

if(strpos($cacheId, ".php") !== -1) {
    $cacheId = explode(".php", $cacheId)[0];
}

//Clear cache for dynamic page
if($_SERVER['REQUEST_URI'] == "/guestbook/sign") {
    $appCache->remove($cacheId);
}

//Cache start
if($appCache->start($cacheId)) {
    exit;
}

After $application->bootstrap()->run(); add below line:


    //Cache end
    if(!is_null($appCache)){
        $appCache->end();
    }

2. Add below code inside end of the public function save() of models/GuestbookMapper.php file:-


//Clear cache on save action to show new data to user instead of cached data
$appCache = Zend_Registry::get('appCacheObj');
$appCache->clean(Zend_Cache::CLEANING_MODE_ALL);

When you will browse http://quickstart.local/guestbook/sign you will get the page like below.

ppt2

You can check the cache directory which contains the cached files. After click on Sign Guestbook it will clear the cache 1st and then it will create new cached files.

FYI : So for your project you have to clear cache on any save action so that user will get new fetched records otherwise you can show data from cached records.

After completing all the above step when you will browse your project you will find that each page of your application is cached. Only the cached record will be cleaned if you click on any save action. So enjoy 🙂

/*Hope you will love it */


2 Comments

cACHING uSING zEND fRAMEWORK(zERO tO hERO)

In my previous post we have seen simple caching using plain PHP. Here we will learn how to implement caching using Framework. We will use ZendFramework-1.12.3. You might wonder that why I am using very old version framework for caching. Don’t worry I will make you zero to hero in caching step by step. In this version caching is very easy to understand also easy to implement. So let’s start!!

Analysis:

Note: You can also refer manual and for demo you can refer my blog.

Zend_Cache provides a generic way to cache any data. Caching in Zend Framework is operated by frontends while cache records are stored through backend adapters (File, Sqlite, Memcache…) through a flexible system of IDs and tags. Using those, it is easy to delete specific types of records afterwards (for example: “delete all cache records marked with a given tag”).

The core of the module (Zend_Cache_Core) is generic, flexible and configurable. Yet, for your specific needs there are cache frontends that extend Zend_Cache_Core for convenience: Output, File, Function and Class.

Example #1 Getting a Frontend with Zend_Cache::factory()

Zend_Cache::factory() instantiates correct objects and ties them together. In this first example, we will use Core frontend together with File backend.


    $frontendOptions = array(
        'lifetime' => 7200, // cache lifetime of 2 hours
        'automatic_serialization' => true
    );

    $backendOptions = array(
        'cache_dir' => './tmp/' // Directory where to put the cache files
     );

    // getting a Zend_Cache_Core object
    $cache = Zend_Cache::factory('Core',
        'File',
        $frontendOptions,
        $backendOptions
    );

Note: Frontends and Backends Consisting of Multiple Words Some frontends and backends are named using multiple words, such as ‘ZendPlatform’. When specifying them to the factory, separate them using a word separator, such as a space (‘ ‘), hyphen (‘-‘), or period (‘.’).

Example #2 Caching a Database Query Result

Now that we have a frontend, we can cache any type of data (we turned on serialization). for example, we can cache a result from a very expensive database query. After it is cached, there is no need to even connect to the database; records are fetched from cache and unserialized.


    // $cache initialized in previous example
    // see if a cache already exists:
    if( ($result = $cache->load('myresult')) === false ) {

        // cache miss; connect to the database

        $db = Zend_Db::factory( [...] );

        $result = $db->fetchAll('SELECT * FROM huge_table');

        $cache->save($result, 'myresult');

        } else {

            // cache hit! shout so that we know
            echo "This one is from cache!\n\n";

    }

    print_r($result);

Example #3 Caching Output with Zend_Cache Output Frontend

We ‘mark up’ sections in which we want to cache output by adding some conditional logic, encapsulating the section within start() and end() methods (this resembles the first example and is the core strategy for caching).

Inside, output your data as usual – all output will be cached when execution hits the end() method. On the next run, the whole section will be skipped in favor of fetching data from cache (as long as the cache record is valid).

$frontendOptions = array(
    'lifetime' => 30, // cache lifetime of 30 seconds
    'automatic_serialization' => false // this is the default anyways
);

$backendOptions = array('cache_dir' => './tmp/');

$cache = Zend_Cache::factory('Output',
    'File',
    $frontendOptions,
    $backendOptions
);

// we pass a unique identifier to the start() method
if(!$cache->start('mypage')) {
    // output as usual:
    echo 'Hello world! ';
    echo 'This is cached ('.time().') ';
    $cache->end(); // the output is saved and sent to the browser
}

echo 'This is never cached ('.time().').';

Simple Demo: I assume that you have installed zend framework 1.12. Here we will use concept of Example #3 for caching. We will use File as backend adapter to store cache records. So create a directory called “cache” inside public folder with read write permission.

Step 1: Add below code in public/index.php before $application->bootstrap() ->run();


    // auto loader
    require_once 'Zend/Loader/Autoloader.php';
    $autoloader = Zend_Loader_Autoloader::getInstance();
    $autoloader->setFallbackAutoloader(true);

    // registry
    $registry = Zend_Registry::getInstance();

    $frontendOptions = array(
        'lifetime' => 7200, // cache lifetime of 2 hours
        'automatic_serialization' => true
    );

    $backendOptions = array(
        'cache_dir' => 'cache/' // Directory where to put the cache files
    );

    $cache = Zend_Cache::factory('Output',
        'File',
        $frontendOptions,
        $backendOptions
    );
    $registry->set('appCacheObj', $cache);

Step 2: Add below code in indexAction() inside indexController.php


    $appCache = Zend_Registry::get('appCacheObj');
    $cacheId = 'myBigLoop';
    //If cache record is not present then caching will be started from this code
    if($appCache->start($cacheId)) {
        exit;
    }
    $data = '';
    for ($i = 0; $i < 10000; $i++) {
        $data = $data . $i." ";
    }
    $this->view->data = $data;

Step 3: Add below code in index.phtml inside view folder.


<?php
$appCache = Zend_Registry::get('appCacheObj');
    echo $this->data;

//Caching will be ended here
if(!is_null($appCache)){$appCache->end();}
?>

Before caching:

When you will browse your index page( EX: http://localhost/quickstart/public/index.php) 1st time you will get the result 0 to 10000 as output. Now if you will check your cache directory you will find Binary file named “zend_cache—myBigLoop” where myBigLoop was your cacheId. If you will check the time taken to get your output it will be at least more than 70ms.

before_caching

After caching:

When you will browse index page next time you will get your output from cached files. The time taken to generate output will be 3-4 times faster than previous result.

after_caching

For time being you can delete your cached record manually from cache folder and experiment on it. We will deal with little complex demo in my next blog and also we will clear cached record through code.

Reference:

http://framework.zend.com/manual/1.12/en/manual.html

/*Hope you will love it */


Leave a comment

CACHING

What is caching?

Caching is an area of a computer’s memory devoted to temporarily storing recently used information. The content, which includes HTML pages, images, files and Web objects, is stored on the local hard drive in order to make it faster for the user to access it, which helps improve the efficiency of the computer and its overall performance.

Most caching occurs without the user knowing about it. For example, when a user returns to a Web page they have recently accessed, the browser can pull those files from the cache instead of the original server because it has stored the user’s activity. The storing of that information saves the user time by getting to it faster, and lessens the traffic on the network.

Caching Mechanism:

Drawing21

Very Simple Example to learn caching in PHP:

Step One: Create the top-cache.php file:

We need to create two files. Here’s the first one: Create a new file named top-cache.php and paste the code below in it.

<?php
  $url = $_SERVER["SCRIPT_NAME"];
  $break = Explode('/', $url);
  $file = $break[count($break) - 1];
  $cachefile = 'cached-'.substr_replace($file ,"",-4).'.html';
  $cachetime = 18000; //in seconds

  // Serve from the cache if it is younger than $cachetime
  if (file_exists($cachefile) && time() - $cachetime < filemtime($cachefile)) {
      echo "<!-- Cached copy, generated ".date('H:i', filemtime($cachefile))." -->\n";
      include($cachefile);
      exit;
  }
  ob_start(); // Start the output buffer
?>

So, what this code does? The first 5 lines create the cached file name according to the current php file. So, if you’re using a file named index.php, the cached file will be named cached-index.html.

Line 6 creates a $cachetime(in seconds) variable which determines the life of the cache. You can experiment by changing the time.

Lines 9 to 13 are a conditional statement which look for a file named $cachefile. If the file is found, a comment is inserted (line 10) and the $cachefile file is included. Then, the exit statement stops the execution of the script and the file is sent to the client brother. Which means that if a static file is found, no php code is interpreted by the server.

Line 14 creates a buffer, if the $cachefile file isn’t found. That’s all for the top-cache.php file.

Step two: Create the bottom-cache.php file:

Now, create a second php file, named bottom-cache.php and paste the code below in it.

 <?php
  // Cache the contents to a file
  $cached = fopen($cachefile, 'w');
  fwrite($cached, ob_get_contents());
  fclose($cached);
  ob_end_flush(); // Send the output to the browser
?>

If a file named $cachefile isn’t found on your server, this code is executed and create the file, so next time the page will be called, the $cachefile static file will be served to the client browser instead of executing the whole PHP file.

Step three: Include cache files on your page
Now that you have created the two necessary files, you simply have to include them on the php page you wish to cache. As you probably guessed, the top-cache.php file must be included in the beginning of your php page and the bottom-cache.php at the end, as shown below:

You can save this page as index.php.

<?php
  include('top-cache.php');

  // Your regular PHP code goes here.
  //You can uncomment the code and test it.
  /*
  for($i=1;$i<=100000;$i++) {
    echo "Hello world";
  }
  */

  include('bottom-cache.php');
?>

Now if you test the cache on a slow page, you’ll be amazed by how faster the page is.

Note: Give full read and write permission to the directory where you will put the above 3 files. For Windows OS no need to give file permission.
Ex: If this is my folder structure in ubuntu():

cac

Then you should give the read and write permission to caching folder.

When you will browse the page after uncommenting the code in step three “http://localhost/caching/index.php” for very 1st time you will see it will take time around 50-70ms. Next time you will see it will show the result in 17 to 25 ms. Its amazing.

Before caching(time taken 63 ms):

before

After Caching(time taken 18 ms):

after

Reference:

http://en.wikipedia.org/wiki/Cache_(computing)

http://www.catswhocode.com/blog/how-to-create-a-simple-and-efficient-php-cache

http://www.citrix.com/glossary/caching.html

/*Hope you will love it*/