PhpRedis

Cache LibraryPHPRedisExtension ModuleHigh PerformanceDistributed Cache

GitHub Overview

phpredis/phpredis

A PHP extension for Redis

Stars10,157
Watchers451
Forks2,150
Created:March 15, 2011
Language:C
License:Other

Topics

clusterkeydbphpredisredis-clustervalkey

Star History

phpredis/phpredis Star History
Data as of: 10/22/2025, 08:07 AM

Cache Library

PhpRedis

Overview

PhpRedis is a Redis extension module for PHP implemented as a native C extension, providing high-performance communication with Redis servers. It supports configurations ranging from single Redis instances to high-availability setups using RedisCluster and RedisSentinel, making it ideal for caching, session management, and real-time data processing.

Details

PhpRedis is a C extension designed for efficient utilization of Redis's rich features from PHP. Compared to Pure PHP libraries (like Predis), it offers significant performance improvements and is optimized for large-scale production environments.

Key technical features:

  • Native C implementation: Significant performance improvement over Pure PHP implementations
  • Full feature support: Comprehensive support up to Redis 7.x latest features
  • Cluster support: Horizontal scaling with RedisCluster
  • High availability: Automatic failover with RedisSentinel
  • Array support: Automatic sharding with RedisArray
  • Session integration: Usage as PHP session handler

Technical architecture:

  • Connection management: Persistent connections, connection pooling, timeout control
  • Serialization: Support for PHP, igbinary, msgpack
  • Compression: Bandwidth reduction with LZF, ZSTD, LZ4
  • SSL/TLS: Encrypted communication support

Pros and Cons

Pros

  • Maximum performance: Optimized Redis communication through C extension
  • Complete functionality: Comprehensive access to all Redis features
  • Production ready: Cluster, sentinel, and array capabilities
  • Session integration: Use as PHP session storage
  • Rich configuration: Connection, serialization, compression options
  • Proven track record: Used in many large-scale web services
  • Active development: Continuous updates and latest Redis support

Cons

  • Installation requirements: C extension compilation and installation needed
  • Environment dependency: Module activation required in server environment
  • Redis dependency: Dependency on Redis server
  • Learning curve: Requires Redis knowledge and configuration expertise
  • Debugging difficulty: C extension level issues are hard to investigate
  • Version management: Three-layer version management (PHP-Redis-PhpRedis)

Reference Links

Usage Examples

Basic Redis Connection and Operations

<?php
// Redis connection
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);

// Authentication if required
// $redis->auth('your_password');

// Basic key-value operations
$redis->set('user:1000', 'John Doe');
$redis->expire('user:1000', 3600); // Expire in 1 hour

$username = $redis->get('user:1000');
echo "Username: " . $username . "\n";

// Batch operations for multiple keys
$redis->mset([
    'product:1' => 'Laptop',
    'product:2' => 'Mouse',
    'product:3' => 'Keyboard'
]);

$products = $redis->mget(['product:1', 'product:2', 'product:3']);
print_r($products);

// List data structure
$redis->lpush('notifications', 'New message from admin');
$redis->lpush('notifications', 'Your order has been shipped');

$notifications = $redis->lrange('notifications', 0, -1);
print_r($notifications);
?>

Using as PHP Session Storage

<?php
// Session configuration (php.ini or runtime settings)
ini_set('session.save_handler', 'redis');
ini_set('session.save_path', 'tcp://127.0.0.1:6379?auth=password&database=1');

// Start session
session_start();

// Normal session operations
$_SESSION['user_id'] = 12345;
$_SESSION['username'] = 'john_doe';
$_SESSION['last_login'] = time();

// Display session data
echo "User ID: " . $_SESSION['user_id'] . "\n";
echo "Username: " . $_SESSION['username'] . "\n";

// Destroy session
// session_destroy();
?>

RedisCluster Usage

<?php
// RedisCluster connection
$cluster = new RedisCluster(null, [
    'host1:7000',
    'host2:7001', 
    'host3:7002'
], 1.5, 1.5, true, 'cluster_password');

// Check cluster information
$masters = $cluster->_masters();
echo "Number of master nodes: " . count($masters) . "\n";

// Distributed data storage
for ($i = 0; $i < 100; $i++) {
    $cluster->set("key:$i", "value:$i");
}

// Same node placement using hash tags
$cluster->set('{user:1000}:profile', json_encode(['name' => 'John', 'age' => 30]));
$cluster->set('{user:1000}:settings', json_encode(['theme' => 'dark']));

// Transaction (within same node)
$cluster->multi();
$cluster->set('{transaction}:key1', 'value1');
$cluster->set('{transaction}:key2', 'value2');
$result = $cluster->exec();

print_r($result);
?>

High Availability with RedisSentinel

<?php
// Sentinel connection
$sentinel = new RedisSentinel([
    'host' => '127.0.0.1',
    'port' => 26379,
    'connectTimeout' => 2.5,
    'auth' => 'sentinel_password'
]);

