Git Product home page Git Product logo

simple-cache's Introduction

PSR-16 Simple Cache

GitHub Action Travis CI Scrutinizer CI Code Coverage Code Quality
build Build Status Build Status codecov Scrutinizer Code Quality

Caching, a common performance-boosting technique, is a staple feature in many frameworks and libraries. This interoperability allows libraries to utilize existing caching implementations rather than creating their own. PSR-6 has addressed this issue, but its formal and verbose nature complicates simple use cases. PSR-16 is a simpler approach seeks to create a streamlined standard interface for common situations, ensuring compatibility with PSR-6 in a straightforward manner.

Showcase

Simple Cache is utilized in Cache Master, a WordPress Cache Plugin, and it performs excellently. Check it out if you're running WordPress sites; it won't let you down.

Built-in drivers:

The required parameters are marked by an asterisk (*)

Driver name ($driver) PHP modules ($config)
File file - *storage
Redis redis redis host, port, user, pass, unix_socket
MongoDB mongo mongodb host, port, user, pass, dbname, collection, unix_socket
MySQL mysql pdo_mysql host, port, *user, *pass, *dbname, table, charset
SQLite sqlite pdo_sqlite *storage
APC apc apc -
APCu apcu apcu -
Memcache memcache memcache host, port, unix_socket
LibMemcached memcached memcached host, port, unix_socket
WinCache wincache wincache -

Note:

  • WinCache is excluded from unit testing since it's only used on Windows, and the testing processes are done on Linux environment.
  • unix_socket is empty by default, accepting the absolute path of the unix domain socket file. If it is set, host and port will be ignored.

The following command displays a list of installed PHP modules.

php -m

Before using, make sure the required PHP modules are installed on your system.


Table of Contents

  • Install
  • Usage
    • Cache
      • Built-in drivers
      • __construct
      • $driver
      • $config
  • API
    • set
    • get
    • has
    • delete
    • getMultiple
    • setMultiple
    • deleteMultiple
    • clear
    • clearExpiredItems (Non-PSR-16)
  • Build Data Schema
    • MySQL
    • SQLite
  • Garbage Collection
  • Author
  • License

Install

composer require shieldon/simple-cache

Usage

Cache

Class Cache is an adapter that not only allows the implemented instance of Psr\SimpleCache\CacheInterface, but also has built-in drivers already.

__construct($driver = '', $config = [])

Create a cache handler using the file driver.

Example:

$driver = new \Shieldon\SimpleCache\Cache('file', [
    'storage' => __DIR__ . '/../tmp'
]);

$driver

(string|CacheInterface)

The class name of a built-in driver, or a PSR-16 driver that implements Psr\SimpleCache\CacheInterface.

$config

(array)

An array of parameters will be passed to a built-in driver.

Example:

Redis

$config = [
    'host' => '127.0.0.1',
    'port' => 6379,
    'user' => null,
    'pass' => null,
];

File

$config = [
    'storage' => '/tmp/simple-cache',
];

Mysql

$config = [
    'host'    => '127.0.0.1',
    'port'    => 3306,
    'user'    => null,
    'pass'    => null,
    'dbname'  => null,
    'table'   => 'cache_data',
    'charset' => 'utf8'
];

Sqlite

$config = [
    'storage' => '/tmp/simple-cache',
];

Mongo

$config = [
    'host'       => '127.0.0.1',
    'port'       => 27017,
    'user'       => null,
    'pass'       => null,
    'database'   => 'test',
    'collection' => 'cache_data',
];

Memcache, Memcached

$config = [
    'host' => '127.0.0.1',
    'port' => 11211,
];

API

Those API methods are defined on Psr\SimpleCache\CacheInterface. Please check out the PSR-16 document to get the detailed explanation.

  • set
  • get
  • has
  • delete
  • setMultiple
  • getMultiple
  • deleteMultiple
  • clear
  • clearExpiredItems (Non-PSR-16)

set

public function set(string $key, mixed value, $ttl = null);

Note that $ttl accepts null,int,DateInterval. The null means that the key never expires until deleted.

Example:

$cache->set('foo', 'bar', 300);
$cache->set('foo2', 'bar2');

$array = [
    'hello' => 'world',
    'yes' => 'Taiwan',
];

$cache->set('foo3', $array);
$cache->set('foo4', $array, 300);

get

public function get(string $key, mixed $default = null): mixed

Example:

echo $cache->get('foo', 'placeholder');
// bar

sleep(301);

echo $cache->get('foo', 'placeholder');
// placeholder

echo $cache->get('foo');
// null

echo $cache->get('foo2', 'placeholder');
// bar2

$example = $cache->get('foo3', 'placeholder');
var_dump($example);
// string(11) "placeholder"

$example = $cache->get('foo4', 'placeholder');
var_dump($example);
/* 
    array(2) {
    ["hello"]=>
    string(5) "world"
    ["yes"]=>
    string(6) "Taiwan"
    }
*/

has

public function has(string $key): bool

Example:

if ($cache->has('foo3')) {
    echo 'foo3 exists.';
} else {
    echo 'foo3 does not exist.';
}
// foo3 exists.

