Skip to content

Commit 62d6321

Browse files
committed
Fixed #563 (V7)
1 parent fcdcc3a commit 62d6321

File tree

7 files changed

+171
-28
lines changed

7 files changed

+171
-28
lines changed

docs/OPTIONS.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
PhpFastCache has some options that you may want to know before using them, here's the list:
22

33
### File-based drivers options *
4+
* **path** See the "**Host/Authenticating options**" section
45
* **default_chmod** _| int>octal (default: 0777)_ `[>=V4]` This option will define the chmod used to write driver cache files.
56
* **securityKey** _| string (default: 'auto')_ `[>=V4]` A security key that define the subdirectory name. 'auto' value will be the HTTP_HOST value.
6-
* **path** _| string (default: Tmp directory)_ `[>=V4]` The absolute path where the written cache files belong to.
77
* **htaccess** _| bool (default: true)_ `[>=V4]` Option designed to (dis)allow the auto-generation of .htaccess.
88
* **autoTmpFallback** _| bool (default: false)_ `[>=V6]`Option designed to automatically attempt to fallback to temporary directory if the cache fails to write on the specified directory
99
* **secureFileManipulation** _| bool (default: false)_ `[>=V6]` This option enforces a strict I/O manipulation policy by adding more integrity checks. This option may slow down the write operations, therefore you must use it with caution. In case of failure an **phpFastCacheIOException** exception will be thrown. Currently only supported by _Files_ driver.
@@ -22,11 +22,13 @@ PhpFastCache has some options that you may want to know before using them, here'
2222
* **cacheSlamsTimeout** _| int (default: 15)_ `[>=V6]` This option defines the cache slams timeout in seconds
2323

2424
### Host/Authenticating options *
25-
* **host** _| string (default: not set)_ The host
25+
* **host** _| string (default: not set)_ The hostname
26+
* **path** _| string (default: not set)_ `[>=V4], [>=V6.1]` The absolute path where the written cache files belong to (system temp directory by default). **As of the V6.1** this option is also used to define (P)redis and Memcache(d) UNIX socket
2627
* **port** _| int (default: not set)_ The port
2728
* **username** _| string (default: not set)_ The username
2829
* **password** _| string (default: not set)_ The password
2930
* **timeout** _| int (default: not set)_ The timeout (in seconds)
31+
* **servers** _| array (default: not set)_ Array of servers. Exclusive to Memcache(d)
3032

3133
These options differs depending the driver that you are using, see **/Examples** folder for more information about these options.
3234

src/phpFastCache/CacheManager.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -502,9 +502,9 @@ protected static function validateConfig(array $config)
502502
break;
503503
case 'securityKey':
504504
case 'path':
505-
if (!is_string($configValue)) {
506-
throw new phpFastCacheInvalidConfigurationException("{$configName} must be a string");
507-
}
505+
if (!is_string($configValue) && (!is_bool($configValue) || $configValue)) {
506+
throw new phpFastCacheInvalidConfigurationException("{$configName} must be a string or a false boolean");
507+
}
508508
break;
509509
case 'default_chmod':
510510
case 'limited_memory_each_object':

