Skip to content

Add #[Override] annotations and improve PHP 8.4 compatibility #16

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion .github/workflows/phpunit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,15 @@ jobs:
strategy:
matrix:
php-version:
- "8.4"
- "8.3"
- "8.2"
- "8.1"

env:
MEMCACHED_SERVER: "memcached:11211"
REDIS_SERVER: "redis:6379"

# Service containers to run
services:
memcached:
Expand All @@ -39,8 +44,8 @@ jobs:
steps:
- uses: actions/checkout@v4
- run: composer install
- run: ./vendor/bin/phpunit --stderr
- run: ./vendor/bin/psalm
- run: ./vendor/bin/phpunit

Documentation:
if: github.ref == 'refs/heads/master'
Expand Down
28 changes: 28 additions & 0 deletions .gitpod.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
tasks:
- name: Run Composer
command: |
composer install

image: byjg/gitpod-image:latest

jetbrains:
phpstorm:
vmoptions: '-Xmx4g'
plugins:
- com.github.copilot
- com.intellij.kubernetes
- com.intellij.mermaid
- ru.adelf.idea.dotenv
- org.toml.lang

vscode:
extensions:
- ikappas.composer
- hbenl.test-adapter-converter
- hbenl.vscode-test-explorer
- felixfbecker.php-debug
- neilbrayfield.php-docblocker
- bmewburn.vscode-intelephense-client
- getpsalm.psalm-vscode-plugin
- SonarSource.sonarlint-vscode
- recca0120.vscode-phpunit
35 changes: 35 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug current Script in Console",
"type": "php",
"request": "launch",
"program": "${file}",
"cwd": "${fileDirname}",
"port": 9003,
"runtimeArgs": [
"-dxdebug.start_with_request=yes"
],
"env": {
"XDEBUG_MODE": "debug,develop",
"XDEBUG_CONFIG": "client_port=${port}"
}
},
{
"name": "PHPUnit Debug",
"type": "php",
"request": "launch",
"program": "${workspaceFolder}/vendor/bin/phpunit",
"cwd": "${workspaceFolder}",
"port": 9003,
"runtimeArgs": [
"-dxdebug.start_with_request=yes"
],
"env": {
"XDEBUG_MODE": "debug,develop",
"XDEBUG_CONFIG": "client_port=${port}"
}
}
]
}
115 changes: 55 additions & 60 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,84 +1,78 @@
# Cache Engine

