Skip to content

Commit 41c3bd6

Browse files
committed
[VarDumper] introduce reflection to discover memcached constants
1 parent 1dd8288 commit 41c3bd6

File tree

2 files changed

+116
-176
lines changed

2 files changed

+116
-176
lines changed

src/Symfony/Component/VarDumper/Caster/MemcachedCaster.php

+37-66
Original file line numberDiff line numberDiff line change
@@ -23,83 +23,54 @@ public static function castMemcached(\Memcached $c, array $a, Stub $stub, $isNes
2323
$a += array(
2424
Caster::PREFIX_VIRTUAL.'servers' => $c->getServerList(),
2525
Caster::PREFIX_VIRTUAL.'options' => new EnumStub(
26-
self::getNonDefaultValueOptions($c)
26+
self::getMemcachedNonDefaultValueOptions($c)
2727
),
2828
);
2929

3030
return $a;
3131
}
3232

33-
private static function getNonDefaultValueOptions(\Memcached $c)
33+
public static function getMemcachedNonDefaultValueOptions(\Memcached $c)
3434
{
35-
$options = array(
36-
'OPT_COMPRESSION' => self::getOptionValue($c, \Memcached::OPT_COMPRESSION),
37-
'OPT_SERIALIZER' => self::getOptionValue($c, \Memcached::OPT_SERIALIZER),
38-
'OPT_PREFIX_KEY' => self::getOptionValue($c, \Memcached::OPT_PREFIX_KEY),
39-
'OPT_HASH' => self::getOptionValue($c, \Memcached::OPT_HASH),
40-
'OPT_DISTRIBUTION' => self::getOptionValue($c, \Memcached::OPT_DISTRIBUTION),
41-
'OPT_LIBKETAMA_COMPATIBLE' => self::getOptionValue($c, \Memcached::OPT_LIBKETAMA_COMPATIBLE),
42-
'OPT_BUFFER_WRITES' => self::getOptionValue($c, \Memcached::OPT_BUFFER_WRITES),
43-
'OPT_BINARY_PROTOCOL' => self::getOptionValue($c, \Memcached::OPT_BINARY_PROTOCOL),
44-
'OPT_NO_BLOCK' => self::getOptionValue($c, \Memcached::OPT_NO_BLOCK),
45-
'OPT_TCP_NODELAY' => self::getOptionValue($c, \Memcached::OPT_TCP_NODELAY),
46-
'OPT_SOCKET_SEND_SIZE' => self::getOptionValue($c, \Memcached::OPT_SOCKET_SEND_SIZE),
47-
'OPT_SOCKET_RECV_SIZE' => self::getOptionValue($c, \Memcached::OPT_SOCKET_RECV_SIZE),
48-
'OPT_CONNECT_TIMEOUT' => self::getOptionValue($c, \Memcached::OPT_CONNECT_TIMEOUT),
49-
'OPT_RETRY_TIMEOUT' => self::getOptionValue($c, \Memcached::OPT_RETRY_TIMEOUT),
50-
'OPT_SEND_TIMEOUT' => self::getOptionValue($c, \Memcached::OPT_SEND_TIMEOUT),
51-
'OPT_RECV_TIMEOUT' => self::getOptionValue($c, \Memcached::OPT_RECV_TIMEOUT),
52-
'OPT_POLL_TIMEOUT' => self::getOptionValue($c, \Memcached::OPT_POLL_TIMEOUT),
53-
'OPT_CACHE_LOOKUPS' => self::getOptionValue($c, \Memcached::OPT_CACHE_LOOKUPS),
54-
'OPT_SERVER_FAILURE_LIMIT' => self::getOptionValue($c, \Memcached::OPT_SERVER_FAILURE_LIMIT),
55-
);
35+
$defaultOptions = self::discoverDefaultMemcachedOptions();
36+
$optionConstants = self::getMemcachedOptionConstants();
37+
38+
$nonDefaultOptions = array();
39+
foreach ($optionConstants as $constantKey => $value) {
40+
if ($defaultOptions[$constantKey] !== $option = $c->getOption($value)) {
41+
$nonDefaultOptions[$constantKey] = $option;
42+
}
43+
}
44+
45+
return $nonDefaultOptions;
46+
}
47+
48+
public static function discoverDefaultMemcachedOptions()
49+
{
50+
$defaultMemcached = new \Memcached();
51+
$defaultMemcached->addServer('127.0.0.1', 11211);
52+
53+
$defaultOptions = array();
54+
$optionConstants = self::getMemcachedOptionConstants();
55+
56+
foreach ($optionConstants as $constantKey => $value) {
57+
$defaultOptions[$constantKey] = $defaultMemcached->getOption($value);
58+
}
5659

57-
return array_filter($options, function ($option) {
58-
return null !== $option ?? $option;
59-
});
60+
return $defaultOptions;
6061
}
6162