src/phpFastCache/Drivers/Memcache/Driver.php

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -65,25 +65,47 @@ public function driverCheck(): bool
6565
*/
6666
protected function driverConnect(): bool
6767
{
68-
self::checkCollision('Memcache');
69-
if (array_key_exists('compress_data', $this->getConfig()) && $this->getConfig()[ 'compress_data' ] === true) {
70-
$this->memcacheFlags = MEMCACHE_COMPRESSED;
71-
}
7268
$this->instance = new MemcacheSoftware();
73-
$clientConfig = $this->getConfig();
69+
$servers = (!empty($this->config[ 'servers' ]) && is_array($this->config[ 'servers' ]) ? $this->config[ 'servers' ] : []);
70+
if (count($servers) < 1) {
71+
$servers = [
72+
[
73+
'host' => !empty($this->config[ 'host' ]) ? $this->config[ 'host' ] : '127.0.0.1',
74+
'path' => !empty($this->config[ 'path' ]) ? $this->config[ 'path' ] : false,
75+
'port' => !empty($this->config[ 'port' ]) ? $this->config[ 'port' ] : 11211,
76+
'sasl_user' => !empty($this->config[ 'sasl_user' ]) ? $this->config[ 'sasl_user' ] : false,
77+
'sasl_password' =>!empty($this->config[ 'sasl_password' ]) ? $this->config[ 'sasl_password' ]: false,
78+
],
79+
];
80+
}
7481

75-
foreach ($clientConfig[ 'servers' ] as $server) {
82+
foreach ($servers as $server) {
7683
try {
77-
if (!$this->instance->addServer($server[ 'host' ], $server[ 'port' ])) {
84+
/**
85+
* If path is provided we consider it as an UNIX Socket
86+
*/
87+
if(!empty($server[ 'path' ]) && !$this->instance->addServer($server[ 'path' ], 0)){
88+
$this->fallback = true;
89+
}else if (!empty($server[ 'host' ]) && !$this->instance->addServer($server[ 'host' ], $server[ 'port' ])) {
7890
$this->fallback = true;
7991
}
92+
8093
if (!empty($server[ 'sasl_user' ]) && !empty($server[ 'sasl_password' ])) {
81-
$this->instance->setSaslAuthData($server[ 'sasl_user' ], $server[ 'sasl_password' ]);
94+
throw new phpFastCacheDriverException('Unlike Memcached, Memcache does not support SASL authentication');
8295
}
8396
} catch (\Exception $e) {
8497
$this->fallback = true;
8598
}
99+
100+
/**
101+
* Since Memcached does not throw
102+
* any error if not connected ...
103+
*/
104+
if(!$this->instance->getServerStatus(!empty($server[ 'path' ]) ? $server[ 'path' ] : $server[ 'host' ], !empty($server[ 'port' ]) ? $server[ 'port' ] : 0)){
105+
throw new phpFastCacheDriverException('Memcache seems to not be connected');
106+
}
86107
}
108+
87109
return true;
88110
}
89111

src/phpFastCache/Drivers/Memcached/Driver.php

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,22 +62,47 @@ protected function driverConnect(): bool
6262
{
6363
$this->instance = new MemcachedSoftware();
6464
$this->instance->setOption(\Memcached::OPT_BINARY_PROTOCOL, true);
65+
$servers = (!empty($this->config[ 'servers' ]) && is_array($this->config[ 'servers' ]) ? $this->config[ 'servers' ] : []);
66+
if (count($servers) < 1) {
67+
$servers = [
68+
[
69+
'host' => !empty($this->config[ 'host' ]) ? $this->config[ 'host' ] : '127.0.0.1',
70+
'path' => !empty($this->config[ 'path' ]) ? $this->config[ 'path' ] : false,
71+
'port' => !empty($this->config[ 'port' ]) ? $this->config[ 'port' ] : 11211,
72+
'sasl_user' => !empty($this->config[ 'sasl_user' ]) ? $this->config[ 'sasl_user' ] : false,
73+
'sasl_password' =>!empty($this->config[ 'sasl_password' ]) ? $this->config[ 'sasl_password' ]: false,
74+
],
75+
];
76+
}
6577

66-
$clientConfig = $this->getConfig();
67-
68-
foreach ($clientConfig[ 'servers' ] as $server) {
78+
foreach ($servers as $server) {
6979
try {
70-
if (!$this->instance->addServer($server[ 'host' ], $server[ 'port' ])) {
80+
/**
81+
* If path is provided we consider it as an UNIX Socket
82+
*/
83+
if(!empty($server[ 'path' ]) && !$this->instance->addServer($server[ 'path' ], 0)){
84+
$this->fallback = true;
85+
}else if (!empty($server[ 'host' ]) && !$this->instance->addServer($server[ 'host' ], $server[ 'port' ])) {
7186
$this->fallback = true;
7287
}
88+
7389
if (!empty($server[ 'sasl_user' ]) && !empty($server[ 'sasl_password' ])) {
7490
$this->instance->setSaslAuthData($server[ 'sasl_user' ], $server[ 'sasl_password' ]);
7591
}
92+
7693
} catch (\Exception $e) {
7794
$this->fallback = true;
7895
}
7996
}
8097

98+
/**
99+
* Since Memcached does not throw
100+
* any error if not connected ...
101+
*/
102+
$version = $this->instance->getVersion();
103+
if(!$version || $this->instance->getResultCode() !== MemcachedSoftware::RES_SUCCESS){
104+
throw new phpFastCacheDriverException('Memcached seems to not be connected');
105+
}
81106
return true;
82107
}
83108

src/phpFastCache/Drivers/Predis/Driver.php

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,20 @@ public function driverCheck(): bool
5353
*/
5454
protected function driverConnect(): bool
5555
{
56-
$this->instance = new PredisClient($this->getConfig());
56+
$config = $this->getConfig();
57+
if(!empty($config['path'])){
58+
$this->instance = new PredisClient([
59+
'scheme' => 'unix',
60+
'path' => $config['path']
61+
]);
62+
}else{
63+
$this->instance = new PredisClient($this->getConfig());
64+
}
5765

5866
try {
5967
$this->instance->connect();
6068
} catch (PredisConnectionException $e) {
61-
throw new phpFastCacheDriverException('Failed to connect to predis server', 0, $e);
69+
throw new phpFastCacheDriverException('Failed to connect to predis server. Check the Predis documentation: https://github.com/nrk/predis/tree/v1.1#how-to-install-and-use-predis', 0, $e);
6270
}
6371

6472
return true;
@@ -176,6 +184,7 @@ public function getDefaultConfig(): ArrayObject
176184
$defaultConfig = new ArrayObject();
177185

178186
$defaultConfig[ 'host' ] = '127.0.0.1';
187+
$defaultConfig[ 'path' ] = false;
179188
$defaultConfig[ 'port' ] = 6379;
180189
$defaultConfig[ 'password' ] = null;
181190
$defaultConfig[ 'database' ] = null;

src/phpFastCache/Drivers/Redis/Driver.php

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@
1515

1616
namespace phpFastCache\Drivers\Redis;
1717

18-
use phpFastCache\Core\Pool\{DriverBaseTrait, ExtendedCacheItemPoolInterface};
18+
use phpFastCache\Core\Pool\{
19+
DriverBaseTrait, ExtendedCacheItemPoolInterface
20+
};
1921
use phpFastCache\Entities\DriverStatistic;
2022
use phpFastCache\Exceptions\{
2123
phpFastCacheInvalidArgumentException, phpFastCacheLogicException
@@ -53,18 +55,27 @@ protected function driverConnect(): bool
5355
$clientConfig = $this->getConfig();
5456
$this->instance = $this->instance ?: new RedisClient();
5557

56-
if (!$this->instance->connect($clientConfig[ 'host' ], (int)$clientConfig[ 'port' ], (float)$clientConfig[ 'timeout' ])) {
57-
return false;
58+
/**
59+
* If path is provided we consider it as an UNIX Socket
60+
*/
61+
if ($clientConfig[ 'path' ]) {
62+
$isConnected = $this->instance->connect($clientConfig[ 'path' ]);
5863
} else {
64+
$isConnected = $this->instance->connect($clientConfig[ 'host' ], (int)$clientConfig[ 'port' ], (int)$clientConfig[ 'timeout' ]);
65+
}
66+
67+
if (!$isConnected && $clientConfig[ 'path' ]) {
68+
return false;
69+
} else if (!$clientConfig[ 'path' ]) {
5970
if ($clientConfig[ 'password' ] && !$this->instance->auth($clientConfig[ 'password' ])) {
6071
return false;
6172
}
62-
if ($clientConfig[ 'database' ]) {
63-
$this->instance->select((int)$clientConfig[ 'database' ]);
64-
}
73+
}
6574

66-
return true;
75+
if ($clientConfig[ 'database' ]) {
76+
$this->instance->select((int)$clientConfig[ 'database' ]);
6777
}
78+
return true;
6879
}
6980
}
7081

@@ -120,7 +131,7 @@ protected function driverDelete(CacheItemInterface $item): bool
120131
* Check for Cross-Driver type confusion
121132
*/
122133
if ($item instanceof Item) {
123-
return (bool) $this->instance->del($item->getKey());
134+
return (bool)$this->instance->del($item->getKey());
124135
} else {
125136
throw new phpFastCacheInvalidArgumentException('Cross-Driver type confusion detected');
126137
}
@@ -152,7 +163,7 @@ public function getStats(): DriverStatistic
152163
return (new DriverStatistic())
153164
->setData(implode(', ', array_keys($this->itemInstances)))
154165
->setRawData($info)
155-
->setSize((int) $info[ 'used_memory' ])
166+
->setSize((int)$info[ 'used_memory' ])
156167
->setInfo(sprintf("The Redis daemon v%s is up since %s.\n For more information see RawData. \n Driver size includes the memory allocation size.",
157168
$info[ 'redis_version' ], $date->format(DATE_RFC2822)));
158169
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
<?php
2+
3+
/**
4+
* @author Khoa Bui (khoaofgod) <[email protected]> http://www.phpfastcache.com
5+
* @author Georges.L (Geolim4) <[email protected]>
6+
*/
7+
8+
use phpFastCache\CacheManager;
9+
use phpFastCache\Helper\TestHelper;
10+
11+
chdir(__DIR__);
12+
require_once __DIR__ . '/../vendor/autoload.php';
13+
$testHelper = new TestHelper('Memcached altyernative configuration syntax');
14+
15+
$cacheInstanceDefSyntax = CacheManager::getInstance('Memcached', []);
16+
$cacheInstanceOldSyntax = CacheManager::getInstance('Memcached', [
17+
'servers' => [
18+
[
19+
'host' => '127.0.0.1',
20+
'path' => false,
21+
'port' => 11211,
22+
]
23+
]
24+
]);
25+
$cacheInstanceNewSyntax = CacheManager::getInstance('Memcached', [
26+
'host' => '127.0.0.1',
27+
'path' => false,
28+
'port' => 11211,
29+
]);
30+
$cacheKey = 'cacheKey';
31+
$RandomCacheValue = str_shuffle(uniqid('pfc', true));
32+
33+
$cacheItem = $cacheInstanceDefSyntax->getItem($cacheKey);
34+
$cacheItem->set($RandomCacheValue)->expiresAfter(600);
35+
$cacheInstanceDefSyntax->save($cacheItem);
36+
unset($cacheItem);
37+
$cacheInstanceDefSyntax->detachAllItems();
38+
39+
40+
$cacheItem = $cacheInstanceOldSyntax->getItem($cacheKey);
41+
$cacheItem->set($RandomCacheValue)->expiresAfter(600);
42+
$cacheInstanceOldSyntax->save($cacheItem);
43+
unset($cacheItem);
44+
$cacheInstanceOldSyntax->detachAllItems();
45+
46+
$cacheItem = $cacheInstanceNewSyntax->getItem($cacheKey);
47+
$cacheItem->set($RandomCacheValue)->expiresAfter(600);
48+
$cacheInstanceNewSyntax->save($cacheItem);
49+
unset($cacheItem);
50+
$cacheInstanceNewSyntax->detachAllItems();
51+
52+
53+
if($cacheInstanceDefSyntax->getItem($cacheKey)->isHit()){
54+
$testHelper->printPassText('The default Memcached syntax is working well');
55+
}else{
56+
$testHelper->printFailText('The default Memcached syntax is not working');
57+
}
58+
59+
if($cacheInstanceOldSyntax->getItem($cacheKey)->isHit()){
60+
$testHelper->printPassText('The old Memcached syntax is working well');
61+
}else{
62+
$testHelper->printFailText('The old Memcached syntax is not working');
63+
}
64+
65+
if($cacheInstanceNewSyntax->getItem($cacheKey)->isHit()){
66+
$testHelper->printPassText('The new Memcached syntax is working well');
67+
}else{
68+
$testHelper->printFailText('The new Memcached syntax is not working');
69+
}
70+
71+
$cacheInstanceDefSyntax->clear();
72+
$cacheInstanceOldSyntax->clear();
73+
$cacheInstanceNewSyntax->clear();
74+
$testHelper->terminateTest();

0 commit comments

Comments
 (0)