delete

public function delete(string $key): bool

Example:

if ($cache->delete('foo3')) {
    echo 'foo3 has been deleted successfully.';
} else {
    echo 'Failed to delete key foo3.';
}
// foo3 has been deleted successfully.

if ($cache->has('foo3')) {
    echo 'foo3 exists.';
} else {
    echo 'foo3 does not exist.';
}
// foo3 does not exist.

setMultiple

public function setMultiple(iterable $values, $ttl = null): bool

Note that $ttl accepts null,int,DateInterval. The null means that the key never expires until deleted.

Example:

$array = [
    'bar' => 'foo',
    'bar2' => 'foo2',
];

$cache->setMultiple($array, 300);

getMultiple

public function getMultiple(array $keys, mixed $default = null): iterable

Example:

$example = $cache->getMultiple(['bar', 'bar2', 'bar3'], 'hello');
var_dump($example);
/* 
    array(3) {
    ["bar"]=>
    string(3) "foo"
    ["bar2"]=>
    string(4) "foo2"
    ["bar3"]=>
    string(5) "hello"
    }
*/

deleteMultiple

public function deleteMultiple(array $keys): bool

Example:

if ($cache->deleteMultiple(['bar', 'bar2'])) {
    echo 'bar and bar2 have been deleted successfully.';
} else {
    echo 'Failed to delete keys bar or bar2.';
}
// bar and bar2 have been deleted successfully.

$example = $cache->getMultiple(['bar', 'bar2', 'bar3'], 'hello');
var_dump($example);
/* 
    array(3) {
    ["bar"]=>
    string(5) "hello"
    ["bar2"]=>
    string(5) "hello"
    ["bar3"]=>
    string(5) "hello"
    }
*/

clear

public function clear(): bool

Example:

if ($cache->clear()) {
    echo 'All cached data has been deleted successfully.';
} else {
    echo 'Failed to delete the cached data.';
}
// All cached data has been deleted successfully.

clearExpiredItems Non-PSR-16

public function clearExpiredItems(): array

This method returns a list of deleted cache keys.

Note: Redis and Memcache, Memcached drivers will always return an empty array. See Garbage Collection section below.

Example:

$cache->set('foo', 'bar', 300);
$cache->set('foo2', 'bar2', 5);
$cache->set('foo3', 'bar3', 5);

sleep(6);

$expiredItems = $cache->clearExpiredItems();
var_dump($expiredItems);

/* 
    array(2) {
    [0]=>
    string(4) "foo2"
    [1]=>
    string(4) "foo3"
    }
*/

Build Data Schema

The data schema needs to be built for the initial use of MySQL and SQLite drivers.

This API can be utilized for this purpose.

$cache->rebuild();

Or build it manually.

MySQL

CREATE TABLE IF NOT EXISTS `cache_data` (
    `cache_key` varchar(40) NOT NULL,
    `cache_value` longtext,
    PRIMARY KEY (`cache_key`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

SQLite

CREATE TABLE IF NOT EXISTS cache_data (
    cache_key VARCHAR(40) PRIMARY KEY,
    cache_value LONGTEXT
);

Garbage Collection

For built-in drivers, enabling garbage collection will automatically clear expired cache from your system.

Use the following parameters:

$config = [
    'gc_enable'      => true,
    'gc_divisor'     => 100, // default
    'gc_probability' => 1, // default
];

This implies a 1% probability of executing garbage collection. Avoid setting it to 100% as it will unnecessarily fetch and check all keys one by one.

Example:

$driver = new \Shieldon\SimpleCache\Cache('file', [
    'storage'   => __DIR__ . '/../tmp',
    'gc_enable' => true,
]);

You can just use the gc_enable to enable garbage collection.

Note

For the Redis, Memcache, and Memcached drivers, this method isn't necessary as expired items are automatically cleared.


Contributing

Thank you for your interest in contributing to our project! We welcome contributions from everyone. Before getting started, please take a moment to review the guidelines below:

Guidelines

  • Fork the repository and create your branch from master.
  • Make sure your code follows our coding style and conventions.
  • Keep your code concise, well-documented, and modular.
  • Write clear commit messages that describe the purpose of your changes.
  • Test your changes thoroughly to ensure they don't introduce any new issues.
  • Make sure your code builds successfully without any errors or warnings.
  • Update relevant documentation, including README files if necessary.
  • Submit a pull request (PR) to the master branch of the original repository.

Code Testing

We utilize a Docker image that includes various dependencies for our code testing. The image is based on /tests/Fixture/docker/Dockerfile and is preconfigured with the following components:

  • Redis
  • MongoDB
  • MySQL
  • PHP
  • Memcached
  • APCu

Follow the steps below to run the tests:

  • Make sure you have Docker installed on your machine. If not, you can download and install it from the official Docker website.
  • Navigate to the project directory and build the Docker image by running the following command:
    composer test:docker:build
    
  • Once the Docker image is built, you can run the tests by executing the following command:
    composer test:docker:run
    
  • Observe the test results and make note of any failures or errors. The output will be displayed in the terminal.

Author

The Origin of this Library

This PHP library was created for the 12th Ironman Game competition, hosted by ITHelp, a Taiwanese IT community. My chosen topic was "Road to PHP Master - The Best Practice in Open Source Code", composed in traditional Chinese. You can read it here if you're interested.

License

MIT

simple-cache's People

Contributors

paulcapron avatar s1syphos avatar terrylinooo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

simple-cache's Issues

Exclude urls from cache

Hello,

I think a function to exclusive some cache urls would be nice.

In my case we have a reservation plugin and the search page to be cached for all, since visitors will still select other dates.

Another serial option is to cache by url parameters and do nothing in general.

example url:

search/?dep=2022-02-09+14%3A38&p1=403&d1=402&p2=&d2=&ppl=1&trip=1

Thanks

Checking if MySQL db has been built

Hey there,
I'm thinking about the rebuild() function, and how to check if the database was initiated before. For sqlite, I would simply check if cache.sqlite3 exists, but how would I do this for MySQL?

Since simple-cache handles the db connection, it could provide a) a method or b) check automatically & (re)build if need be ..

