From 15fd0e871185775782a80bc1680044e3e27a85c8 Mon Sep 17 00:00:00 2001 From: Terry Lin Date: Thu, 12 Nov 2020 19:56:37 +0800 Subject: [PATCH] Add "unix_socket" setting for Reids, MongoDB, Memcache and Memcached drivers. --- README.md | 13 ++++++----- src/SimpleCache/AssertTrait.php | 10 +++++++-- src/SimpleCache/Driver/Memcache.php | 26 +++++++++++++++++----- src/SimpleCache/Driver/Memcached.php | 24 +++++++++++++++----- src/SimpleCache/Driver/Mongo.php | 18 +++++++++++---- src/SimpleCache/Driver/Redis.php | 14 ++++++++++-- tests/SimpleCache/Driver/MemcacheTest.php | 21 ++++++++++++++++- tests/SimpleCache/Driver/MemcachedTest.php | 21 ++++++++++++++++- tests/SimpleCache/Driver/MongoTest.php | 19 ++++++++++++++++ tests/SimpleCache/Driver/RedisTest.php | 19 ++++++++++++++++ tests/redis.sh | 1 + 11 files changed, 160 insertions(+), 26 deletions(-) create mode 100644 tests/redis.sh diff --git a/README.md b/README.md index 799b756..d5cce52 100644 --- a/README.md +++ b/README.md @@ -17,17 +17,20 @@ The required parameters are marked by an asterisk (*) | Driver name | `($driver)`| PHP modules | `($config)` | --- | --- | --- | --- | | File | `file` | - | `*storage` | -| Redis | `redis` | redis | `host`, `port`, `user`, `pass` | -| MongoDB | `mongo` | mongodb | `host`, `port`, `user`, `pass`, `dbname`, `collection` | +| Redis | `redis` | redis | `host`, `port`, `user`, `pass`, `unix_socket` | +| MongoDB | `mongo` | mongodb | `host`, `port`, `user`, `pass`, `dbname`, `collection`, `unix_socket` | | MySQL | `mysql` | pdo_mysql | `host`, `port`, `*user`, `*pass`, `*dbname`, `table`, `charset` | | SQLite | `sqlite` | pdo_sqlite | `*storage` | | APC | `apc` | apc | - | | APCu | `apcu` | apcu | - | -| Memcache | `memcache` | memcache | `host`, `port` | -| LibMemcached | `memcached` | memcached | `host`, `port` | +| Memcache | `memcache` | memcache | `host`, `port`, `unix_socket` | +| LibMemcached | `memcached` | memcached | `host`, `port`, `unix_socket` | | WinCache | `wincache` | wincache | - | -Note: **WinCache** is excluded from unit testing since it's only used on Windows, and the testing processes are done on Linux environment. +Note: + +- **WinCache** is excluded from unit testing since it's only used on Windows, and the testing processes are done on Linux environment. +- `unix_socket` is empty by default, accepting the absolute path of the unix domain socket file. If it is set, `host` and `port` will be ignored. This command will show a list of the installed PHP modules. diff --git a/src/SimpleCache/AssertTrait.php b/src/SimpleCache/AssertTrait.php index 9d6e4a6..5b8fb4c 100644 --- a/src/SimpleCache/AssertTrait.php +++ b/src/SimpleCache/AssertTrait.php @@ -108,7 +108,10 @@ protected function assertDirectoryWritable(string $directory): void { if (!is_dir($directory)) { throw new CacheException( - 'The directory of the storage does not exist. (' . $directory . ')' + sprintf( + 'The directory of the storage does not exist. ( %s )', + $directory + ) ); } @@ -116,7 +119,10 @@ protected function assertDirectoryWritable(string $directory): void if (!is_writable($directory)) { throw new CacheException( - 'The directory of the storage must be wriable. (' . $directory . ')' + sprintf( + 'The directory of the storage must be wriable. ( %s )', + $directory + ) ); } diff --git a/src/SimpleCache/Driver/Memcache.php b/src/SimpleCache/Driver/Memcache.php index bee325e..c73bdeb 100644 --- a/src/SimpleCache/Driver/Memcache.php +++ b/src/SimpleCache/Driver/Memcache.php @@ -44,6 +44,9 @@ public function __construct(array $setting = []) $config = [ 'host' => '127.0.0.1', 'port' => 11211, + + // If the UNIX socket is set, host and port will be ignored. + 'unix_socket' => '', ]; foreach (array_keys($config) as $key) { @@ -69,12 +72,23 @@ protected function connect(array $config): void if (extension_loaded('memcache')) { try { $this->memcache = new MemcacheServer(); - $this->memcache->addServer( - $config['host'], - $config['port'], - true, - 1 - ); + + if (!empty($config['unix_socket'])) { + // @codeCoverageIgnoreStart + $this->memcache->addServer( + 'unix://' . $config['unix_socket'], + 0 + ); + // @codeCoverageIgnoreEnd + } else { + $this->memcache->addServer( + $config['host'], + $config['port'], + true, + 1 + ); + } + // @codeCoverageIgnoreStart } catch (Exception $e) { throw new CacheException($e->getMessage()); diff --git a/src/SimpleCache/Driver/Memcached.php b/src/SimpleCache/Driver/Memcached.php index d514487..786c6ff 100644 --- a/src/SimpleCache/Driver/Memcached.php +++ b/src/SimpleCache/Driver/Memcached.php @@ -44,6 +44,9 @@ public function __construct(array $setting = []) $config = [ 'host' => '127.0.0.1', 'port' => 11211, + + // If the UNIX socket is set, host and port will be ignored. + 'unix_socket' => '', ]; foreach (array_keys($config) as $key) { @@ -69,11 +72,22 @@ protected function connect(array $config): void if (extension_loaded('memcached')) { try { $this->memcached = new MemcachedServer(); - $this->memcached->addServer( - $config['host'], - $config['port'], - 1 - ); + + if (!empty($config['unix_socket'])) { + // @codeCoverageIgnoreStart + $this->memcached->addServer( + $config['unix_socket'], + 0 + ); + // @codeCoverageIgnoreEnd + } else { + $this->memcached->addServer( + $config['host'], + $config['port'], + 1 + ); + } + // @codeCoverageIgnoreStart } catch (Exception $e) { throw new CacheException($e->getMessage()); diff --git a/src/SimpleCache/Driver/Mongo.php b/src/SimpleCache/Driver/Mongo.php index 387aa3e..0da9452 100644 --- a/src/SimpleCache/Driver/Mongo.php +++ b/src/SimpleCache/Driver/Mongo.php @@ -75,6 +75,9 @@ public function __construct(array $setting = []) 'pass' => null, 'dbname' => 'test', 'collection' => 'cache_data', + + // If the UNIX socket is set, host, port will be ignored. + 'unix_socket' => '', ]; foreach (array_keys($config) as $key) { @@ -102,6 +105,7 @@ protected function connect(array $config): void { if (extension_loaded('mongodb')) { try { + $auth = ''; $dababase = ''; @@ -116,10 +120,16 @@ protected function connect(array $config): void $dababase = '/' . $config['dbname']; } - // Basic => mongodb://127.0.0.1:27017 - // mongodb://user:pass@127.0.0.1:27017/dbname - $command = 'mongodb://' . $auth . $config['host'] . ':' . $config['port'] . $dababase; - + if (!empty($config['unix_socket'])) { + // @codeCoverageIgnoreStart + $command = 'mongodb://' . $auth . rawurlencode($config['unix_socket']) . $dababase; + // @codeCoverageIgnoreEnd + } else { + // Basic => mongodb://127.0.0.1:27017 + // mongodb://user:pass@127.0.0.1:27017/dbname + $command = 'mongodb://' . $auth . $config['host'] . ':' . $config['port'] . $dababase; + } + $this->mongo = new MongoServer($command); $this->concern = new WriteConcern(WriteConcern::MAJORITY, 1000); diff --git a/src/SimpleCache/Driver/Redis.php b/src/SimpleCache/Driver/Redis.php index 85d0ae5..3068da2 100644 --- a/src/SimpleCache/Driver/Redis.php +++ b/src/SimpleCache/Driver/Redis.php @@ -48,6 +48,9 @@ public function __construct(array $setting = []) 'port' => 6379, 'user' => null, 'pass' => null, + + // If the UNIX socket is set, host, port, user and pass will be ignored. + 'unix_socket' => '', ]; foreach (array_keys($config) as $key) { @@ -73,8 +76,15 @@ protected function connect(array $config): void if (extension_loaded('redis')) { try { $this->redis = new RedisServer(); - $this->redis->connect($config['host'], $config['port']); - $this->auth($config); + + if (!empty($config['unix_socket'])) { + // @codeCoverageIgnoreStart + $this->redis->connect($config['unix_socket']); + // @codeCoverageIgnoreEnd + } else { + $this->redis->connect($config['host'], $config['port']); + $this->auth($config); + } // @codeCoverageIgnoreStart } catch (Exception $e) { diff --git a/tests/SimpleCache/Driver/MemcacheTest.php b/tests/SimpleCache/Driver/MemcacheTest.php index 6ea5086..1d33e58 100644 --- a/tests/SimpleCache/Driver/MemcacheTest.php +++ b/tests/SimpleCache/Driver/MemcacheTest.php @@ -20,7 +20,7 @@ public function getCacheDriver() { $cache = new Memcache([ 'host' => '127.0.0.1', - 'port' => 11211, + 'port' => 11211, ]); return $cache; @@ -36,4 +36,23 @@ public function testCacheDriver() $driver = $this->getCacheDriver(); $this->assertTrue($driver instanceof CacheInterface); } + + public function testConnectWithUnixSocket() + { + $unixSocketFilePath = '/var/run/memcached/memcached.sock'; + + if (file_exists($unixSocketFilePath)) { + $cache = new Memcache([ + 'unix_socket' => $unixSocketFilePath, + ]); + + $cache->set('memcache_socket', 'good'); + $this->assertSame('good', $cache->get('memcache_socket')); + } else { + $this->console(sprintf( + 'Ingore testing with unix domain socket because that file "%s" does not exist.', + $unixSocketFilePath + )); + } + } } \ No newline at end of file diff --git a/tests/SimpleCache/Driver/MemcachedTest.php b/tests/SimpleCache/Driver/MemcachedTest.php index 2f5381a..107ea36 100644 --- a/tests/SimpleCache/Driver/MemcachedTest.php +++ b/tests/SimpleCache/Driver/MemcachedTest.php @@ -20,7 +20,7 @@ public function getCacheDriver() { $cache = new Memcached([ 'host' => '127.0.0.1', - 'port' => 11211, + 'port' => 11211, ]); return $cache; @@ -36,4 +36,23 @@ public function testCacheDriver() $driver = $this->getCacheDriver(); $this->assertTrue($driver instanceof CacheInterface); } + + public function testConnectWithUnixSocket() + { + $unixSocketFilePath = '/var/run/memcached/memcached.sock'; + + if (file_exists($unixSocketFilePath)) { + $cache = new Memcached([ + 'unix_socket' => $unixSocketFilePath, + ]); + + $cache->set('memcached_socket', 'good'); + $this->assertSame('good', $cache->get('memcached_socket')); + } else { + $this->console(sprintf( + 'Ingore testing with unix domain socket because that file "%s" does not exist.', + $unixSocketFilePath + )); + } + } } \ No newline at end of file diff --git a/tests/SimpleCache/Driver/MongoTest.php b/tests/SimpleCache/Driver/MongoTest.php index 80e51f6..7469203 100644 --- a/tests/SimpleCache/Driver/MongoTest.php +++ b/tests/SimpleCache/Driver/MongoTest.php @@ -68,4 +68,23 @@ public function testGetAll() $this->assertSame($items['foo9']['value'], 'bar9'); $this->assertSame($items['foo10']['value'], 'bar10'); } + + public function testConnectWithUnixSocket() + { + $unixSocketFilePath = '/var/run/mongodb/mongodb.sock'; + + if (file_exists($unixSocketFilePath)) { + $cache = new Mongo([ + 'unix_socket' => $unixSocketFilePath, + ]); + + $cache->set('mongodb_socket', 'good'); + $this->assertSame('good', $cache->get('mongodb_socket')); + } else { + $this->console(sprintf( + 'Ingore testing with unix domain socket because that file "%s" does not exist.', + $unixSocketFilePath + )); + } + } } \ No newline at end of file diff --git a/tests/SimpleCache/Driver/RedisTest.php b/tests/SimpleCache/Driver/RedisTest.php index 079ac0b..69fee01 100644 --- a/tests/SimpleCache/Driver/RedisTest.php +++ b/tests/SimpleCache/Driver/RedisTest.php @@ -43,4 +43,23 @@ public function testInvalidUsernameAndPassword() // Nothing happended?? } + + public function testConnectWithUnixSocket() + { + $unixSocketFilePath = '/var/run/redis/redis.sock'; + + if (file_exists($unixSocketFilePath)) { + $cache = new Redis([ + 'unix_socket' => $unixSocketFilePath, + ]); + + $cache->set('redis_socket', 'good'); + $this->assertSame('good', $cache->get('redis_socket')); + } else { + $this->console(sprintf( + 'Ingore testing with unix domain socket because that file "%s" does not exist.', + $unixSocketFilePath + )); + } + } } \ No newline at end of file diff --git a/tests/redis.sh b/tests/redis.sh new file mode 100644 index 0000000..26be2b4 --- /dev/null +++ b/tests/redis.sh @@ -0,0 +1 @@ +php ../vendor/phpunit/phpunit/phpunit --configuration ../phpunit.xml --filter RedisTest ../tests/SimpleCache/Driver/RedisTest.php \ No newline at end of file