// Get master information
$masters = $sentinel->masters();
foreach ($masters as $master) {
    echo "Master name: " . $master['name'] . "\n";
    echo "IP address: " . $master['ip'] . ":" . $master['port'] . "\n";
    echo "Status: " . $master['flags'] . "\n";
}

// Get current master address
$masterAddr = $sentinel->getMasterAddrByName('mymaster');
if ($masterAddr) {
    $redis = new Redis();
    $redis->connect($masterAddr[0], $masterAddr[1]);
    
    // Write to master
    $redis->set('counter', 1);
    echo "Write to master completed\n";
}

// Get slave information
$slaves = $sentinel->slaves('mymaster');
echo "Number of slaves: " . count($slaves) . "\n";
?>

Automatic Sharding with RedisArray

<?php
// HashRing configuration (redis.ini)
/*
redis.arrays.names = "user_cache"
redis.arrays.hosts = "user_cache[]=host1:6379&user_cache[]=host2:6379&user_cache[]=host3:6379"
redis.arrays.functions = "user_cache=user_hash_function"
redis.arrays.index = "user_cache=1"
redis.arrays.auth = "user_cache=password"
*/

// Custom hash function
function user_hash_function($key) {
    // Hash based on user ID
    if (preg_match('/user:(\d+)/', $key, $matches)) {
        return $matches[1]; // Shard by user ID
    }
    return $key;
}

// Use RedisArray
$redisArray = new RedisArray(['host1:6379', 'host2:6379', 'host3:6379'], [
    'function' => 'user_hash_function',
    'consistent' => true, // Consistent hashing
    'algorithm' => 'crc32'
]);

// Distributed data storage
$redisArray->set('user:1000:profile', json_encode(['name' => 'Alice']));
$redisArray->set('user:2000:profile', json_encode(['name' => 'Bob']));
$redisArray->set('user:3000:profile', json_encode(['name' => 'Charlie']));

// Check which node data is placed on
$target = $redisArray->_target('user:1000:profile');
echo "user:1000 data placement: " . $target . "\n";

// Place same user's data on same node
$host = $redisArray->_target('user:1000:profile');
$redisArray->multi($host)
          ->set('user:1000:settings', json_encode(['theme' => 'light']))
          ->sadd('user:1000:friends', '2000', '3000')
          ->exec();
?>

Advanced Data Structures and Performance Optimization

<?php
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);

// High-speed processing with pipeline
$pipe = $redis->multi(Redis::PIPELINE);
for ($i = 0; $i < 1000; $i++) {
    $pipe->set("batch:$i", "value:$i");
    $pipe->expire("batch:$i", 3600);
}
$results = $pipe->exec();
echo "Pipeline execution result: " . count($results) . " items processed\n";

// Lua script execution
$luaScript = '
    local key = KEYS[1]
    local increment = ARGV[1]
    local current = redis.call("GET", key)
    if current == false then
        current = 0
    end
    local new_value = current + increment
    redis.call("SET", key, new_value)
    return new_value
';

$result = $redis->eval($luaScript, ['counter:atomic', '5'], 1);
echo "Atomic counter result: " . $result . "\n";

// Hash data structure
$redis->hset('user:profile:1000', 'name', 'John Doe');
$redis->hset('user:profile:1000', 'email', '[email protected]');
$redis->hset('user:profile:1000', 'age', 30);

$profile = $redis->hgetall('user:profile:1000');
print_r($profile);

// Sorted set (ranking)
$redis->zadd('leaderboard', 1500, 'player1');
$redis->zadd('leaderboard', 2000, 'player2');
$redis->zadd('leaderboard', 1800, 'player3');

// Get top ranking
$topPlayers = $redis->zrevrange('leaderboard', 0, 2, true);
foreach ($topPlayers as $player => $score) {
    echo "Player: $player, Score: $score\n";
}
?>

Configuration and Monitoring

<?php
$redis = new Redis();

// Connection settings
$redis->connect('127.0.0.1', 6379, 2.5); // 2.5 second timeout

// Or persistent connection
// $redis->pconnect('127.0.0.1', 6379, 2.5, 'persistent_id');

// Option settings
$redis->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_JSON);
$redis->setOption(Redis::OPT_COMPRESSION, Redis::COMPRESSION_LZ4);

// Get server information
$info = $redis->info();
echo "Redis version: " . $info['redis_version'] . "\n";
echo "Used memory: " . $info['used_memory_human'] . "\n";
echo "Connected clients: " . $info['connected_clients'] . "\n";

// Statistics information
$stats = $redis->info('stats');
echo "Total connections: " . $stats['total_connections_received'] . "\n";
echo "Total commands: " . $stats['total_commands_processed'] . "\n";

// Check slow queries
$slowlog = $redis->slowlog('get', 10);
foreach ($slowlog as $entry) {
    echo "Slow query: " . implode(' ', $entry[3]) . " (execution time: " . $entry[2] . "μs)\n";
}

// Check/change configuration
$maxMemory = $redis->config('get', 'maxmemory');
echo "Max memory setting: " . $maxMemory['maxmemory'] . "\n";

// Runtime configuration change
// $redis->config('set', 'maxmemory', '1gb');
?>