62-
private static function getOptionValue(\Memcached $c, int $option)
63+
public static function getMemcachedOptionConstants()
6364
{
64-
switch ($option) {
65-
case \Memcached::OPT_COMPRESSION:
66-
return ($optionValue = $c->getOption(\Memcached::OPT_COMPRESSION)) ? null : $optionValue;
67-
case \Memcached::OPT_SERIALIZER:
68-
return (\Memcached::SERIALIZER_PHP === $optionValue = $c->getOption(\Memcached::OPT_SERIALIZER)) ? null : $optionValue;
69-
case \Memcached::OPT_PREFIX_KEY:
70-
return empty($optionValue = $c->getOption(\Memcached::OPT_PREFIX_KEY)) ? null : $optionValue;
71-
case \Memcached::OPT_HASH:
72-
return (\Memcached::HASH_DEFAULT === $optionValue = $c->getOption(\Memcached::OPT_HASH)) ? null : $optionValue;
73-
case \Memcached::OPT_DISTRIBUTION:
74-
return (\Memcached::DISTRIBUTION_MODULA === $optionValue = $c->getOption(\Memcached::OPT_DISTRIBUTION)) ? null : $optionValue;
75-
case \Memcached::OPT_LIBKETAMA_COMPATIBLE:
76-
return (!($optionValue = $c->getOption(\Memcached::OPT_LIBKETAMA_COMPATIBLE))) ? null : $optionValue;
77-
case \Memcached::OPT_BUFFER_WRITES:
78-
return (!($optionValue = $c->getOption(\Memcached::OPT_BUFFER_WRITES))) ? null : $optionValue;
79-
case \Memcached::OPT_BINARY_PROTOCOL:
80-
return (!($optionValue = $c->getOption(\Memcached::OPT_BINARY_PROTOCOL))) ? null : $optionValue;
81-
case \Memcached::OPT_NO_BLOCK:
82-
return (!($optionValue = $c->getOption(\Memcached::OPT_NO_BLOCK))) ? null : $optionValue;
83-
case \Memcached::OPT_TCP_NODELAY:
84-
return (!($optionValue = $c->getOption(\Memcached::OPT_TCP_NODELAY))) ? null : $optionValue;
85-
case \Memcached::OPT_SOCKET_SEND_SIZE:
86-
return $c->getOption(\Memcached::OPT_SOCKET_SEND_SIZE);
87-
case \Memcached::OPT_SOCKET_RECV_SIZE:
88-
return $c->getOption(\Memcached::OPT_SOCKET_RECV_SIZE);
89-
case \Memcached::OPT_CONNECT_TIMEOUT:
90-
return (1000 === $optionValue = $c->getOption(\Memcached::OPT_CONNECT_TIMEOUT)) ? null : $optionValue;
91-
case \Memcached::OPT_RETRY_TIMEOUT:
92-
return (0 === $optionValue = $c->getOption(\Memcached::OPT_RETRY_TIMEOUT)) ? null : $optionValue;
93-
case \Memcached::OPT_SEND_TIMEOUT:
94-
return (0 === $optionValue = $c->getOption(\Memcached::OPT_SEND_TIMEOUT)) ? null : $optionValue;
95-
case \Memcached::OPT_RECV_TIMEOUT:
96-
return (0 === $optionValue = $c->getOption(\Memcached::OPT_RECV_TIMEOUT)) ? null : $optionValue;
97-
case \Memcached::OPT_POLL_TIMEOUT:
98-
return (1000 === $optionValue = $c->getOption(\Memcached::OPT_POLL_TIMEOUT)) ? null : $optionValue;
99-
case \Memcached::OPT_CACHE_LOOKUPS:
100-
return (0 === $optionValue = $c->getOption(\Memcached::OPT_CACHE_LOOKUPS)) ? null : $optionValue;
101-
case \Memcached::OPT_SERVER_FAILURE_LIMIT:
102-
return (0 === $optionValue = $c->getOption(\Memcached::OPT_SERVER_FAILURE_LIMIT)) ? null : $optionValue;
65+
$reflectedMemcached = new \ReflectionClass(\Memcached::class);
66+
67+
$optionConstants = array();
68+
foreach ($reflectedMemcached->getConstants() as $constantKey => $value) {
69+
if ('OPT_' === substr($constantKey, 0, 4)) {
70+
$optionConstants[$constantKey] = $value;
71+
}
10372
}
73+
74+
return $optionConstants;
10475
}
10576
}

