Skip to main content
Go to homepage
Github

HTTP Cache

The caching system is used to store dynamic responses, utilizing If-None-Match (ETag) or If-Modified-Since to allow sending an HTTP 304 response.

Caching Response

Starts the buffer to cache the response:

use Inphinit\Experimental\Http\Cache; $cacher = new Cache(); $result = $cacher->start(); if ($result === Cache::FAILED) { error_log('Cache failed', 0); } elseif ($result === Cache::CACHED) { // If it is already cached, processing can be terminated early exit; } echo gmdate('M d Y H:i:s e'), "\n"; echo str_repeat("Hello!\n", 500); // The use of stop() is generally optional, but it is recommended for greater control by the developer $cacher->stop();

HTTP Response:

HTTP/1.1 200 OK Host: localhost:5000 Cache-Control: public, max-age=3600 Expires: Thu, 01 Oct 2026 19:15:25 GMT Last-Modified: Thu, 01 Oct 2026 19:14:55 GMT Etag: "ec6bf505c3767e7598eb89876a52d97c86d42613c6b1a555d525a0a4c0b65601" Content-type: text/html; charset=UTF-8

Development Environment

In the development environment, when the APP_ENVIRONMENT=development environment variable is used, the X-Inphinit-Experimental-Cache header is sent to indicate whether the response was generated during the current request or came from the stored cache, returning something like:

HTTP/1.1 200 OK Host: localhost:5000 Cache-Control: public, max-age=3600 Expires: Thu, 01 Oct 2026 19:15:25 GMT Last-Modified: Thu, 01 Oct 2026 19:14:55 GMT Etag: "ec6bf505c3767e7598eb89876a52d97c86d42613c6b1a555d525a0a4c0b65601" X-Inphinit-Experimental-Cache: writing Content-type: text/html; charset=UTF-8

Possible values for the X-Inphinit-Experimental-Cache header:

Header Description
X-Inphinit-Experimental-Cache: cached If the response for the current request is served from the cache
X-Inphinit-Experimental-Cache: failed If caching the response fails
X-Inphinit-Experimental-Cache: writing If the current response is not from the cache, but the process of writing to the cache has started for use in future requests

Configuring storage

If you need to create separate caches for different users or scenarios to avoid conflicts, you can change the storage location, separating the caches into different directories as shown in the example:

use Inphinit\Experimental\Http\Cache; use Inphinit\Experimental\Utility\Storage; $user_path = 'storage/output/' . $user_id; if (Storage::mkdir($user_path)) { $cacher = new Cache(null, null, $user_path); if ($cacher->start() === Cache::CACHED) { exit; } } else { $cacher = null; } echo gmdate('M d Y H:i:s e'), "\n"; echo str_repeat("Hello!\n", 500); if ($cache !== null) { $cacher->stop(); }

Running tests

To perform tests (such as unit tests) outside the web context, it is possible to explicitly pass the method and path values, as in the example:

use Inphinit\Experimental\Http\Cache; use Inphinit\Experimental\Utility\Storage; $tests_path = 'storage/output/tests/'; if (Storage::mkdir($tests_path) === false) { throw \RuntimeException('Failed to create folder'); } $cacher = new Cache('GET', '/fake_path?a=1&b=2', $tests_path); $result = $cacher->start(); my_assert($result !== Cache::FAILED); echo gmdate('M d Y H:i:s e'), "\n"; echo str_repeat("Hello!\n", 500); $cacher->stop();

Using routes

Example of usage with routes:

use Inphinit\Experimental\Http\Cache; $app->action(['GET', 'HEAD'], '/vehicle/<id:uuid>.html', function (App $app, array $params) { $cacher = new Cache(); if ($cacher->start() === Cache::CACHED) { exit; } echo 'Hour: ', gmdate('M d Y H:i:s e'); $cacher->stop(); });

Using route controllers

Controller example:

<?php namespace Controllers; use Inphinit\Experimental\Http\Cache; class MyController { private $cacher; public function __construct() { $this->cacher = new Cache(); if ($this->cacher->start() === Cache::CACHED) { exit; } } public function __destruct() { $this->cacher->stop(); } public function foo($app, $params) { return 'Foo!'; } public function bar($app, $params) { return 'Bar!'; } }

Configuring routes:

<?php $app->action('GET', '/sample/foo', 'MyController::foo'); $app->action('GET', '/sample/bar', 'MyController::bar');

Extending The Cache class

Example of class extension:

use Inphinit\Experimental\Http\Cache; class MyOwnCache { protected static function match($etag, $modified) { // Validates only ETag, ignoring the use of If-Modified-Since return Request::header('If-None-Match') === "\"{$etag}\""; } protected static function valid($method) { // Caches only requests using the HTTP QUERY method return $method === 'QUERY'; } protected static function createHash($path) { // Uses SHA-384 return \hash('sha384', $path); } } $cacher = new MyOwnCache(); $result = $cacher->start(); if ($result === Cache::CACHED) { exit; } ...

API

Below is an explanation of how to use the methods of the Inphinit\Experimental\Http\Cache class:

Usage Description
__construct(string $method = null, string $path = null, string $storage = null)
  • The $method parameter defines the HTTP method (defaults to the request method).
  • The $path parameter defines the path and query string used to generate the cache key (defaults to the current request's path and query string).
  • The $storage parameter defines the directory location within system/storage where the cache will be stored (defaults to system/storage/cache/output/).
setWriter(callable $callback) Sets a callback to overwrite the buffer on every flush (depends on the $chunkSize parameter in the start($expires, $chunkSize) method).
start(int $expires = 3600, int $chunkSize = 1024): int Starts the buffer to be written to the cache.
  • The $expires parameter defines the time limit for serving a cache (if it exists).
  • The $chunkSize parameter defines when to flush the output after a code block causes the buffer size to equal or exceed $chunkSize.
stop() Ends the buffering.
protected static function match(string $etag, int $modified): bool Checks the If-None-Match header against the ETag and the If-Modified-Since header against the cache modification timestamp - Optionally be overridden in an extended class.
protected static function valid(string $method): bool Checks if the method is HEAD or GET - Optionally be overridden in an extended class to accept other methods.
protected static function createHash(string $path): string Creates the hashes used for caches and ETags - Optionally be overridden in an extended class.