/library/Zend/Cache/Storage/Adapter/MemcachedOptions.php

https://github.com/christeredvartsen/zf2 · PHP · 300 lines · 155 code · 35 blank · 110 comment · 22 complexity · 66af79995640e37d74dfa75544e6984e MD5 · raw file

  1. <?php
  2. /**
  3. * Zend Framework (http://framework.zend.com/)
  4. *
  5. * @link http://github.com/zendframework/zf2 for the canonical source repository
  6. * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
  7. * @license http://framework.zend.com/license/new-bsd New BSD License
  8. * @package Zend_Cache
  9. */
  10. namespace Zend\Cache\Storage\Adapter;
  11. use Memcached as MemcachedResource;
  12. use Zend\Cache\Exception;
  13. /**
  14. * These are options specific to the APC adapter
  15. *
  16. * @category Zend
  17. * @package Zend_Cache
  18. * @subpackage Storage
  19. */
  20. class MemcachedOptions extends AdapterOptions
  21. {
  22. /**
  23. * A memcached resource to share
  24. *
  25. * @var null|MemcachedResource
  26. */
  27. protected $memcachedResource;
  28. /**
  29. * List of memcached servers to add on initialize
  30. *
  31. * @var string
  32. */
  33. protected $servers = array(
  34. array(
  35. 'host' => '127.0.0.1',
  36. 'port' => 11211,
  37. 'weight' => 0,
  38. ),
  39. );
  40. /**
  41. * List of Libmemcached options to set on initialize
  42. *
  43. * @var array
  44. */
  45. protected $libOptions = array();
  46. /**
  47. * Set namespace.
  48. *
  49. * The option Memcached::OPT_PREFIX_KEY will be used as the namespace.
  50. * It can't be longer than 128 characters.
  51. *
  52. * @see AdapterOptions::setNamespace()
  53. * @see MemcachedOptions::setPrefixKey()
  54. */
  55. public function setNamespace($namespace)
  56. {
  57. $namespace = (string) $namespace;
  58. if (128 < strlen($namespace)) {
  59. throw new Exception\InvalidArgumentException(sprintf(
  60. '%s expects a prefix key of no longer than 128 characters',
  61. __METHOD__
  62. ));
  63. }
  64. return parent::setNamespace($namespace);
  65. }
  66. /**
  67. * A memcached resource to share
  68. *
  69. * @param null|MemcachedResource $memcachedResource
  70. * @return MemcachedOptions
  71. */
  72. public function setMemcachedResource(MemcachedResource $memcachedResource = null)
  73. {
  74. if ($this->memcachedResource !== $memcachedResource) {
  75. $this->triggerOptionEvent('memcached_resource', $memcachedResource);
  76. $this->memcachedResource = $memcachedResource;
  77. }
  78. return $this;
  79. }
  80. /**
  81. * Get memcached resource to share
  82. *
  83. * @return null|MemcachedResource
  84. */
  85. public function getMemcachedResource()
  86. {
  87. return $this->memcachedResource;
  88. }
  89. /**
  90. * Add a server to the list
  91. *
  92. * @param string $host
  93. * @param int $port
  94. * @param int $weight
  95. * @return MemcachedOptions
  96. */
  97. public function addServer($host, $port = 11211, $weight = 0)
  98. {
  99. $new = array(
  100. 'host' => $host,
  101. 'port' => $port,
  102. 'weight' => $weight
  103. );
  104. foreach ($this->servers as $server) {
  105. $diff = array_diff($new, $server);
  106. if (empty($diff)) {
  107. // Done -- server is already present
  108. return $this;
  109. }
  110. }
  111. $this->servers[] = $new;
  112. return $this;
  113. }
  114. /**
  115. * Set a list of memcached servers to add on initialize
  116. *
  117. * @param string|array $servers list of servers
  118. * @return MemcachedOptions
  119. * @throws Exception\InvalidArgumentException
  120. */
  121. public function setServers($servers)
  122. {
  123. if (!is_array($servers)) {
  124. return $this->setServers(explode(',', $servers));
  125. }
  126. $this->servers = array();
  127. foreach ($servers as $server) {
  128. // default values
  129. $host = null;
  130. $port = 11211;
  131. $weight = 1;
  132. if (!is_array($server) && !is_string($server)) {
  133. throw new Exception\InvalidArgumentException('Invalid server specification provided; must be an array or string');
  134. }
  135. // parse a single server from an array
  136. if (is_array($server)) {
  137. if (!isset($server[0]) && !isset($server['host'])) {
  138. throw new Exception\InvalidArgumentException("Invalid list of servers given");
  139. }
  140. // array(array(<host>[, <port>[, <weight>]])[, ...])
  141. if (isset($server[0])) {
  142. $host = (string) $server[0];
  143. $port = isset($server[1]) ? (int) $server[1] : $port;
  144. $weight = isset($server[2]) ? (int) $server[2] : $weight;
  145. }
  146. // array(array('host' => <host>[, 'port' => <port>[, 'weight' => <weight>]])[, ...])
  147. if (!isset($server[0]) && isset($server['host'])) {
  148. $host = (string) $server['host'];
  149. $port = isset($server['port']) ? (int) $server['port'] : $port;
  150. $weight = isset($server['weight']) ? (int) $server['weight'] : $weight;
  151. }
  152. }
  153. // parse a single server from a string
  154. if (!is_array($server)) {
  155. $server = trim($server);
  156. if (strpos($server, '://') === false) {
  157. $server = 'tcp://' . $server;
  158. }
  159. $server = parse_url($server);
  160. if (!$server) {
  161. throw new Exception\InvalidArgumentException("Invalid list of servers given");
  162. }
  163. $host = $server['host'];
  164. $port = isset($server['port']) ? (int) $server['port'] : $port;
  165. if (isset($server['query'])) {
  166. $query = null;
  167. parse_str($server['query'], $query);
  168. if (isset($query['weight'])) {
  169. $weight = (int) $query['weight'];
  170. }
  171. }
  172. }
  173. if (!$host) {
  174. throw new Exception\InvalidArgumentException('The list of servers must contain a host value.');
  175. }
  176. $this->addServer($host, $port, $weight);
  177. }
  178. return $this;
  179. }
  180. /**
  181. * Get Servers
  182. *
  183. * @return array
  184. */
  185. public function getServers()
  186. {
  187. return $this->servers;
  188. }
  189. /**
  190. * Set libmemcached options
  191. *
  192. * @param array $libOptions
  193. * @return MemcachedOptions
  194. * @link http://php.net/manual/memcached.constants.php
  195. */
  196. public function setLibOptions(array $libOptions)
  197. {
  198. $normalizedOptions = array();
  199. foreach ($libOptions as $key => $value) {
  200. $this->normalizeLibOptionKey($key);
  201. $normalizedOptions[$key] = $value;
  202. }
  203. $this->triggerOptionEvent('lib_options', $normalizedOptions);
  204. $this->libOptions = array_diff_key($this->libOptions, $normalizedOptions) + $normalizedOptions;
  205. return $this;
  206. }
  207. /**
  208. * Set libmemcached option
  209. *
  210. * @param string|int $key
  211. * @param mixed $value
  212. * @return MemcachedOptions
  213. * @link http://php.net/manual/memcached.constants.php
  214. */
  215. public function setLibOption($key, $value)
  216. {
  217. $this->normalizeLibOptionKey($key);
  218. $this->triggerOptionEvent('lib_options', array($key, $value));
  219. $this->libOptions[$key] = $value;
  220. return $this;
  221. }
  222. /**
  223. * Get libmemcached options
  224. *
  225. * @return array
  226. * @link http://php.net/manual/memcached.constants.php
  227. */
  228. public function getLibOptions()
  229. {
  230. return $this->libOptions;
  231. }
  232. /**
  233. * Get libmemcached option
  234. *
  235. * @param string|int $key
  236. * @return mixed
  237. * @link http://php.net/manual/memcached.constants.php
  238. */
  239. public function getLibOption($key)
  240. {
  241. $this->normalizeLibOptionKey($key);
  242. if (isset($this->libOptions[$key])) {
  243. return $this->libOptions[$key];
  244. }
  245. return null;
  246. }
  247. /**
  248. * Normalize libmemcached option name into it's constant value
  249. *
  250. * @param string|int $key
  251. * @throws Exception\InvalidArgumentException
  252. */
  253. protected function normalizeLibOptionKey(& $key)
  254. {
  255. if (is_string($key)) {
  256. $const = 'Memcached::OPT_' . str_replace(array(' ', '-'), '_', strtoupper($key));
  257. if (!defined($const)) {
  258. throw new Exception\InvalidArgumentException("Unknown libmemcached option '{$key}' ({$const})");
  259. }
  260. $key = constant($const);
  261. } else {
  262. $key = (int) $key;
  263. }
  264. }
  265. }