src/Symfony/Component/VarDumper/Tests/Caster/MemcachedCasterTest.php

+79-110
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\VarDumper\Tests\Caster;
1313

1414
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\VarDumper\Caster\MemcachedCaster;
1516
use Symfony\Component\VarDumper\Test\VarDumperTestTrait;
1617

1718
class MemcachedCasterTest extends TestCase
@@ -25,49 +26,24 @@ public function testCastMemcachedWithDefaultOptions()
2526
}
2627

2728
$var = new \Memcached();
28-
29-
$expectedServerHost1 = '127.0.0.1';
30-
$expectedServerPort1 = 11211;
31-
$expectedConnectionType1 = 'TCP';
32-
33-
$expectedServerHost2 = '127.0.0.2';
34-
$expectedServerPort2 = 11211;
35-
$expectedConnectionType2 = 'TCP';
36-
37-
$var->addServer($expectedServerHost1, $expectedServerPort1);
38-
$var->addServer($expectedServerHost2, $expectedServerPort2);
39-
40-
$expectedOption11 = $var->getOption(\Memcached::OPT_SOCKET_SEND_SIZE);
41-
$expectedOption12 = $var->getOption(\Memcached::OPT_SOCKET_RECV_SIZE);
42-
$expectedOption13 = $var->getOption(\Memcached::OPT_CONNECT_TIMEOUT);
43-
$expectedOption14 = $var->getOption(\Memcached::OPT_RETRY_TIMEOUT);
44-
$expectedOption17 = $var->getOption(\Memcached::OPT_POLL_TIMEOUT);
45-
$expectedOption18 = $var->getOption(\Memcached::OPT_CACHE_LOOKUPS);
46-
$expectedOption19 = $var->getOption(\Memcached::OPT_SERVER_FAILURE_LIMIT);
29+
$var->addServer('127.0.0.1', 11211);
30+
$var->addServer('127.0.0.2', 11212);
4731

4832
$expected = <<<EOTXT
4933
Memcached {
5034
servers: array:2 [
5135
0 => array:3 [
52-
"host" => "$expectedServerHost1"
53-
"port" => $expectedServerPort1
54-
"type" => "$expectedConnectionType1"
36+
"host" => "127.0.0.1"
37+
"port" => 11211
38+
"type" => "TCP"
5539
]
5640
1 => array:3 [
57-
"host" => "$expectedServerHost2"
58-
"port" => $expectedServerPort2
59-
"type" => "$expectedConnectionType2"
41+
"host" => "127.0.0.2"
42+
"port" => 11212
43+
"type" => "TCP"
6044
]
6145
]
62-
options: {
63-
OPT_SOCKET_SEND_SIZE: $expectedOption11
64-
OPT_SOCKET_RECV_SIZE: $expectedOption12
65-
OPT_CONNECT_TIMEOUT: $expectedOption13
66-
OPT_RETRY_TIMEOUT: $expectedOption14
67-
OPT_POLL_TIMEOUT: $expectedOption17
68-
OPT_CACHE_LOOKUPS: $expectedOption18
69-
OPT_SERVER_FAILURE_LIMIT: $expectedOption19
70-
}
46+
options: {}
7147
}
7248
EOTXT;
7349
$this->assertDumpEquals($expected, $var);
@@ -80,97 +56,90 @@ public function testCastMemcachedWithCustomOptions()
8056
}
8157

8258
$var = new \Memcached();
59+
$var->addServer('127.0.0.1', 11211);
60+
$var->addServer('127.0.0.2', 11212);
8361

