PHP Classes
elePHPant
Icontem

PHP Page Cache Output: Store full page output in cache files

Recommend this page to a friend!
  Info   View files Example   View files View files (57)   DownloadInstall with Composer Download .zip   Reputation   Support forum (1)   Blog    
Last Updated Ratings Unique User Downloads Download Rankings
2018-04-01 (9 months ago) RSS 2.0 feedStarStarStarStar 78%Total: 301 All time: 7,199 This week: 341Up
Version License PHP version Categories
page-cache 1.13MIT/X Consortium ...5.5PHP 5, Cache
Description Author

This package can store full page output in cache files.

It can check if a valid cache file exists and is valid for the current page.

If the cache file is valid, it serves the cache file contents and exits.

If the cache file is not valid or does not exist, it creates a new cache file and starts capturing the page output.

The cache file name is defined using strategy classes that consider the current request URL.

  Performance   Level  
Name: Muhammed M <contact>
Classes: 3 packages by
Country: United States United States

Details

Build Status Latest Stable Version License

Full-page PHP Caching library

PageCache is a lightweight PHP library for full page cache, works out of the box with zero configuration. Use it when you need a simple yet powerful file based PHP caching solution. Page caching for mobile devices is built-in.

Install PHP PageCache and start caching your PHP's browser output code using Composer:

composer require mmamedov/page-cache

Or manually add to your composer.json file:

{
  "require": {
      "mmamedov/page-cache": "^2.0"
  }
}

Once PageCache is installed, include Composer's autoload.php file, or implement your own autoloader. Composer autoloader is recommended.

Do not use master branch, as it may contain unstable code, use versioned branches instead.

Upgrading to to v2.*

Version 2.0 is not backwards compatible with versions starting with v1.0. Version 2.0 introduces new features and code was refactored to enable us deliver more features.

When upgrading to version 2.0, please note the followings: - PHP requirements >= 5.6. - Your config file must be like this return [...] and not $config = array(...); like in previous version. - Config expiration setting was renamed to cache_expiration_in_seconds - Use try/catch to ensure proper page load in case of PageCache error.

If you find any other notable incompatibilities please let us know we will include them here.

No Database calls

Once page is cached, there are no more database calls needed! Even if your page contains many database calls and complex logic, it will be executed once and cached for period you specify. No more overload!

This is a very efficient and simple method, to cache your most visited dynamic pages. Tmawto.com website is built on PageCache, and is very fast.

Why another PHP Caching class?

Short answer - simplicity. If you want to include a couple lines of code on top of your dynamic PHP pages and be able to cache them fully, then PageCache is for you. No worrying about cache file name setup for each URL, no worries about your dynamically generated URL parameters and changing URLs. PageCache detects those changed and caches accordingly.

PageCache also detects $_SESSION changes and caches those pages correctly. This is useful if you have user authentication enabled on your site, and page contents change per user login while URL remains the same.

Lots of caching solutions focus on keyword-based approach, where you need to setup a keyword for your content (be it a full page cache, or a variable, etc.). There are great packages for keyword based approach. One could also use a more complex solution like a cache proxy, Varnish. PageCache on the other hand is a simple full page only caching solution, that does exactly what its name says - generates page cache in PHP.

How PageCache works

PageCache doesn't ask you for a keyword, it automatically generates them based on Strategies implementing StrategyInterface. You can define your own naming strategy, based on your application needs. Strategy class is responsible for generating a unique key for current request, key becomes file name for the cache file (if FileSystem storage is used).

<?php
require_once __DIR__.'/../vendor/autoload.php';

try {
    $cache = new PageCache\PageCache();
    $cache->config()
                    ->setCachePath('/your/path/')
                    ->setEnableLog(true);
    $cache->init();
} catch (\Exception $e) {
    // Log PageCache error or simply do nothing.
    // In case of PageCache error, page will load normally, without cache.
}

//rest of your PHP page code, everything below will be cached

Using PSR-16 compatible cache adapter

PageCache is built on top of PSR-16 SimpleCache "key"=>"value" storage and has default file-based cache adapter in class FileSystemPsrCacheAdapter. This implementation is fast and uses var_export + include internally so every cache file is also automatically cached in OpCache or APC (if you have configured opcode caching for your project). This is perfect choice for single-server applications but if you have multi-server application you should want to share page cache content between servers. In this case you may use any PSR-16 compatible cache adapter for network-based "key"=>"value" storage like Memcached or Redis:

<?php
require_once __DIR__.'/../vendor/autoload.php';

use Naroga\RedisCache\Redis;
use Predis\Client;

$config = array(
    'scheme' => 'tcp',
    'host'   => 'localhost',
    'port'   => 6379
);

$redis = new Redis(new Client($config));

$cache = new PageCache\PageCache();
$cache->setCacheAdapter($redis);
$cache->init();

//rest of your PHP page code, everything below will be cached

PageCache also has "Dry Run mode" option, is is turned off by default. Dry Run mode enables all functionality except that users won't be getting the cached content, they will be getting live content. No cache headers and no cached content will be send, if Dry Run mode is enabled. But cache will be stored in its as if it would run with Dry mode disabled. This mode lets PageCache dry run, useful if you want to test, debug or to see how your cache content populates.

For more examples see code inside PageCache examples directory.

For those who wonder, cache is saved into path specified in config file or using API, inside directories based on file hash. Based on the hash of the filename, 2 subdirectories will be created (if not created already), this is to avoid numerous files in a single cache directory.

Caching Strategies

PageCache uses various strategies to differentiate among separate versions of the same page.

All PageCache Strategies support sessions. See PageCache cache page with sessions example.

DefaultStrategy() is the default behaviour of PageCache. It caches pages and generated cache filenames using this PHP code:

md5($_SERVER['REQUEST_URI'] . $_SERVER['SCRIPT_NAME'] . $_SERVER['QUERY_STRING'] . $session_str)`

String $session_str is a serialized $_SESSION variable, with some keys ignored/or not based on whether session support is enabled or if sessionExclude() was called.

You could create your own naming strategy and pass it to PageCache:

$cache = new PageCache\PageCache();
$cache->setStrategy(new MyOwnStrategy());

Included with the PageCache is the MobileStrategy() based on Mobile_Detect. It is useful if you are serving the same URL differently across devices. See cache_mobiledetect.php PageCache example file for demo using MobileDetect._

You can define your own naming strategy based on the needs of your application.

Config file

Although not required, configuration file can be specified during PageCache initialization for system wide caching properties

// Optional system-wide cache config
use PageCache\PageCache;
$config_file_ = __DIR__.'/config.php';
$cache = new PageCache($config_file_);
// You can overwrite or get configuration parameters like this:
$cache->config()->getFileLock();
$cache->config()->setUseSession(true);

All available configuration options are documented in config file. Be sure to check it.

API - PageCache access methods

The following are public methods of PageCache class that you could call from your application. This is not a complete list. Check out examples and source code for more.

| Method | Description | | --- | --- | | init():void | initiate cache, this should be your last method to call on PageCache object.| | setStrategy(\PageCache\StrategyInterface):void | set cache file strategy. Built-in strategies are DefaultStrategy() and MobileStrategy(). Define your own if needed.| | setCacheAdapter(CacheInterface) | Set cache adapter. | | getCurrentKey() : string | Get cache key value for this page.| | getStrategy() : Strategy | Get set Strategy object. | | setStrategy(Strategy) : void | Set Strategy object. | | clearPageCache():void | Clear cache for current page, if this page was cached before. | | getPageCache():string | Return current page cache as a string or false on error, if this page was cached before.| | isCached():bool | Checks if current page is in cache, true if exists false if not cached yet.| | setLogger(\Psr\Log\LoggerInterface):void | Set PSR-3 compliant logger.| | clearAllCache() | Removes all content from cache storage.| | destroy() : void | Destroy PageCache instance, reset SessionHandler | | config() : Config | Get Config element. Setting and getting configuration values is done via this method. |

Check source code for more available methods.

Caching pages using Sessions (i.e. User Login enabled applications)

PageCache makes it simple to maintain a full page cache in PHP while using sessions.

One example for using session feature could be when you need to incorporate logged in users into your applications. In that case URL might remain same (if you rely on sessions to log users in), while content of the page will be different for each logged in user.

For PageCache to be aware of your $_SESSION, in config file or in your PHP file you must enable session support. In your PHP file, before calling init() call $cache->config()->setUseSession(true). That's it! Now your session pages will be cached seperately for your different session values.

Another handy method is config()->setSessionExcludeKeys(). Check out Session exclude keys example for code.

When to use config()->setSessionExcludeKeys(): For example let's assume that your application changes $_SESSION['count'] variable, but that doesn't reflect on the page content. Exclude this variable, otherwise PageCache will generate seperate cache files for each value of $_SESSION['count] session variable. To exclude 'count' session variable:

    // ...
    $cache->config()->setUseSession(true);
    $cache->config()->setSessionExcludeKeys(array('count'));
    // ...
    $cache->init();

HTTP Headers

PageCache can send cache related HTTP Headers. This helps browsers to load your pages faster and makes your application SEO aware. Search engines will read this headers and know whether your page was modified or expired.

By default, HTTP headers are disabled. You can enable appropriate headers to be sent with the response to the client. This is done by calling config()->setSendHeaders(true), prior to init(), or send_headers = true in config file. Although disabled by default, we encourage you to use this feature. Test on your local application before deploying it to your live version.

When HTTP headers are enabled, PageCache will attempt to send the following HTTP headers automatically with each response: - Last-Modified - Expires - ETag - HTTP/1.1 304 Not Modified

PageCache will attempt to send HTTP/1.1 304 Not Modified header along with cached content. When this header is sent, content is omitted from the response. This makes your application super fast. Browser is responsible for fetching a locally cached version when this header is present.

There is also forward_headers option in config, or config()->setForwardHeaders(true) which allows PageCache to fetch values of these HTTP headers from the app response and store them into cache item so headers would be cached too. This approach is useful if your app has fine-grained control.

Check out HTTP Headers demo for code.

Cache Stampede (dog-piling) protection

Under a heavy load or when multiple calls to the web server are made to the same URL when it has been expired, there might occur a condition where system might become unresponsive or when all clients will try to regenerate cache of the same page. This effect is called cache stampede.

PageCache uses 2 strategies to defeat cache stampede, and even when thousands request are made to the same page system continues to function normally.

File Lock mechanism

By default PageCache sets file lock to LOCK_EX | LOCK_NB, which means that only 1 process will be able to write into a cache file. During that write, all other processes will read old version of the file. This ensures that no user is presented with a blank page, and that all users receive a cached version of the URL - without exceptions.

This eliminates possibility of cache stampede, since there can only be a single write to a file, even though thousands of clients have reached a page when it has expired (one client generates new cache and sees the new cached version, the rest will receive old version). Number of users hitting page when it has expired is also reduced by random early and late expiration.

Random early and late expiration

Using random logarithmic calculations, producing sometimes negative and at times positive results, cache expiration for each client hitting the same URL at the same time is going to be different. While some clients might still get the same cache expiration value as others, overall distribution of cache expiration value among clients is random.

Making pages expire randomly at most 6 seconds before or after actual cache expiration of the page, ensures that we have less clients trying to regenerate cache content. File locking already takes care of simultaneous writes of cache page, random expiration takes it a step further minimizing the number of such required attempts.

To give an example, consider you have set expiration to 10 minutes config()->setCacheExpirationInSeconds(600). Page will expire for some clients in 594 seconds, for some in 606 seconds, and for some in 600 seconds. Actual page expiration is going to be anywhere in between 594 and 606 seconds inclusive, this is randomly calculated. Expiration value is not an integer internally, so there are a lot more of random expiration values than you can think of.

That's it!

Check out PageCache examples folder for sample code.

  Files folder image Files  
File Role Description
Files folder imageexamples (11 files, 2 directories)
Files folder imagesrc (7 files, 2 directories)
Files folder imagetests (6 files, 3 directories)
Accessible without login Plain text file .gitignore Data Auxiliary data
Accessible without login Plain text file .php_cs Example Example script
Accessible without login Plain text file .travis.yml Data Auxiliary data
Accessible without login Plain text file CHANGELOG.md Data Auxiliary data
Accessible without login Plain text file composer.json Data Auxiliary data
Accessible without login Plain text file LICENSE.txt Lic. License
Accessible without login Plain text file phpunit.xml Data Auxiliary data
Accessible without login Plain text file README.md Doc. README

  Files folder image Files  /  examples  
File Role Description
Files folder imagecache (1 file)
Files folder imagelog (1 file)
  Accessible without login Plain text file config.php Aux. Auxiliary script
  Accessible without login Plain text file demo-api.php Example Example script
  Accessible without login Plain text file demo-clear-cache.php Example Example script
  Accessible without login Plain text file demo-default-logger.php Example Example script
  Accessible without login Plain text file demo-headers.php Example Example script
  Accessible without login Plain text file demo-mobiledetect.php Example Example script
  Accessible without login Plain text file demo-monolog.php Example Example script
  Accessible without login Plain text file demo-session-exclude-keys.php Example Example script
  Accessible without login Plain text file demo-session-support.php Example Example script
  Accessible without login Plain text file demo-with-config.php Example Example script
  Accessible without login Plain text file demo.php Example Example script

  Files folder image Files  /  examples  /  cache  
File Role Description
  Accessible without login Plain text file .gitkeep Data Auxiliary data

  Files folder image Files  /  examples  /  log  
File Role Description
  Accessible without login Plain text file .gitkeep Data Auxiliary data

  Files folder image Files  /  src  
File Role Description
Files folder imageStorage (5 files, 1 directory)
Files folder imageStrategy (2 files)
  Plain text file Config.php Class Class source
  Plain text file DefaultLogger.php Class Class source
  Plain text file HttpHeaders.php Class Class source
  Plain text file PageCache.php Class Class source
  Plain text file PageCacheException.php Class Class source
  Plain text file SessionHandler.php Class Class source
  Plain text file StrategyInterface.php Class Class source

  Files folder image Files  /  src  /  Storage  
File Role Description
Files folder imageFileSystem (3 files)
  Plain text file CacheAdapterException.php Class Class source
  Plain text file CacheItem.php Class Class source
  Plain text file CacheItemInterface.php Class Class source
  Plain text file CacheItemStorage.php Class Class source
  Plain text file InvalidArgumentException.php Class Class source

  Files folder image Files  /  src  /  Storage  /  FileSystem  
File Role Description
  Plain text file FileSystem.php Class Class source
  Plain text file FileSystemCacheAdapter.php Class Class source
  Plain text file HashDirectory.php Class Class source

  Files folder image Files  /  src  /  Strategy  
File Role Description
  Plain text file DefaultStrategy.php Class Class source
  Plain text file MobileStrategy.php Class Class source

  Files folder image Files  /  tests  
File Role Description
Files folder imageIntegration (2 files, 1 directory)
Files folder imageStorage (1 directory)
Files folder imageStrategy (2 files)
  Accessible without login Plain text file bootstrap.php Aux. Auxiliary script
  Plain text file ConfigTest.php Class Class source
  Accessible without login Plain text file config_test.php Aux. Auxiliary script
  Accessible without login Plain text file config_wrong_test.php Aux. Auxiliary script
  Plain text file PageCacheTest.php Class Class source
  Plain text file SessionHandlerTest.php Class Class source

  Files folder image Files  /  tests  /  Integration  
File Role Description
Files folder imagewww (6 files)
  Plain text file IntegrationPsrCacheTest.php Class Class source
  Plain text file IntegrationWebServerTest.php Class Class source

  Files folder image Files  /  tests  /  Integration  /  www  
File Role Description
  Accessible without login Plain text file 1.php Aux. Auxiliary script
  Accessible without login Plain text file 2.php Aux. Auxiliary script
  Accessible without login Plain text file 3.php Aux. Auxiliary script
  Accessible without login Plain text file 4.php Aux. Auxiliary script
  Accessible without login Plain text file 5.php Aux. Auxiliary script
  Accessible without login Plain text file index.php Example Example script

  Files folder image Files  /  tests  /  Storage  
File Role Description
Files folder imageFileSystem (3 files)

  Files folder image Files  /  tests  /  Storage  /  FileSystem  
File Role Description
  Plain text file FileSystemCacheAdapterTest.php Class Class source
  Plain text file FileSystemTest.php Class Class source
  Plain text file HashDirectoryTest.php Class Class source

  Files folder image Files  /  tests  /  Strategy  
File Role Description
  Plain text file DefaultStrategyTest.php Class Class source
  Plain text file MobileStrategyTest.php Class Class source

 Version Control Unique User Downloads Download Rankings  
 100%
Total:301
This week:0
All time:7,199
This week:341Up
User Ratings User Comments (1)
 All time
Utility:100%StarStarStarStarStarStar
Consistency:100%StarStarStarStarStarStar
Documentation:93%StarStarStarStarStar
Examples:93%StarStarStarStarStar
Tests:-
Videos:-
Overall:78%StarStarStarStar
Rank:45
 
nice
1 year ago (muabshir)
80%StarStarStarStarStar