[![Build Status](https://github.com/byjg/php-cache-engine/actions/workflows/phpunit.yml/badge.svg?branch=master)](https://github.com/byjg/php-cache-engine/actions/workflows/phpunit.yml)
[![Opensource ByJG](https://img.shields.io/badge/opensource-byjg-success.svg)](http://opensource.byjg.com)
[![GitHub source](https://img.shields.io/badge/Github-source-informational?logo=github)](https://github.com/byjg/php-cache-engine/)
[![GitHub license](https://img.shields.io/github/license/byjg/php-cache-engine.svg)](https://opensource.byjg.com/opensource/licensing.html)
[![GitHub release](https://img.shields.io/github/release/byjg/php-cache-engine.svg)](https://github.com/byjg/php-cache-engine/releases/)

# PHP Cache Engine

A multipurpose cache engine PSR-6 and PSR-16 implementation with several drivers.

## PSR-16

PSR-16 defines a Simple Cache interface with less verbosity than PSR-6. Below a list
of engines available in this library that is PSR-16 compliant:

PSR-16 Getting Started: [here](docs/basic-usage-psr16-simplecache.md)

## PSR-6

The PSR-6 implementation use the engines defined above. PSR-6 is more verbosity and
have an extra layer do get and set the cache values.

You can use one of the factory methods to create a instance of the CachePool implementation:

PSR-6 Getting Started: [here](docs/basic-usage-psr6-cachepool.md)

## List of Cache Engines

| Class | Description |
|:-------------------------------------------------------------------------------------------------|:-----------------------------------------------------------------------|
| [\ByJG\Cache\Psr16\NoCacheEngine](docs/class-no-cache-engine.md) | Do nothing. Use it for disable the cache without change your code |
| [\ByJG\Cache\Psr16\ArrayCacheEngine](docs/class-array-cache-engine.md) | Local cache only using array. It does not persists between requests |
| [\ByJG\AnyDataset\NoSql\Cache\KeyValueCacheEngine](https://github.com/byjg/php-anydataset-nosql) | Use S3-Like or ClouflareKV as a store for the cache (other repository) |
| [\ByJG\Cache\Psr16\FileSystemCacheEngine](docs/class-filesystem-cache-engine.md) | Save the cache result in the local file system |
| [\ByJG\Cache\Psr16\MemcachedEngine](docs/class-memcached-engine.md) | Uses the Memcached as the cache engine |
| [\ByJG\Cache\Psr16\TmpfsCacheEngine](docs/class-tmpfs-cache-engine.md) | Uses the Tmpfs as the cache engine |
| [\ByJG\Cache\Psr16\RedisCachedEngine](docs/class-redis-cache-engine.md) | uses the Redis as cache |
| [\ByJG\Cache\Psr16\SessionCachedEngine](docs/class-session-cache-engine.md) | uses the PHP session as cache |
| [\ByJG\Cache\Psr16\ShmopCacheEngine](docs/class-shmop-cache-engine.md) (deprecated) | uses the shared memory area for cache. Use TmpfsCacheEngine. |


## Logging cache commands

You can add a PSR Log compatible to the constructor in order to get Log of the operations

See log examples [here](docs/setup-log-handler.md)
A powerful, versatile cache implementation providing both PSR-6 and PSR-16 interfaces with support for multiple storage drivers.

## Use a PSR-11 container to retrieve the cache keys
## Key Features

You can use a PSR-11 compatible to retrieve the cache keys.
- **PSR-16 Simple Cache interface** - Simple, straightforward caching API
- **PSR-6 Cache Pool interface** - More verbose caching with fine-grained control
- **Multiple storage backends** - Choose from memory, file system, Redis, Memcached and more
- **Atomic operations** - Support for increment, decrement and add operations in compatible engines
- **Garbage collection** - Automatic cleanup of expired items
- **PSR-11 container support** - Retrieve cache keys via dependency container
- **Logging capabilities** - PSR-3 compatible logging of cache operations

See more [here](docs/psr11-usage.md)
## Quick Start

## Beyond the PSR protocol

The PSR protocol is a good way to standardize the cache access,
but sometimes you need to go beyond the protocol.
```bash
composer require "byjg/cache-engine"
```

Some cache engines have additional features that are not covered by the PSR protocol.
```php
// PSR-16 Simple Cache
$cache = new \ByJG\Cache\Psr16\FileSystemCacheEngine();
$cache->set('key', 'value', 3600); // Cache for 1 hour
$value = $cache->get('key');

// PSR-6 Cache Pool
$pool = \ByJG\Cache\Factory::createFilesystemPool();
$item = $pool->getItem('key');
if (!$item->isHit()) {
$item->set('value');
$item->expiresAfter(3600);
$pool->save($item);
}
$value = $item->get();
```

Some examples are:
## Documentation

### Getting Started
- [PSR-16 Simple Cache Usage](docs/basic-usage-psr16-simplecache.md)
- [PSR-6 Cache Pool Usage](docs/basic-usage-psr6-cachepool.md)

### Available Cache Engines
| Engine | Description |
|:--------------------------------------------------------------------|:--------------------------------------------------------|
| [NoCacheEngine](docs/class-no-cache-engine.md) | No-op engine for disabling cache without code changes |
| [ArrayCacheEngine](docs/class-array-cache-engine.md) | In-memory array cache (non-persistent between requests) |
| [FileSystemCacheEngine](docs/class-filesystem-cache-engine.md) | File system based caching |
| [MemcachedEngine](docs/class-memcached-engine.md) | Memcached distributed caching |
| [RedisCacheEngine](docs/class-redis-cache-engine.md) | Redis-based caching |
| [SessionCacheEngine](docs/class-session-cache-engine.md) | PHP session-based caching |
| [TmpfsCacheEngine](docs/class-tmpfs-cache-engine.md) | Tmpfs-based caching |
| [ShmopCacheEngine](docs/class-shmop-cache-engine.md) | Shared memory caching (deprecated) |
| [KeyValueCacheEngine](https://github.com/byjg/php-anydataset-nosql) | S3-Like or CloudflareKV storage (separate package) |

### Advanced Features
- [Atomic Operations](docs/atomic-operations.md)
- [Garbage Collection](docs/garbage-collection.md)
- [Logging](docs/setup-log-handler.md)
- [PSR-11 Container Usage](docs/psr11-usage.md)

## Install

Just type:

```
composer require "byjg/cache-engine"
```


## Running Unit Testes
## Running Unit Tests

```
vendor/bin/phpunit --stderr
```

**Note:** the parameter `--stderr` after `phpunit` is to permit run the tests on SessionCacheEngine.
**Note:** The `--stderr` parameter is required for SessionCacheEngine tests to run properly.

## Dependencies

Expand All @@ -89,5 +83,6 @@ flowchart TD
byjg/cache-engine --> psr/simple-cache
byjg/cache-engine --> psr/container
```

----
[Open source ByJG](http://opensource.byjg.com)
6 changes: 3 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@
}
},
"require": {
"php": ">=8.1 <8.4",
"php": ">=8.1 <8.5",
"psr/cache": "^1.0|^2.0|^3.0",
"psr/log": "^1.0|^1.1|^2.0",
"psr/simple-cache": "^1.0|^2.0",
"psr/container": "^1.0|^1.1|^2.0"
},
"require-dev": {
"phpunit/phpunit": "^9.6",
"vimeo/psalm": "^5.9"
"phpunit/phpunit": "^10.5|^11.5",
"vimeo/psalm": "^5.9|^6.2"
},
"suggest": {
"ext-memcached": "*",
Expand Down
4 changes: 2 additions & 2 deletions docs/atomic-operations.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ The atomic operations are:
The engines that support atomic operations have to implement the `AtomicOperationInterface`.

Some engines that support atomic operations are:
- RedisCachedEngine
- RedisCacheEngine
- MemcachedEngine
- TmpfsCacheEngine
- FileSystemCacheEngine
- TmpfsCacheEngine (inherits from FileSystemCacheEngine)

## Increment

Expand Down
6 changes: 3 additions & 3 deletions docs/class-redis-cache-engine.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,19 @@ $server = 'localhost:5678'
## PSR-16 Constructor

```php
$cache = new \ByJG\Cache\Psr16\RedisCacheEngine($server, $password)
$cache = new \ByJG\Cache\Psr16\RedisCacheEngine($server, $password, $logger)
```

## PSR-6 Constructor

```php
$cachePool = \ByJG\Cache\Factory::createRedisCacheEngine($server, $password)
$cachePool = \ByJG\Cache\Factory::createRedisPool($server, $password, $bufferSize, $logger)
```

or

```php
$cachePool = new \ByJG\Cache\Psr6\CachePool(new \ByJG\Cache\Psr16\RedisCacheEngine($server, $password));
$cachePool = new \ByJG\Cache\Psr6\CachePool(new \ByJG\Cache\Psr16\RedisCacheEngine($server, $password, $logger));
```


6 changes: 3 additions & 3 deletions docs/class-tmpfs-cache-engine.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,19 @@ The TmpfsCacheEngine allows to store the cache files in the `/dev/shm` tmpfs.
## PSR-16 Constructor

```php
$cache = new \ByJG\Cache\Psr16\TmpfsCacheEngine($path, $prefix)
$cache = new \ByJG\Cache\Psr16\TmpfsCacheEngine($prefix, $logger)
```

## PSR-6 Constructor

```php
$cachePool = \ByJG\Cache\Factory::createTmpfsCachePool($path, $prefix, $bufferSize = 10)
$cachePool = \ByJG\Cache\Factory::createTmpfsCachePool($prefix, $logger)
```

or

```php
$cachePool = new \ByJG\Cache\Psr6\CachePool(new \ByJG\Cache\Psr16\createTmpfsCachePool($path, $prefix));
$cachePool = new \ByJG\Cache\Psr6\CachePool(new \ByJG\Cache\Psr16\TmpfsCacheEngine($prefix, $logger));
```


6 changes: 3 additions & 3 deletions docs/garbage-collection.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,18 @@ is based on the Best Effort. It means an expired key is removed only when you tr
If the cache engine has a low hit rate, it is recommended to run a garbage collection process
to avoid the cache to grow indefinitely.

The classes that implement the `GarbageCollectionInterface` have the method `collectGarbage()`.
The classes that implement the `GarbageCollectorInterface` have the method `collectGarbage()`.

Some engines that support garbage collection are:
- FileSystemCacheEngine
- ArrayCacheEngine
- TmpfsCacheEngine
- TmpfsCacheEngine (inherits from FileSystemCacheEngine)

## Example

```php
<?php
/** @var \ByJG\Cache\GarbageCollectionInterface $cache */
/** @var \ByJG\Cache\GarbageCollectorInterface $cache */
$cache->collectGarbage();
```

Expand Down
17 changes: 9 additions & 8 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,25 @@ and open the template in the editor.
bootstrap="./vendor/autoload.php"
colors="true"
testdox="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
convertDeprecationsToExceptions="true"
displayDetailsOnTestsThatTriggerDeprecations="true"
displayDetailsOnTestsThatTriggerErrors="true"
displayDetailsOnTestsThatTriggerNotices="true"
displayDetailsOnTestsThatTriggerWarnings="true"
displayDetailsOnPhpunitDeprecations="true"
stopOnFailure="false"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd">
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.5/phpunit.xsd">

<php>
<ini name="display_errors" value="On"/>
<ini name="display_startup_errors" value="On"/>
<ini name="error_reporting" value="E_ALL"/>
</php>

<coverage>
<source>
<include>
<directory>./src</directory>
<directory>./src/</directory>
</include>
</coverage>
</source>

<testsuites>
<testsuite name="Test Suite">
Expand Down
2 changes: 1 addition & 1 deletion src/Factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public static function createMemcachedPool(?array $servers = null, int $bufferSi
);
}

public static function createRedisCacheEngine(?string $servers = null, ?string $password = null, int $bufferSize = 10, ?LoggerInterface $logger = null): CachePool
public static function createRedisPool(?string $servers = null, ?string $password = null, int $bufferSize = 10, ?LoggerInterface $logger = null): CachePool
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exposed Redis Credentials in Function Signature category Security

Tell me more
What is the issue?

The Redis connection password parameter is passed directly through the function signature, potentially exposing sensitive credentials if used with hardcoded values.

Why this matters

Passing sensitive credentials through function parameters can lead to credentials being exposed in logs, stack traces, or debugging output. It also encourages developers to hardcode passwords in their code.

Suggested change ∙ Feature Preview

Consider accepting a configuration object or using dependency injection:

public static function createRedisPool(?string $servers = null, array $config = [], int $bufferSize = 10, ?LoggerInterface $logger = null): CachePool
{
    return new CachePool(
        new RedisCacheEngine($servers, $config['password'] ?? null, $logger),
        $bufferSize
    );
}
Provide feedback to improve future suggestions

Nice Catch Incorrect Not in Scope Not in coding standard Other

💬 Looking for more details? Reply to this comment to chat with Korbit.

{
return new CachePool(
new RedisCacheEngine($servers, $password, $logger),
Expand Down
Loading