84-
$expectedServerHost1 = '127.0.0.1';
85-
$expectedServerPort1 = 11211;
86-
$expectedConnectionType1 = 'TCP';
87-
88-
$expectedServerHost2 = '127.0.0.2';
89-
$expectedServerPort2 = 11211;
90-
$expectedConnectionType2 = 'TCP';
91-
92-
$var->addServer($expectedServerHost1, $expectedServerPort1);
93-
$var->addServer($expectedServerHost2, $expectedServerPort2);
94-
95-
$var->setOptions(
96-
array(
97-
\Memcached::OPT_COMPRESSION => false,
98-
//\Memcached::OPT_SERIALIZER => \Memcached::SERIALIZER_IGBINARY, // throws Memcached::setOptions(): invalid serializer provided
99-
\Memcached::OPT_PREFIX_KEY => 'prefix',
100-
\Memcached::OPT_HASH => \Memcached::HASH_MD5,
101-
\Memcached::OPT_DISTRIBUTION => \Memcached::DISTRIBUTION_CONSISTENT,
102-
\Memcached::OPT_LIBKETAMA_COMPATIBLE => true,
103-
\Memcached::OPT_BUFFER_WRITES => true,
104-
\Memcached::OPT_BINARY_PROTOCOL => true,
105-
\Memcached::OPT_NO_BLOCK => true,
106-
\Memcached::OPT_TCP_NODELAY => true,
107-
//\Memcached::OPT_SOCKET_SEND_SIZE => 100, // varies by platform/kernel
108-
//\Memcached::OPT_SOCKET_RECV_SIZE => 100, // varies by platform/kernel
109-
\Memcached::OPT_CONNECT_TIMEOUT => 100,
110-
\Memcached::OPT_RETRY_TIMEOUT => 100,
111-
\Memcached::OPT_SEND_TIMEOUT => 100,
112-
\Memcached::OPT_RECV_TIMEOUT => 100,
113-
\Memcached::OPT_POLL_TIMEOUT => 100,
114-
//\Memcached::OPT_CACHE_LOOKUPS => true, // option deprecated
115-
\Memcached::OPT_SERVER_FAILURE_LIMIT => 1,
116-
)
117-
);
62+
$var->setOptions($this->getCustomOptions());
63+
64+
$expectedOptions = $this->getExpectedOptions($var);
11865

119-
$expectedOption1 = $var->getOption(\Memcached::OPT_COMPRESSION) ? 'true' : 'false';
120-
$expectedOption3 = $var->getOption(\Memcached::OPT_PREFIX_KEY);
121-
$expectedOption4 = $var->getOption(\Memcached::OPT_HASH);
122-
$expectedOption5 = $var->getOption(\Memcached::OPT_DISTRIBUTION);
123-
$expectedOption6 = $var->getOption(\Memcached::OPT_LIBKETAMA_COMPATIBLE);
124-
$expectedOption7 = $var->getOption(\Memcached::OPT_BUFFER_WRITES);
125-
$expectedOption8 = $var->getOption(\Memcached::OPT_BINARY_PROTOCOL);
126-
$expectedOption9 = $var->getOption(\Memcached::OPT_NO_BLOCK);
127-
$expectedOption10 = $var->getOption(\Memcached::OPT_TCP_NODELAY);
128-
$expectedOption11 = $var->getOption(\Memcached::OPT_SOCKET_SEND_SIZE);
129-
$expectedOption12 = $var->getOption(\Memcached::OPT_SOCKET_RECV_SIZE);
130-
$expectedOption13 = $var->getOption(\Memcached::OPT_CONNECT_TIMEOUT);
131-
$expectedOption14 = $var->getOption(\Memcached::OPT_RETRY_TIMEOUT);
132-
$expectedOption15 = $var->getOption(\Memcached::OPT_SEND_TIMEOUT);
133-
$expectedOption16 = $var->getOption(\Memcached::OPT_RECV_TIMEOUT);
134-
$expectedOption17 = $var->getOption(\Memcached::OPT_POLL_TIMEOUT);
135-
$expectedOption18 = $var->getOption(\Memcached::OPT_CACHE_LOOKUPS);
136-
$expectedOption19 = $var->getOption(\Memcached::OPT_SERVER_FAILURE_LIMIT);
66+
$expectedOptionsAsString = implode(PHP_EOL, $expectedOptions);
13767

