Kohana v3.3.5
This commit is contained in:
45
modules/cache/.travis.yml
vendored
Normal file
45
modules/cache/.travis.yml
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
sudo: false
|
||||
|
||||
language: php
|
||||
|
||||
# Only build the main develop/master branches - feature branches will be covered by PRs
|
||||
branches:
|
||||
only:
|
||||
- /^[0-9\.]+\/(develop|master)$/
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- vendor
|
||||
- $HOME/.composer/cache
|
||||
|
||||
php:
|
||||
- 5.3
|
||||
- 5.4
|
||||
- 5.5
|
||||
- 5.6
|
||||
- 7.0
|
||||
- hhvm
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- php: 5.3
|
||||
env: 'COMPOSER_PHPUNIT="lowest"'
|
||||
|
||||
services:
|
||||
- memcached
|
||||
|
||||
before_script:
|
||||
- if [[ $TRAVIS_PHP_VERSION != "hhvm" ]]; then INI_FILE=~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini; else INI_FILE=/etc/hhvm/php.ini; fi;
|
||||
- if [[ $TRAVIS_PHP_VERSION = 5.* ]]; then echo extension = memcache.so >> $INI_FILE; fi;
|
||||
- if [[ $TRAVIS_PHP_VERSION = 5.* ]]; then (echo yes | pecl install -f apcu-4.0.10 && echo apc.enable_cli = 1 >> $INI_FILE); fi;
|
||||
- if [[ $TRAVIS_PHP_VERSION = 7.* ]]; then (echo yes | pecl install -f apcu-5.1.2 && echo apc.enable_cli = 1 >> $INI_FILE); fi;
|
||||
- if [[ $TRAVIS_PHP_VERSION != "hhvm" ]] ; then echo -e 'apc.max_file_size = 0\napc.cache_by_default = 0' >> $INI_FILE ; fi
|
||||
- composer install --prefer-dist
|
||||
- if [ "$COMPOSER_PHPUNIT" = "lowest" ]; then composer update --prefer-lowest --with-dependencies phpunit/phpunit; fi;
|
||||
- vendor/bin/koharness
|
||||
|
||||
script:
|
||||
- cd /tmp/koharness && ./vendor/bin/phpunit --bootstrap=modules/unittest/bootstrap.php modules/unittest/tests.php
|
||||
|
||||
notifications:
|
||||
email: false
|
6
modules/cache/README.md
vendored
6
modules/cache/README.md
vendored
@@ -1,6 +1,12 @@
|
||||
Kohana Cache library
|
||||
====================
|
||||
|
||||
| ver | Stable | Develop |
|
||||
|-------|--------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| 3.3.x | [](https://travis-ci.org/kohana/cache) | [](https://travis-ci.org/kohana/cache) |
|
||||
| 3.4.x | [](https://travis-ci.org/kohana/cache) | [](https://travis-ci.org/kohana/cache) |
|
||||
|
||||
|
||||
The cache library for Kohana 3 provides a simple interface to the most common cache solutions. Developers are free to add their own caching solutions that follow the cache design pattern defined within this module.
|
||||
|
||||
Supported cache solutions
|
||||
|
3
modules/cache/classes/Cache/Apcu.php
vendored
Normal file
3
modules/cache/classes/Cache/Apcu.php
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class Cache_Apcu extends Kohana_Cache_Apcu {}
|
10
modules/cache/classes/Kohana/Cache.php
vendored
10
modules/cache/classes/Kohana/Cache.php
vendored
@@ -36,7 +36,7 @@
|
||||
* Below is an example of a _memcache_ server configuration.
|
||||
*
|
||||
* return array(
|
||||
* 'default' => array( // Default group
|
||||
* 'memcache' => array( // Name of group
|
||||
* 'driver' => 'memcache', // using Memcache driver
|
||||
* 'servers' => array( // Available server definitions
|
||||
* array(
|
||||
@@ -49,8 +49,12 @@
|
||||
* ),
|
||||
* )
|
||||
*
|
||||
* In cases where only one cache group is required, if the group is named `default` there is
|
||||
* no need to pass the group name when instantiating a cache instance.
|
||||
* In cases where only one cache group is required, set `Cache::$default` (in your bootstrap,
|
||||
* or by extending `Kohana_Cache` class) to the name of the group, and use:
|
||||
*
|
||||
* $cache = Cache::instance(); // instead of Cache::instance('memcache')
|
||||
*
|
||||
* It will return the cache instance of the group it has been set in `Cache::$default`.
|
||||
*
|
||||
* #### General cache group configuration settings
|
||||
*
|
||||
|
174
modules/cache/classes/Kohana/Cache/Apcu.php
vendored
Normal file
174
modules/cache/classes/Kohana/Cache/Apcu.php
vendored
Normal file
@@ -0,0 +1,174 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
/**
|
||||
* [Kohana Cache](api/Kohana_Cache) APCu data store driver for Kohana Cache
|
||||
* library.
|
||||
*
|
||||
* ### Configuration example
|
||||
*
|
||||
* Below is an example of an _apcu_ server configuration.
|
||||
*
|
||||
* return array(
|
||||
* 'apcu' => array( // Driver group
|
||||
* 'driver' => 'apcu', // using APCu driver
|
||||
* ),
|
||||
* )
|
||||
*
|
||||
* In cases where only one cache group is required, if the group is named `default` there is
|
||||
* no need to pass the group name when instantiating a cache instance.
|
||||
*
|
||||
* #### General cache group configuration settings
|
||||
*
|
||||
* Below are the settings available to all types of cache driver.
|
||||
*
|
||||
* Name | Required | Description
|
||||
* -------------- | -------- | ---------------------------------------------------------------
|
||||
* driver | __YES__ | (_string_) The driver type to use
|
||||
*
|
||||
* ### System requirements
|
||||
*
|
||||
* * Kohana 3.0.x
|
||||
* * PHP 5.2.4 or greater
|
||||
* * APCu PHP extension
|
||||
*
|
||||
* @package Kohana/Cache
|
||||
* @category Base
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2009-2012 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class Kohana_Cache_Apcu extends Cache implements Cache_Arithmetic {
|
||||
|
||||
/**
|
||||
* Check for existence of the APCu extension This method cannot be invoked externally. The driver must
|
||||
* be instantiated using the `Cache::instance()` method.
|
||||
*
|
||||
* @param array $config configuration
|
||||
* @throws Cache_Exception
|
||||
*/
|
||||
protected function __construct(array $config)
|
||||
{
|
||||
if ( ! extension_loaded('apcu'))
|
||||
{
|
||||
throw new Cache_Exception('PHP APCu extension is not available.');
|
||||
}
|
||||
|
||||
parent::__construct($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a cached value entry by id.
|
||||
*
|
||||
* // Retrieve cache entry from apcu group
|
||||
* $data = Cache::instance('apcu')->get('foo');
|
||||
*
|
||||
* // Retrieve cache entry from apcu group and return 'bar' if miss
|
||||
* $data = Cache::instance('apcu')->get('foo', 'bar');
|
||||
*
|
||||
* @param string $id id of cache to entry
|
||||
* @param string $default default value to return if cache miss
|
||||
* @return mixed
|
||||
* @throws Cache_Exception
|
||||
*/
|
||||
public function get($id, $default = NULL)
|
||||
{
|
||||
$data = apcu_fetch($this->_sanitize_id($id), $success);
|
||||
|
||||
return $success ? $data : $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a value to cache with id and lifetime
|
||||
*
|
||||
* $data = 'bar';
|
||||
*
|
||||
* // Set 'bar' to 'foo' in apcu group, using default expiry
|
||||
* Cache::instance('apcu')->set('foo', $data);
|
||||
*
|
||||
* // Set 'bar' to 'foo' in apcu group for 30 seconds
|
||||
* Cache::instance('apcu')->set('foo', $data, 30);
|
||||
*
|
||||
* @param string $id id of cache entry
|
||||
* @param string $data data to set to cache
|
||||
* @param integer $lifetime lifetime in seconds
|
||||
* @return boolean
|
||||
*/
|
||||
public function set($id, $data, $lifetime = NULL)
|
||||
{
|
||||
if ($lifetime === NULL)
|
||||
{
|
||||
$lifetime = Arr::get($this->_config, 'default_expire', Cache::DEFAULT_EXPIRE);
|
||||
}
|
||||
|
||||
return apcu_store($this->_sanitize_id($id), $data, $lifetime);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a cache entry based on id
|
||||
*
|
||||
* // Delete 'foo' entry from the apcu group
|
||||
* Cache::instance('apcu')->delete('foo');
|
||||
*
|
||||
* @param string $id id to remove from cache
|
||||
* @return boolean
|
||||
*/
|
||||
public function delete($id)
|
||||
{
|
||||
return apcu_delete($this->_sanitize_id($id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all cache entries.
|
||||
*
|
||||
* Beware of using this method when
|
||||
* using shared memory cache systems, as it will wipe every
|
||||
* entry within the system for all clients.
|
||||
*
|
||||
* // Delete all cache entries in the apcu group
|
||||
* Cache::instance('apcu')->delete_all();
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function delete_all()
|
||||
{
|
||||
return apcu_clear_cache();
|
||||
}
|
||||
|
||||
/**
|
||||
* Increments a given value by the step value supplied.
|
||||
* Useful for shared counters and other persistent integer based
|
||||
* tracking.
|
||||
*
|
||||
* @param string id of cache entry to increment
|
||||
* @param int step value to increment by
|
||||
* @return integer
|
||||
* @return boolean
|
||||
*/
|
||||
public function increment($id, $step = 1)
|
||||
{
|
||||
if (apcu_exists($id)) {
|
||||
return apcu_inc($id, $step);
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrements a given value by the step value supplied.
|
||||
* Useful for shared counters and other persistent integer based
|
||||
* tracking.
|
||||
*
|
||||
* @param string id of cache entry to decrement
|
||||
* @param int step value to decrement by
|
||||
* @return integer
|
||||
* @return boolean
|
||||
*/
|
||||
public function decrement($id, $step = 1)
|
||||
{
|
||||
if (apcu_exists($id)) {
|
||||
return apcu_dec($id, $step);
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
} // End Kohana_Cache_Apcu
|
93
modules/cache/classes/Kohana/Cache/File.php
vendored
93
modules/cache/classes/Kohana/Cache/File.php
vendored
@@ -140,17 +140,21 @@ class Kohana_Cache_File extends Cache implements Cache_GarbageCollect {
|
||||
}
|
||||
else
|
||||
{
|
||||
// Open the file and parse data
|
||||
$created = $file->getMTime();
|
||||
$data = $file->openFile();
|
||||
$lifetime = $data->fgets();
|
||||
|
||||
// If we're at the EOF at this point, corrupted!
|
||||
if ($data->eof())
|
||||
// Test the expiry
|
||||
if ($this->_is_expired($file))
|
||||
{
|
||||
throw new Cache_Exception(__METHOD__.' corrupted cache file!');
|
||||
// Delete the file
|
||||
$this->_delete_file($file, FALSE, TRUE);
|
||||
return $default;
|
||||
}
|
||||
|
||||
// open the file to read data
|
||||
$data = $file->openFile();
|
||||
|
||||
// Run first fgets(). Cache data starts from the second line
|
||||
// as the first contains the lifetime timestamp
|
||||
$data->fgets();
|
||||
|
||||
$cache = '';
|
||||
|
||||
while ($data->eof() === FALSE)
|
||||
@@ -158,17 +162,7 @@ class Kohana_Cache_File extends Cache implements Cache_GarbageCollect {
|
||||
$cache .= $data->fgets();
|
||||
}
|
||||
|
||||
// Test the expiry
|
||||
if (($created + (int) $lifetime) < time())
|
||||
{
|
||||
// Delete the file
|
||||
$this->_delete_file($file, NULL, TRUE);
|
||||
return $default;
|
||||
}
|
||||
else
|
||||
{
|
||||
return unserialize($cache);
|
||||
}
|
||||
return unserialize($cache);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -219,14 +213,7 @@ class Kohana_Cache_File extends Cache implements Cache_GarbageCollect {
|
||||
// If the directory path is not a directory
|
||||
if ( ! $dir->isDir())
|
||||
{
|
||||
// Create the directory
|
||||
if ( ! mkdir($directory, 0777, TRUE))
|
||||
{
|
||||
throw new Cache_Exception(__METHOD__.' unable to create directory : :directory', array(':directory' => $directory));
|
||||
}
|
||||
|
||||
// chmod to solve potential umask issues
|
||||
chmod($directory, 0777);
|
||||
$this->_make_directory($directory, 0777, TRUE);
|
||||
}
|
||||
|
||||
// Open file to inspect
|
||||
@@ -267,7 +254,7 @@ class Kohana_Cache_File extends Cache implements Cache_GarbageCollect {
|
||||
$filename = Cache_File::filename($this->_sanitize_id($id));
|
||||
$directory = $this->_resolve_directory($filename);
|
||||
|
||||
return $this->_delete_file(new SplFileInfo($directory.$filename), NULL, TRUE);
|
||||
return $this->_delete_file(new SplFileInfo($directory.$filename), FALSE, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -337,9 +324,7 @@ class Kohana_Cache_File extends Cache implements Cache_GarbageCollect {
|
||||
else
|
||||
{
|
||||
// Assess the file expiry to flag it for deletion
|
||||
$json = $file->openFile('r')->current();
|
||||
$data = json_decode($json);
|
||||
$delete = $data->expiry < time();
|
||||
$delete = $this->_is_expired($file);
|
||||
}
|
||||
|
||||
// If the delete flag is set delete file
|
||||
@@ -375,7 +360,7 @@ class Kohana_Cache_File extends Cache implements Cache_GarbageCollect {
|
||||
// Create new file resource
|
||||
$fp = new SplFileInfo($files->getRealPath());
|
||||
// Delete the file
|
||||
$this->_delete_file($fp);
|
||||
$this->_delete_file($fp, $retain_parent_directory, $ignore_errors, $only_expired);
|
||||
}
|
||||
|
||||
// Move the file pointer on
|
||||
@@ -446,21 +431,55 @@ class Kohana_Cache_File extends Cache implements Cache_GarbageCollect {
|
||||
* `mkdir` to ensure DRY principles
|
||||
*
|
||||
* @link http://php.net/manual/en/function.mkdir.php
|
||||
* @param string $directory
|
||||
* @param integer $mode
|
||||
* @param boolean $recursive
|
||||
* @param resource $context
|
||||
* @param string $directory directory path
|
||||
* @param integer $mode chmod mode
|
||||
* @param boolean $recursive allows nested directories creation
|
||||
* @param resource $context a stream context
|
||||
* @return SplFileInfo
|
||||
* @throws Cache_Exception
|
||||
*/
|
||||
protected function _make_directory($directory, $mode = 0777, $recursive = FALSE, $context = NULL)
|
||||
{
|
||||
if ( ! mkdir($directory, $mode, $recursive, $context))
|
||||
// call mkdir according to the availability of a passed $context param
|
||||
$mkdir_result = $context ?
|
||||
mkdir($directory, $mode, $recursive, $context) :
|
||||
mkdir($directory, $mode, $recursive);
|
||||
|
||||
// throw an exception if unsuccessful
|
||||
if ( ! $mkdir_result)
|
||||
{
|
||||
throw new Cache_Exception('Failed to create the defined cache directory : :directory', array(':directory' => $directory));
|
||||
}
|
||||
|
||||
// chmod to solve potential umask issues
|
||||
chmod($directory, $mode);
|
||||
|
||||
return new SplFileInfo($directory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if cache file is expired
|
||||
*
|
||||
* @param SplFileInfo $file the cache file
|
||||
* @return boolean TRUE if expired false otherwise
|
||||
*/
|
||||
protected function _is_expired(SplFileInfo $file)
|
||||
{
|
||||
// Open the file and parse data
|
||||
$created = $file->getMTime();
|
||||
$data = $file->openFile("r");
|
||||
$lifetime = (int) $data->fgets();
|
||||
|
||||
// If we're at the EOF at this point, corrupted!
|
||||
if ($data->eof())
|
||||
{
|
||||
throw new Cache_Exception(__METHOD__ . ' corrupted cache file!');
|
||||
}
|
||||
|
||||
//close file
|
||||
$data = null;
|
||||
|
||||
// test for expiry and return
|
||||
return (($lifetime !== 0) AND ( ($created + $lifetime) < time()));
|
||||
}
|
||||
}
|
||||
|
6
modules/cache/classes/Kohana/HTTP/Cache.php
vendored
6
modules/cache/classes/Kohana/HTTP/Cache.php
vendored
@@ -1,6 +1,6 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
/**
|
||||
* HTTT Caching adaptor class that provides caching services to the
|
||||
* HTTP Caching adaptor class that provides caching services to the
|
||||
* [Request_Client] class, using HTTP cache control logic as defined in
|
||||
* RFC 2616.
|
||||
*
|
||||
@@ -36,7 +36,7 @@ class Kohana_HTTP_Cache {
|
||||
* )
|
||||
* );
|
||||
*
|
||||
* @uses [Cache]
|
||||
* @uses Cache
|
||||
* @param mixed $cache cache engine to use
|
||||
* @param array $options options to set to this class
|
||||
* @return HTTP_Cache
|
||||
@@ -298,7 +298,7 @@ class Kohana_HTTP_Cache {
|
||||
* Controls whether the response can be cached. Uses HTTP
|
||||
* protocol to determine whether the response can be cached.
|
||||
*
|
||||
* @link RFC 2616 http://www.w3.org/Protocols/rfc2616/
|
||||
* @link http://www.w3.org/Protocols/rfc2616/rfc2616.html RFC 2616
|
||||
* @param Response $response The Response
|
||||
* @return boolean
|
||||
*/
|
||||
|
10
modules/cache/composer.json
vendored
10
modules/cache/composer.json
vendored
@@ -24,10 +24,18 @@
|
||||
"kohana/core": ">=3.3",
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"kohana/core": "3.3.*@dev",
|
||||
"kohana/unittest": "3.3.*@dev",
|
||||
"kohana/koharness": "*@dev"
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-3.3/develop": "3.3.x-dev",
|
||||
"dev-3.4/develop": "3.4.x-dev"
|
||||
}
|
||||
},
|
||||
"installer-paths": {
|
||||
"vendor/{$vendor}/{$name}": ["type:kohana-module"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
12
modules/cache/guide/cache/config.md
vendored
12
modules/cache/guide/cache/config.md
vendored
@@ -55,7 +55,7 @@ failure_callback | __NO__ | (_[callback](http://www.php.net/manual/en/language
|
||||
'driver' => 'memcache',
|
||||
'default_expire' => 3600,
|
||||
'compression' => FALSE, // Use Zlib compression
|
||||
(can cause issues with integers)
|
||||
// (can cause issues with integers)
|
||||
'servers' => array
|
||||
(
|
||||
'local' => array
|
||||
@@ -71,7 +71,7 @@ failure_callback | __NO__ | (_[callback](http://www.php.net/manual/en/language
|
||||
'driver' => 'memcachetag',
|
||||
'default_expire' => 3600,
|
||||
'compression' => FALSE, // Use Zlib compression
|
||||
(can cause issues with integers)
|
||||
// (can cause issues with integers)
|
||||
'servers' => array
|
||||
(
|
||||
'local' => array
|
||||
@@ -90,7 +90,15 @@ failure_callback | __NO__ | (_[callback](http://www.php.net/manual/en/language
|
||||
'driver' => 'apc',
|
||||
'default_expire' => 3600,
|
||||
),
|
||||
|
||||
## APCu settings
|
||||
|
||||
'apcu' => array
|
||||
(
|
||||
'driver' => 'apcu',
|
||||
'default_expire' => 3600,
|
||||
),
|
||||
|
||||
## SQLite settings
|
||||
|
||||
'sqlite' => array
|
||||
|
10
modules/cache/guide/cache/index.md
vendored
10
modules/cache/guide/cache/index.md
vendored
@@ -6,7 +6,7 @@ instances of cache engines through a grouped singleton pattern.
|
||||
|
||||
## Supported cache engines
|
||||
|
||||
* APC ([Cache_Apc])
|
||||
* APC/APCu ([Cache_Apc])
|
||||
* File ([Cache_File])
|
||||
* Memcached ([Cache_Memcache])
|
||||
* Memcached-tags ([Cache_Memcachetag])
|
||||
@@ -16,13 +16,13 @@ instances of cache engines through a grouped singleton pattern.
|
||||
## Introduction to caching
|
||||
|
||||
Caching should be implemented with consideration. Generally, caching the result of resources
|
||||
is faster than reprocessing them. Choosing what, how and when to cache is vital. [PHP APC](http://php.net/manual/en/book.apc.php) is one of the fastest caching systems available, closely followed by [Memcached](http://memcached.org/). [SQLite](http://www.sqlite.org/) and File caching are two of the slowest cache methods, however usually faster than reprocessing
|
||||
is faster than reprocessing them. Choosing what, how and when to cache is vital. [PHP APCu](http://php.net/manual/en/book.apcu.php) is one of the fastest caching systems available, closely followed by [Memcached](http://memcached.org/). [SQLite](http://www.sqlite.org/) and File caching are two of the slowest cache methods, however usually faster than reprocessing
|
||||
a complex set of instructions.
|
||||
|
||||
Caching engines that use memory are considerably faster than file based alternatives. But
|
||||
memory is limited whereas disk space is plentiful. If caching large datasets, such as large database result sets, it is best to use file caching.
|
||||
|
||||
[!!] Cache drivers require the relevant PHP extensions to be installed. APC, eAccelerator, Memecached and Xcache all require non-standard PHP extensions.
|
||||
[!!] Cache drivers require the relevant PHP extensions to be installed. APC, eAccelerator, Memecached and Xcache all require non-standard PHP extensions.
|
||||
|
||||
## What the Kohana Cache module does (and does not do)
|
||||
|
||||
@@ -43,7 +43,7 @@ Getting and setting values to cache is very simple when using the _Kohana Cache_
|
||||
|
||||
Driver | Storage | Speed | Tags | Distributed | Automatic Garbage Collection | Notes
|
||||
---------------- | ------------ | --------- | -------- | ----------- | ---------------------------- | -----------------------
|
||||
APC | __Memory__ | Excellent | No | No | Yes | Widely available PHP opcode caching solution, improves php execution performance
|
||||
APC/APCu | __Memory__ | Excellent | No | No | Yes | Widely available PHP opcode caching solution, improves php execution performance
|
||||
Wincache | __Memory__ | Excellent | No | No | Yes | Windows variant of APC
|
||||
File | __Disk__ | Poor | No | No | No | Marginally faster than execution
|
||||
Memcache (tag) | __Memory__ | Good | No (yes) | Yes | Yes | Generally fast distributed solution, but has a speed hit due to variable network latency and serialization
|
||||
@@ -54,4 +54,4 @@ It is possible to have hybrid cache solutions that use a combination of the engi
|
||||
## Minimum requirements
|
||||
|
||||
* Kohana 3.0.4
|
||||
* PHP 5.2.4 or greater
|
||||
* PHP 5.2.4 or greater
|
||||
|
10
modules/cache/guide/cache/usage.md
vendored
10
modules/cache/guide/cache/usage.md
vendored
@@ -9,7 +9,7 @@ Creating a new _Kohana Cache_ instance is simple, however it must be done using
|
||||
// Create a new instance of cache using the default group
|
||||
$cache = Cache::instance();
|
||||
|
||||
The default group will use whatever is set to [Cache::$default] and must have a corresponding [configuration](cache.config) definition for that group.
|
||||
The default group will use whatever is set to [Cache::$default] and must have a corresponding [configuration](config) definition for that group.
|
||||
|
||||
To create a cache instance using a group other than the _default_, simply provide the group name as an argument.
|
||||
|
||||
@@ -18,7 +18,7 @@ To create a cache instance using a group other than the _default_, simply provid
|
||||
|
||||
If there is a cache instance already instantiated then you can get it directly from the class member.
|
||||
|
||||
[!!] Beware that this can cause issues if you do not test for the instance before trying to access it.
|
||||
[!!] Beware that this can cause issues if you do not test for the instance before trying to access it.
|
||||
|
||||
// Check for the existance of the cache driver
|
||||
if (isset(Cache::$instances['memcache']))
|
||||
@@ -36,11 +36,11 @@ If there is a cache instance already instantiated then you can get it directly f
|
||||
|
||||
The cache library supports scalar and object values, utilising object serialization where required (or not supported by the caching engine). This means that the majority or objects can be cached without any modification.
|
||||
|
||||
[!!] Serialisation does not work with resource handles, such as filesystem, curl or socket resources.
|
||||
[!!] Serialisation does not work with resource handles, such as filesystem, curl or socket resources.
|
||||
|
||||
### Setting a value to cache
|
||||
|
||||
Setting a value to cache using the [Cache::set] method can be done in one of two ways; either using the Cache instance interface, which is good for atomic operations; or getting an instance and using that for multiple operations.
|
||||
Setting a value to cache using the [Cache::set] method can be done in one of two ways: either using the Cache instance interface, which is good for atomic operations, or getting an instance and using that for multiple operations.
|
||||
|
||||
The first example demonstrates how to quickly load and set a value to the default cache instance.
|
||||
|
||||
@@ -104,7 +104,7 @@ In cases where the requested key is not available or the entry has expired, a de
|
||||
|
||||
It is possible to retrieve values from cache grouped by tag, using the [Cache::find] method with drivers that support tagging.
|
||||
|
||||
[!!] The __Memcachetag__ driver does not support the `Cache::find($tag)` interface and will throw an exception.
|
||||
[!!] The __Memcachetag__ driver does not support the `Cache::find($tag)` interface and will throw an exception.
|
||||
|
||||
// Get an instance of cache
|
||||
$cache = Cache::instance('memcachetag');
|
||||
|
9
modules/cache/koharness.php
vendored
Normal file
9
modules/cache/koharness.php
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
// Configuration for koharness - builds a standalone skeleton Kohana app for running unit tests
|
||||
return array(
|
||||
'kohana_version' => '3.3',
|
||||
'modules' => array(
|
||||
'cache' => __DIR__,
|
||||
'unittest' => __DIR__ . '/vendor/kohana/unittest'
|
||||
),
|
||||
);
|
@@ -164,6 +164,17 @@ TESTTEXT;
|
||||
),
|
||||
'foo bar snafu'
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'id' => 'test ttl 0 means never expire',
|
||||
'value' => 'cache value that should last',
|
||||
'ttl' => 0,
|
||||
'wait' => 1,
|
||||
'type' => 'string',
|
||||
'default' => NULL
|
||||
),
|
||||
'cache value that should last'
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'id' => 'bar',
|
||||
@@ -196,6 +207,28 @@ TESTTEXT;
|
||||
'default' => NULL,
|
||||
),
|
||||
$html_text
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'id' => 'test with 60*5',
|
||||
'value' => 'blabla',
|
||||
'ttl' => 60*5,
|
||||
'wait' => FALSE,
|
||||
'type' => 'string',
|
||||
'default' => NULL,
|
||||
),
|
||||
'blabla'
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'id' => 'test with 60*50',
|
||||
'value' => 'bla bla',
|
||||
'ttl' => 60*50,
|
||||
'wait' => FALSE,
|
||||
'type' => 'string',
|
||||
'default' => NULL,
|
||||
),
|
||||
'bla bla'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
9
modules/cache/tests/cache/CacheTest.php
vendored
9
modules/cache/tests/cache/CacheTest.php
vendored
@@ -90,14 +90,13 @@ class Kohana_CacheTest extends PHPUnit_Framework_TestCase {
|
||||
*/
|
||||
public function test_cloning_fails()
|
||||
{
|
||||
if ( ! Kohana::$config->load('cache.file'))
|
||||
{
|
||||
$this->markTestSkipped('Unable to load File configuration');
|
||||
}
|
||||
$cache = $this->getMockBuilder('Cache')
|
||||
->disableOriginalConstructor()
|
||||
->getMockForAbstractClass();
|
||||
|
||||
try
|
||||
{
|
||||
$cache_clone = clone(Cache::instance('file'));
|
||||
clone($cache);
|
||||
}
|
||||
catch (Cache_Exception $e)
|
||||
{
|
||||
|
69
modules/cache/tests/cache/FileTest.php
vendored
69
modules/cache/tests/cache/FileTest.php
vendored
@@ -30,7 +30,21 @@ class Kohana_Cache_FileTest extends Kohana_CacheBasicMethodsTest {
|
||||
|
||||
if ( ! Kohana::$config->load('cache.file'))
|
||||
{
|
||||
$this->markTestSkipped('Unable to load File configuration');
|
||||
Kohana::$config->load('cache')
|
||||
->set(
|
||||
'file',
|
||||
array(
|
||||
'driver' => 'file',
|
||||
'cache_dir' => APPPATH.'cache',
|
||||
'default_expire' => 3600,
|
||||
'ignore_on_delete' => array(
|
||||
'file_we_want_to_keep.cache',
|
||||
'.gitignore',
|
||||
'.git',
|
||||
'.svn'
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$this->cache(Cache::instance('file'));
|
||||
@@ -45,7 +59,7 @@ class Kohana_Cache_FileTest extends Kohana_CacheBasicMethodsTest {
|
||||
{
|
||||
$cache = $this->cache();
|
||||
$config = Kohana::$config->load('cache')->file;
|
||||
$file = $config['cache_dir'].'/.gitignore';
|
||||
$file = $config['cache_dir'].'/file_we_want_to_keep.cache';
|
||||
|
||||
// Lets pollute the cache folder
|
||||
file_put_contents($file, 'foobar');
|
||||
@@ -95,4 +109,55 @@ class Kohana_Cache_FileTest extends Kohana_CacheBasicMethodsTest {
|
||||
$this->assertSame($expected, $cache->get('utf8'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests garbage collection.
|
||||
* Tests if non-expired cache files withstand garbage collection
|
||||
*
|
||||
* @test
|
||||
*/
|
||||
public function test_garbage_collection()
|
||||
{
|
||||
$cache = $this->cache();
|
||||
$cache->set('persistent', 'dummy persistent data', 3);
|
||||
$cache->set('volatile', 'dummy volatile data', 1);
|
||||
|
||||
$this->assertTrue($this->is_file('persistent'));
|
||||
$this->assertTrue($this->is_file('volatile'));
|
||||
|
||||
// sleep for more than a second
|
||||
sleep(2);
|
||||
|
||||
$cache->garbage_collect();
|
||||
|
||||
$this->assertTrue($this->is_file('persistent'));
|
||||
$this->assertFalse($this->is_file('volatile'));
|
||||
}
|
||||
|
||||
/**
|
||||
* helper method for test_garbage_collection.
|
||||
* Tests if cache file exists given cache id.
|
||||
*
|
||||
* @param string $id cache id
|
||||
* @return boolean TRUE if file exists FALSE otherwise
|
||||
*/
|
||||
protected function is_file($id)
|
||||
{
|
||||
$cache = $this->cache();
|
||||
|
||||
$method_sanitize_id = new ReflectionMethod($cache, '_sanitize_id');
|
||||
$method_sanitize_id->setAccessible(TRUE);
|
||||
$method_filename = new ReflectionMethod($cache, 'filename');
|
||||
$method_filename->setAccessible(TRUE);
|
||||
$method_resolve_directory = new ReflectionMethod($cache, '_resolve_directory');
|
||||
$method_resolve_directory->setAccessible(TRUE);
|
||||
|
||||
$sanitized_id = $method_sanitize_id->invoke($cache, $id);
|
||||
$filename = $method_filename->invoke($cache, $sanitized_id);
|
||||
$directory = $method_resolve_directory->invoke($cache, $filename);
|
||||
|
||||
$file = new SplFileInfo($directory.$filename);
|
||||
|
||||
//var_dump($cache->_is_expired($file));
|
||||
return $file->isFile();
|
||||
}
|
||||
} // End Kohana_SqliteTest
|
||||
|
11
modules/cache/tests/cache/SqliteTest.php
vendored
11
modules/cache/tests/cache/SqliteTest.php
vendored
@@ -35,7 +35,16 @@ class Kohana_SqliteTest extends Kohana_CacheBasicMethodsTest {
|
||||
|
||||
if ( ! Kohana::$config->load('cache.sqlite'))
|
||||
{
|
||||
$this->markTestIncomplete('Unable to load sqlite configuration');
|
||||
Kohana::$config->load('cache')
|
||||
->set(
|
||||
'sqlite',
|
||||
array(
|
||||
'driver' => 'sqlite',
|
||||
'default_expire' => 3600,
|
||||
'database' => 'memory',
|
||||
'schema' => 'CREATE TABLE caches(id VARCHAR(127) PRIMARY KEY, tags VARCHAR(255), expiration INTEGER, cache TEXT)',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$this->cache(Cache::instance('sqlite'));
|
||||
|
72
modules/cache/tests/cache/WincacheTest.php
vendored
72
modules/cache/tests/cache/WincacheTest.php
vendored
@@ -1,39 +1,49 @@
|
||||
<?php
|
||||
include_once(Kohana::find_file('tests/cache', 'CacheBasicMethodsTest'));
|
||||
|
||||
/**
|
||||
* @package Kohana/Cache
|
||||
* @group kohana
|
||||
* @group kohana.cache
|
||||
* @category Test
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2009-2012 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class Kohana_WincacheTest extends Kohana_CacheBasicMethodsTest {
|
||||
if (isset($_ENV['TRAVIS']))
|
||||
{
|
||||
// This is really hacky, but without it the result is permanently full of noise that makes it impossible to see
|
||||
// any unexpected skipped tests.
|
||||
print "Skipping all Wincache driver tests as these will never run on Travis.".\PHP_EOL;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
include_once(Kohana::find_file('tests/cache', 'CacheBasicMethodsTest'));
|
||||
|
||||
/**
|
||||
* This method MUST be implemented by each driver to setup the `Cache`
|
||||
* instance for each test.
|
||||
*
|
||||
* This method should do the following tasks for each driver test:
|
||||
*
|
||||
* - Test the Cache instance driver is available, skip test otherwise
|
||||
* - Setup the Cache instance
|
||||
* - Call the parent setup method, `parent::setUp()`
|
||||
*
|
||||
* @return void
|
||||
* @package Kohana/Cache
|
||||
* @group kohana
|
||||
* @group kohana.cache
|
||||
* @category Test
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2009-2012 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
class Kohana_WincacheTest extends Kohana_CacheBasicMethodsTest {
|
||||
|
||||
if ( ! extension_loaded('wincache'))
|
||||
/**
|
||||
* This method MUST be implemented by each driver to setup the `Cache`
|
||||
* instance for each test.
|
||||
*
|
||||
* This method should do the following tasks for each driver test:
|
||||
*
|
||||
* - Test the Cache instance driver is available, skip test otherwise
|
||||
* - Setup the Cache instance
|
||||
* - Call the parent setup method, `parent::setUp()`
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setUp()
|
||||
{
|
||||
$this->markTestSkipped('Wincache PHP Extension is not available');
|
||||
parent::setUp();
|
||||
|
||||
if ( ! extension_loaded('wincache'))
|
||||
{
|
||||
$this->markTestSkipped('Wincache PHP Extension is not available');
|
||||
}
|
||||
|
||||
$this->cache(Cache::instance('wincache'));
|
||||
}
|
||||
|
||||
$this->cache(Cache::instance('wincache'));
|
||||
}
|
||||
|
||||
} // End Kohana_WincacheTest
|
||||
} // End Kohana_WincacheTest
|
||||
}
|
||||
|
14
modules/cache/tests/cache/arithmetic/ApcTest.php
vendored
14
modules/cache/tests/cache/arithmetic/ApcTest.php
vendored
@@ -39,6 +39,18 @@ class Kohana_ApcTest extends Kohana_CacheArithmeticMethodsTest {
|
||||
'place "apc.enable_cli=1" in your php.ini file');
|
||||
}
|
||||
|
||||
if ( ! Kohana::$config->load('cache.apc'))
|
||||
{
|
||||
Kohana::$config->load('cache')
|
||||
->set(
|
||||
'apc',
|
||||
array(
|
||||
'driver' => 'apc',
|
||||
'default_expire' => 3600,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$this->cache(Cache::instance('apc'));
|
||||
}
|
||||
|
||||
@@ -57,7 +69,7 @@ class Kohana_ApcTest extends Kohana_CacheArithmeticMethodsTest {
|
||||
*
|
||||
* @dataProvider provider_set_get
|
||||
*
|
||||
* @param array data
|
||||
* @param array data
|
||||
* @param mixed expected
|
||||
* @return void
|
||||
*/
|
||||
|
87
modules/cache/tests/cache/arithmetic/ApcuTest.php
vendored
Normal file
87
modules/cache/tests/cache/arithmetic/ApcuTest.php
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
include_once(Kohana::find_file('tests/cache/arithmetic', 'CacheArithmeticMethods'));
|
||||
|
||||
/**
|
||||
* @package Kohana/Cache
|
||||
* @group kohana
|
||||
* @group kohana.cache
|
||||
* @category Test
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2009-2012 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class Kohana_ApcuTest extends Kohana_CacheArithmeticMethodsTest {
|
||||
|
||||
/**
|
||||
* This method MUST be implemented by each driver to setup the `Cache`
|
||||
* instance for each test.
|
||||
*
|
||||
* This method should do the following tasks for each driver test:
|
||||
*
|
||||
* - Test the Cache instance driver is available, skip test otherwise
|
||||
* - Setup the Cache instance
|
||||
* - Call the parent setup method, `parent::setUp()`
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
if ( ! extension_loaded('apcu'))
|
||||
{
|
||||
$this->markTestSkipped('APCu PHP Extension is not available');
|
||||
}
|
||||
|
||||
if ( ! (ini_get('apc.enabled') AND ini_get('apc.enable_cli')))
|
||||
{
|
||||
$this->markTestSkipped('APCu is not enabled. To fix '.
|
||||
'set "apc.enabled=1" and "apc.enable_cli=1" in your php.ini file');
|
||||
}
|
||||
|
||||
if ( ! Kohana::$config->load('cache.apcu'))
|
||||
{
|
||||
Kohana::$config->load('cache')
|
||||
->set(
|
||||
'apcu',
|
||||
array(
|
||||
'driver' => 'apcu',
|
||||
'default_expire' => 3600,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$this->cache(Cache::instance('apcu'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the [Cache::set()] method, testing;
|
||||
*
|
||||
* - The value is cached
|
||||
* - The lifetime is respected
|
||||
* - The returned value type is as expected
|
||||
* - The default not-found value is respected
|
||||
*
|
||||
* This test doesn't test the TTL as there is a known bug/feature
|
||||
* in APCu that prevents the same request from killing cache on timeout.
|
||||
*
|
||||
* @link http://pecl.php.net/bugs/bug.php?id=16814
|
||||
*
|
||||
* @dataProvider provider_set_get
|
||||
*
|
||||
* @param array data
|
||||
* @param mixed expected
|
||||
* @return void
|
||||
*/
|
||||
public function test_set_get(array $data, $expected)
|
||||
{
|
||||
if ($data['wait'] !== FALSE)
|
||||
{
|
||||
$this->markTestSkipped('Unable to perform TTL test in CLI, see: '.
|
||||
'http://pecl.php.net/bugs/bug.php?id=16814 for more info!');
|
||||
}
|
||||
|
||||
parent::test_set_get($data, $expected);
|
||||
}
|
||||
|
||||
} // End Kohana_ApcuTest
|
@@ -35,7 +35,28 @@ class Kohana_CacheArithmeticMemcacheTest extends Kohana_CacheArithmeticMethodsTe
|
||||
}
|
||||
if ( ! $config = Kohana::$config->load('cache.memcache'))
|
||||
{
|
||||
$this->markTestSkipped('Unable to load Memcache configuration');
|
||||
Kohana::$config->load('cache')
|
||||
->set(
|
||||
'memcache',
|
||||
array(
|
||||
'driver' => 'memcache',
|
||||
'default_expire' => 3600,
|
||||
'compression' => FALSE, // Use Zlib compression (can cause issues with integers)
|
||||
'servers' => array(
|
||||
'local' => array(
|
||||
'host' => 'localhost', // Memcache Server
|
||||
'port' => 11211, // Memcache port number
|
||||
'persistent' => FALSE, // Persistent connection
|
||||
'weight' => 1,
|
||||
'timeout' => 1,
|
||||
'retry_interval' => 15,
|
||||
'status' => TRUE,
|
||||
),
|
||||
),
|
||||
'instant_death' => TRUE,
|
||||
)
|
||||
);
|
||||
$config = Kohana::$config->load('cache.memcache');
|
||||
}
|
||||
|
||||
$memcache = new Memcache;
|
||||
|
Reference in New Issue
Block a user