PHP Logopredis/predis

Predis is a robust and feature-rich pure-PHP client library for Redis, an open-source, in-memory data structure store used as a database, cache, and message broker. Unlike other Redis clients for PHP that might require the `phpredis` C extension, Predis is written entirely in PHP, making it easy to install and deploy without any external dependencies beyond PHP itself.

Key Features of Predis:
* Pure PHP: No C extensions are required, simplifying installation and portability across different environments.
* Comprehensive Protocol Support: Supports both the original `RESP` (REdis Serialization Protocol) and `RESP2`, allowing communication with various Redis server versions.
* Extensible Architecture: Allows for custom command implementations, connection classes, and profiles.
* Connection Management: Handles TCP/IP, UNIX domain sockets, and `php-stream` or `ext-socket` backends. It also supports persistent connections.
* High Availability & Clustering: Provides abstractions for client-side sharding, Redis Cluster, Sentinel, and master/slave replication setups, ensuring high availability and scalability.
* Pipelines and Transactions: Supports pipelining commands for improved performance by sending multiple commands in one go, and transactions (`MULTI`/`EXEC`) for atomic operations.
* Publish/Subscribe: Facilitates real-time communication patterns using Redis's Pub/Sub capabilities.
* Error Handling: Offers robust error handling mechanisms for network issues and Redis-specific errors.
* Command Abstraction: Provides a fluent API that maps directly to Redis commands, making it intuitive to use.

Predis is typically installed via Composer, PHP's dependency manager, making it a standard choice for modern PHP applications needing Redis integration for caching, session management, job queues, or real-time features.

Example Code

<?php

require __DIR__ . '/vendor/autoload.php';

use Predis\Client;
use Predis\Connection\ConnectionException;

echo "--- Predis Example ---\n";

try {
    // 1. Establish a connection to Redis
    // By default, it connects to 127.0.0.1:6379
    // You can also pass an array for more options:
    // $client = new Client([
    //     'scheme' => 'tcp',
    //     'host'   => '127.0.0.1',
    //     'port'   => 6379,
    //     'database' => 0,
    //     'password' => 'your_password' // If Redis requires authentication
    // ]);
    $client = new Client();
    echo "Connected to Redis successfully.\n";

    // 2. Basic Key-Value Operations (SET, GET)
    $key = 'my_test_key';
    $value = 'Hello from Predis!';
    $client->set($key, $value);
    echo "SET '{$key}' to '{$value}'.\n";

    $retrievedValue = $client->get($key);
    echo "GET '{$key}': '{$retrievedValue}'.\n";

    // 3. Check if a key exists (EXISTS)
    if ($client->exists($key)) {
        echo "'{$key}' exists.\n";
    } else {
        echo "'{$key}' does not exist.\n";
    }

    // 4. Incrementing a counter (INCR, DECR)
    $counterKey = 'page_views';
    $client->set($counterKey, 0); // Initialize if not present
    $client->incr($counterKey);
    $client->incr($counterKey);
    $client->incrby($counterKey, 5); // Increment by 5
    echo "Current '{$counterKey}': " . $client->get($counterKey) . ".\n";
    $client->decr($counterKey);
    echo "After DECR '{$counterKey}': " . $client->get($counterKey) . ".\n";


    // 5. Working with Lists (LPUSH, RPUSH, LRANGE)
    $listKey = 'my_list';
    $client->del($listKey); // Clear the list for a fresh start

    $client->rpush($listKey, 'item A'); // Right Push
    $client->lpush($listKey, 'item B'); // Left Push
    $client->rpush($listKey, 'item C');

    $listItems = $client->lrange($listKey, 0, -1); // Get all items
    echo "Items in '{$listKey}': " . implode(', ', $listItems) . ".\n";
    // Expected order: B, A, C

    // 6. Set a key with an expiration time (EXPIRE, SETEX)
    $tempKey = 'ephemeral_key';
    $client->setex($tempKey, 10, 'This key will expire in 10 seconds.'); // Set with expiration
    echo "Set '{$tempKey}' with value: '{$client->get($tempKey)}' and 10s expiration.\n";

    // 7. Using Pipelines for improved performance
    echo "\n--- Using Pipeline ---\n";
    $responses = $client->pipeline(function ($pipe) {
        $pipe->set('pipeline_key_1', 'value 1');
        $pipe->set('pipeline_key_2', 'value 2');
        $pipe->get('pipeline_key_1');
        $pipe->incr('pipeline_counter');
        $pipe->get('pipeline_counter');
    });

    echo "Pipeline responses:\n";
    foreach ($responses as $response) {
        echo "  - " . (is_array($response) ? json_encode($response) : $response) . "\n";
    }

    // 8. Cleaning up (DEL)
    $client->del([$key, $counterKey, $listKey, $tempKey, 'pipeline_key_1', 'pipeline_key_2', 'pipeline_counter']);
    echo "\nCleaned up example keys.\n";

} catch (ConnectionException $e) {
    echo "Could not connect to Redis: " . $e->getMessage() . "\n";
    echo "Please ensure Redis server is running on 127.0.0.1:6379.\n";
} catch (Exception $e) {
    echo "An unexpected error occurred: " . $e->getMessage() . "\n";
}

echo "--- End of Predis Example ---\n";
?>