13868
$expected = <<<EOTXT
13969
Memcached {
14070
servers: array:2 [
14171
0 => array:3 [
142-
"host" => "$expectedServerHost1"
143-
"port" => $expectedServerPort1
144-
"type" => "$expectedConnectionType1"
72+
"host" => "127.0.0.1"
73+
"port" => 11211
74+
"type" => "TCP"
14575
]
14676
1 => array:3 [
147-
"host" => "$expectedServerHost2"
148-
"port" => $expectedServerPort2
149-
"type" => "$expectedConnectionType2"
77+
"host" => "127.0.0.2"
78+
"port" => 11212
79+
"type" => "TCP"
15080
]
15181
]
15282
options: {
153-
OPT_COMPRESSION: $expectedOption1
154-
OPT_PREFIX_KEY: "$expectedOption3"
155-
OPT_HASH: $expectedOption4
156-
OPT_DISTRIBUTION: $expectedOption5
157-
OPT_LIBKETAMA_COMPATIBLE: $expectedOption6
158-
OPT_BUFFER_WRITES: $expectedOption7
159-
OPT_BINARY_PROTOCOL: $expectedOption8
160-
OPT_NO_BLOCK: $expectedOption9
161-
OPT_TCP_NODELAY: $expectedOption10
162-
OPT_SOCKET_SEND_SIZE: $expectedOption11
163-
OPT_SOCKET_RECV_SIZE: $expectedOption12
164-
OPT_CONNECT_TIMEOUT: $expectedOption13
165-
OPT_RETRY_TIMEOUT: $expectedOption14
166-
OPT_SEND_TIMEOUT: $expectedOption15
167-
OPT_RECV_TIMEOUT: $expectedOption16
168-
OPT_POLL_TIMEOUT: $expectedOption17
169-
OPT_CACHE_LOOKUPS: $expectedOption18
170-
OPT_SERVER_FAILURE_LIMIT: $expectedOption19
83+
$expectedOptionsAsString
17184
}
17285
}
17386
EOTXT;
87+
17488
$this->assertDumpEquals($expected, $var);
17589
}
90+
91+
private function getCustomOptions()
92+
{
93+
$optionsToIgnore = array(
94+
\Memcached::OPT_SERIALIZER, // trying to set this option to something else then default throws Memcached::setOptions(): invalid serializer provided
95+
\Memcached::OPT_CACHE_LOOKUPS, // option is deprecated
96+
\Memcached::OPT_VERIFY_KEY, // trying to set this option throws Memcached::setOption(): error setting memcached option: INVALID ARGUMENTS
97+
);
98+
99+
$optionConstants = MemcachedCaster::getMemcachedOptionConstants();
100+
$defaultOptions = MemcachedCaster::discoverDefaultMemcachedOptions();
101+
$customOptions = array();
102+
103+
foreach ($optionConstants as $optionConstantKey => $optionConstantValue) {
104+
if (\in_array($optionConstantValue, $optionsToIgnore, true)) {
105+
continue;
106+
}
107+
108+
$defaultOptionValue = $defaultOptions[$optionConstantKey];
109+
110+
if (\is_bool($defaultOptionValue)) {
111+
$customOptions[$optionConstants[$optionConstantKey]] = !$defaultOptionValue;
112+
}
113+
114+
if (\is_string($defaultOptionValue)) {
115+
$customOptions[$optionConstants[$optionConstantKey]] = 'custom';
116+
}
117+
118+
if (\is_int($defaultOptionValue)) {
119+
$customOptions[$optionConstants[$optionConstantKey]] = $defaultOptionValue + 1;
120+
}
121+
}
122+
123+
return $customOptions;
124+
}
125+
126+
private function getExpectedOptions(\Memcached $memcached)
127+
{
128+
$expectedOptions = array();
129+
$nonDefaultOptions = MemcachedCaster::getMemcachedNonDefaultValueOptions($memcached);
130+
131+
foreach ($nonDefaultOptions as $key => $value) {
132+
if (\is_string($value)) {
133+
$value = '"'.$value.'"';
134+
}
135+
136+
if (\is_bool($value)) {
137+
$value = $value ? 'true' : 'false';
138+
}
139+
140+
$expectedOptions[] = ' '.$key.': '.$value;
141+
}
142+
143+
return $expectedOptions;
144+
}
176145
}

0 commit comments

Comments
 (0)