Skip to content

Commit c79b13b

Browse files
committed
Add option to enable memcached extension for get/set, close #67
1 parent 1c38202 commit c79b13b

4 files changed

Lines changed: 58 additions & 39 deletions

File tree

config.dist.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
//'path' => '/var/run/redis/redis-server.sock', // Unix domain socket (optional).
5050
//'databases' => 16, // Number of databases, use this if the CONFIG command is disabled (optional).
5151
//'scansize' => 1000, // Number of keys, the server will use the SCAN command instead of KEYS (optional).
52-
//'separator' => ':', // Separator for tree view (optional)
52+
//'separator' => ':', // Separator for tree view (optional).
5353
],
5454
],
5555
'memcached' => [
@@ -58,10 +58,11 @@
5858
'host' => '127.0.0.1', // Optional when a path is specified.
5959
'port' => 11211, // Optional when the default port is used.
6060
//'path' => '/var/run/memcached/memcached.sock', // Unix domain socket (optional).
61-
//'separator' => ':', // Separator for tree view (optional)
61+
//'separator' => ':', // Separator for tree view (optional).
62+
//'extension' => true, // Enable Memcached extension only for get and set operations (optional).
6263
],
6364
],
64-
'apcuseparator' => ':', // Separator for tree view (optional)
65+
'apcuseparator' => ':', // Separator for tree view (optional).
6566
// Example of authentication with http auth.
6667
/*'auth' => static function (): void {
6768
$username = 'admin';
@@ -145,7 +146,7 @@
145146
'timeformat' => 'd. m. Y H:i:s',
146147
'decimalsep' => ',',
147148
'thousandssep' => ' ',
148-
'listview' => 'table', // table/tree - default key list view
149+
'listview' => 'table', // table/tree - default key list view.
149150
'panelrefresh' => 30, // In seconds, refresh interval for panels - default 30
150151
'metricsrefresh' => 60, // In seconds, refresh interval for metrics - default 60
151152
'metricstab' => 1440, // Default tab in metrics, 60 - Last hour, 1440 - Last day, 10080 - Last week, 43200 - Last month - default 1440

src/Dashboards/Memcached/MemcachedTrait.php

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,15 @@ trait MemcachedTrait {
2222
*/
2323
private function getPanelsData(bool $command_stats = false): array {
2424
try {
25+
$title = '';
26+
2527
if (class_exists(PHPMem::class)) {
2628
$title = 'PHPMem v'.PHPMem::VERSION;
29+
30+
$server = $this->servers[$this->current_server];
31+
if (isset($server['extension']) && $server['extension'] === true && extension_loaded('memcached')) {
32+
$title .= ' + Memcached';
33+
}
2734
}
2835

2936
$info = $this->memcached->getServerStats();
@@ -32,7 +39,7 @@ private function getPanelsData(bool $command_stats = false): array {
3239

3340
$stats = [
3441
[
35-
'title' => $title ?? null,
42+
'title' => $title,
3643
'moreinfo' => true,
3744
'data' => [
3845
'Version' => $info['version'],
@@ -94,9 +101,9 @@ private function moreInfo(): string {
94101
$info = $this->memcached->getServerStats();
95102
$info += ['settings' => $this->memcached->getServerStats('settings')];
96103

97-
if (extension_loaded('memcached') || extension_loaded('memcache')) {
98-
$memcached = extension_loaded('memcached') ? 'd' : '';
99-
$info += Helpers::getExtIniInfo('memcache'.$memcached);
104+
$server = $this->servers[$this->current_server];
105+
if (isset($server['extension']) && $server['extension'] === true && extension_loaded('memcached')) {
106+
$info += Helpers::getExtIniInfo('memcached');
100107
}
101108

102109
return $this->template->render('partials/info_table', [
@@ -126,7 +133,7 @@ private function viewKey(): string {
126133
Helpers::export(
127134
[['key' => $key, 'ttl' => $ttl]],
128135
$key,
129-
fn (string $key): string => base64_encode($this->memcached->getKey($key))
136+
fn (string $key): string => base64_encode($this->memcached->get($key))
130137
);
131138
}
132139

@@ -135,7 +142,7 @@ private function viewKey(): string {
135142
Http::redirect();
136143
}
137144

138-
$value = $this->memcached->getKey($key);
145+
$value = $this->memcached->get($key);
139146

140147
[$formatted_value, $encode_fn, $is_formatted] = Value::format($value);
141148

@@ -184,7 +191,7 @@ private function form(): string {
184191
$value = Http::post('value', '');
185192

186193
if (isset($_GET['key']) && $this->memcached->exists($key)) {
187-
$value = $this->memcached->getKey($key);
194+
$value = $this->memcached->get($key);
188195
}
189196

190197
if (isset($_POST['submit'])) {
@@ -551,7 +558,7 @@ private function mainDashboard(): string {
551558
}
552559

553560
Helpers::export($keys_to_export, 'memcached_backup', function (string $key): ?string {
554-
$value = $this->memcached->getKey(urldecode($key));
561+
$value = $this->memcached->get(urldecode($key));
555562

556563
return $value !== false ? base64_encode($value) : null;
557564
});

src/Dashboards/Memcached/PHPMem.php

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
namespace RobiNN\Pca\Dashboards\Memcached;
1010

11+
use Memcached;
1112
use function explode;
1213
use function is_numeric;
1314
use function preg_match;
@@ -29,6 +30,8 @@ class PHPMem {
2930

3031
private ?string $server_version = null;
3132

33+
private ?Memcached $memcached = null;
34+
3235
private const NO_END_COMMANDS = [
3336
'me' => true, 'incr' => true, 'decr' => true, 'version' => true,
3437
'ms' => true, 'md' => true, 'ma' => true, 'cache_memlimit' => true,
@@ -44,9 +47,18 @@ class PHPMem {
4447
];
4548

4649
/**
47-
* @param array<string, int|string> $server
50+
* @param array<string, int|string|bool> $server
4851
*/
4952
public function __construct(protected array $server = []) {
53+
if (isset($this->server['extension']) && $this->server['extension'] === true && extension_loaded('memcached')) {
54+
$this->memcached = new Memcached();
55+
56+
if (isset($this->server['path'])) {
57+
$this->memcached->addServer($this->server['path'], 0);
58+
} else {
59+
$this->memcached->addServer($this->server['host'], (int) $this->server['port']);
60+
}
61+
}
5062
}
5163

5264
/**
@@ -55,28 +67,43 @@ public function __construct(protected array $server = []) {
5567
* @throws MemcachedException
5668
*/
5769
public function set(string $key, mixed $value, int $expiration = 0): bool {
70+
if ($this->memcached !== null) {
71+
return $this->memcached->set($key, $value, $expiration);
72+
}
73+
5874
$value = is_scalar($value) ? (string) $value : serialize($value);
5975
$raw = $this->runCommand('set '.$key.' 0 '.$expiration.' '.strlen($value)."\r\n".$value);
6076

6177
return str_starts_with($raw, 'STORED');
6278
}
6379

6480
/**
65-
* Retrieve an item.
81+
* Get raw key.
6682
*
6783
* @throws MemcachedException
6884
*/
6985
public function get(string $key): string|false {
86+
if ($this->memcached !== null) {
87+
$value = $this->memcached->get($key);
88+
89+
if ($this->memcached->getResultCode() === Memcached::RES_NOTFOUND) {
90+
return false;
91+
}
92+
93+
return is_scalar($value) ? (string) $value : serialize($value);
94+
}
95+
7096
$raw = $this->runCommand('get '.$key);
71-
$lines = explode("\r\n", $raw);
97+
$data = explode("\r\n", $raw);
7298

73-
if (str_starts_with($raw, 'VALUE') && str_ends_with($raw, 'END')) {
74-
return $lines[1];
99+
if ($data[0] === 'END') {
100+
return false;
75101
}
76102

77-
return false;
103+
return !isset($data[1]) || $data[1] === 'N;' ? '' : $data[1];
78104
}
79105

106+
80107
/**
81108
* Delete item from the server.
82109
*
@@ -258,22 +285,6 @@ public function parseLine(string $line): array {
258285
return $data;
259286
}
260287

261-
/**
262-
* Get raw key.
263-
*
264-
* @throws MemcachedException
265-
*/
266-
public function getKey(string $key): string|false {
267-
$raw = $this->runCommand('get '.$key);
268-
$data = explode("\r\n", $raw);
269-
270-
if ($data[0] === 'END') {
271-
return false;
272-
}
273-
274-
return !isset($data[1]) || $data[1] === 'N;' ? '' : $data[1];
275-
}
276-
277288
/**
278289
* Get key meta-data.
279290
*
@@ -315,7 +326,7 @@ public function getKeyMeta(string $key): array {
315326
* @throws MemcachedException
316327
*/
317328
public function exists(string $key): bool {
318-
return $this->getKey($key) !== false;
329+
return $this->get($key) !== false;
319330
}
320331

321332
/**

tests/Dashboards/MemcachedTest.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ public function testDeleteKeys(): void {
8787
#[DataProvider('keysProvider')]
8888
public function testSetGetKey(string $type, mixed $original, mixed $expected): void {
8989
$this->memcached->set('pu-test-'.$type, $original);
90-
$this->assertSame($expected, Helpers::mixedToString($this->memcached->getKey('pu-test-'.$type)));
90+
$this->assertSame($expected, Helpers::mixedToString($this->memcached->get('pu-test-'.$type)));
9191
$this->memcached->delete('pu-test-'.$type);
9292
}
9393

@@ -104,7 +104,7 @@ public function testSaveKey(): void {
104104
Http::stopRedirect();
105105
$this->dashboard->saveKey();
106106

107-
$this->assertSame('test-value', $this->memcached->getKey($key));
107+
$this->assertSame('test-value', $this->memcached->get($key));
108108

109109
$this->memcached->delete($key);
110110
}
@@ -266,7 +266,7 @@ public function testExportAndImport(): void {
266266
$export_keys_array,
267267
'memcached_backup',
268268
function (string $key): ?string {
269-
$value = $this->memcached->getKey(urldecode($key));
269+
$value = $this->memcached->get(urldecode($key));
270270

271271
return $value !== false ? base64_encode($value) : null;
272272
},
@@ -299,7 +299,7 @@ function (string $key): ?string {
299299

300300
foreach ($keys_to_test as $key => $data) {
301301
$this->assertTrue($this->memcached->exists($key));
302-
$this->assertSame($data['value'], $this->memcached->getKey($key));
302+
$this->assertSame($data['value'], $this->memcached->get($key));
303303
$this->memcached->delete($key);
304304
}
305305

0 commit comments

Comments
 (0)