Backend Development 7 min read

Implementing Redis Cache in PHP Using the __call Magic Method

This article explains how to integrate Redis caching into PHP applications by leveraging the __call magic method to create cache, clear, and flush operations for model methods, enabling shared model layers, resource‑efficient caching, flexible data source selection, and clean, reusable code.

php中文网 Courses
php中文网 Courses
php中文网 Courses
Implementing Redis Cache in PHP Using the __call Magic Method

The article introduces a PHP caching solution that uses Redis to meet several goals: sharing the model layer between front‑end and back‑end modules, avoiding wasteful per‑model caching, allowing modules to choose between database and cache reads, eliminating redundant code, and providing an easy‑to‑use interface.

It demonstrates the desired usage pattern where a Book class can be called as (new Book)->getById(100) (original method), (new Book)->getByIdCache(100) (cached call), (new Book)->getByIdClear(100) (clear cache), and (new Book)->getByIdFlush() (flush all related caches).

The implementation relies on PHP's magic method __call() , which is invoked when an undefined method is called. By parsing the method name suffix (Cache, Clear, Flush), the code decides whether to read from Redis, store data, delete a specific cache entry, or flush a set of keys.

Example of a simple Book class with a regular getById($id) method and an overridden __call($name, $arguments) that prints a message for undefined methods.

A singleton Common class provides a Redis connection via Common::redis() , ensuring a single Redis instance throughout the application.

<code>class Book {
    public function __call($name, $arguments) {
        if (strlen($name) < 5) { exit('Method does not exist.'); }
        $method = substr($name, 0, -5);
        $action = substr($name, -5);
        $class = get_class();
        $key = sprintf('%s:%s:', str_replace('\\', '_', $class), $method);
        $key = strtolower($key);
        switch ($action) {
            case 'Cache':
                $key .= md5(json_encode($arguments));
                $data = Common::redis()->get($key);
                if ($data !== false) {
                    $decodeData = json_decode($data, JSON_UNESCAPED_UNICODE);
                    return $decodeData === null ? $data : $decodeData;
                }
                if (!method_exists($this, $method)) { exit('Method does not exist.'); }
                $data = call_user_func_array([$this, $method], $arguments);
                Common::redis()->set($key, json_encode($data), 3600);
                return $data;
            case 'Clear':
                $key .= md5(json_encode($arguments));
                return Common::redis()->del($key);
            case 'Flush':
                $key .= '*';
                $keys = Common::redis()->keys($key);
                return Common::redis()->del($keys);
            default:
                exit('Method does not exist.');
        }
    }
    // other methods
}

class Common {
    private static $redis = null;
    public static function redis() {
        if (self::$redis === null) {
            self::$redis = new \Redis('127.0.0.1');
            self::$redis->connect('redis');
        }
        return self::$redis;
    }
}
</code>

By integrating this __call logic into a base model class, developers can centralize caching behavior, reduce coupling, and simplify maintenance across the application.

The full source code and further usage instructions are available on the project's GitHub repository.

RediscachingsingletonModelcall
php中文网 Courses
Written by

php中文网 Courses

php中文网's platform for the latest courses and technical articles, helping PHP learners advance quickly.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.