I'm grateful for any pointer in the right direction ..
S1SYPHOS

Getting error when using sqlite

Getting error when using sqlite

code
new \Shieldon\SimpleCache\Cache('sqlite', ['storage' => __DIR__ . '/simple-cache']);

error
PHP Fatal error: Uncaught PDOException: SQLSTATE[HY000]: General error: 1 no such table: cache_data in vendor\shieldon\simple-cache\src\SimpleCache\Driver\SqlTrait.php:153

Has method does not work correctly (Driver File)

The method checks only the physical existence of the file, even if the cache is expired

It's probably better to check that the cache time has not expired
In other drivers, the cache is deleted automatically upon expiration, you need to do something different with the file driver

The last update broke the functionality

PHP 8.x

for version 8 PHP installs version psr/simple-cache 3.0
This version breaks compatibility

PHP Fatal error:  Declaration of Shieldon\SimpleCache\CacheProvider::get($key, $default = null) must be compatible with Psr\SimpleCache\CacheInterface::get(string $key, mixed $default = null): mixed

Suggestion: Clean up of expired cache items

Great library, can certainly see myself using this outside of a framework.

I think it would benefit from a "clean up" (not clear) for removing expired but not deleted items. The purpose being that sometimes you want to purge the cache of expired items, but you don't want to fully clear it, as perhaps the cache has resource intensive items such as generated thumbnails.

Little pushed on time at the moment, but happy to submit a PR too if you like the idea. And apologies if this is not the correct place for suggestions.

apcu part is not handling multiple websites well

apcu part is not handling multiple websites well. See terrylinooo/cache-master#7

This is how the 'w3 total cache' plugin uses apcu. I guess if you incorporate something like the website name with using the cache, this should be fixed.

w3tc_915778564__34_pgcache_dadcd63b66f42d4e8e6246980ab7fc70_gzip | 8 | 1104 | 2021/08/24 13:40:27 | 2021/08/24 13:38:02 | 2021/08/24 13:38:02 | 86400 seconds | [Delete Now]
w3tc_915778564__33_pgcache_8ff652f57f5ec5b6f56a9e382cb01575_gzip | 4 | 5200 | 2021/08/20 07:51:43 | 2021/08/19 20:17:44 | 2021/08/19 20:17:44 | 86400 seconds | [Delete Now]
w3tc_915778564__1_pgcache_9349156837b1d706e1884c4c6be7f5cc | 4 | 15952 | 2021/08/24 12:45:08 | 2021/08/24 04:01:11 | 2021/08/24 04:01:11 | 86400 seconds | [Delete Now]
w3tc_915778564__33_pgcache_eec34b1b18b401377174ae2548bff425_gzip | 3 | 1104 | 2021/08/20 07:51:33 | 2021/08/19 20:17:46 | 2021/08/19 20:17:46 | 86400 seconds | [Delete Now]
w3tc_915778564__34_pgcache_a2452f70a22449f2d8aceab1723c973c_gzip | 2 | 5200 | 2021/08/24 13:39:42 | 2021/08/24 13:38:10 | 2021/08/24 13:38:10 | 86400 seconds | [Delete Now]
w3tc_915778564__34_pgcache_2ef4ed86b1ce00114efdd0cfdf8301b6_gzip | 2 | 4688 | 2021/08/24 13:54:06 | 2021/08/24 13:37:59 | 2021/08/24 13:37:59 | 86400 seconds | [Delete Now]
w3tc_915778564__33_pgcache_7c73ba90c2b3eeeed89d664d89adbff4_gzip | 2 | 6224 | 2021/08/23 19:45:32 | 2021/08/23 16:56:14 | 2021/08/23 16:56:14 | 86400 seconds | [Delete Now]
w3tc_915778564__33_pgcache_4f8e342babbf61c28004677c44c73824_gzip | 2 | 568 | 2021/08/20 07:21:03 | 2021/08/19 19:15:48 | 2021/08/19 19:15:48 | 86400 seconds | [Delete Now]

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.