ConnectionParameters.php 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. <?php
  2. namespace Predis;
  3. use Predis\Options\IOption;
  4. use Predis\Options\Option;
  5. use Predis\Options\CustomOption;
  6. class ConnectionParameters {
  7. private $_parameters;
  8. private $_userDefined;
  9. private static $_sharedOptions;
  10. public function __construct($parameters = array()) {
  11. $extractor = is_array($parameters) ? 'filter' : 'parseURI';
  12. $this->_parameters = $this->$extractor($parameters);
  13. $this->_userDefined = array_fill_keys(array_keys($this->_parameters), true);
  14. }
  15. private static function getSharedOptions() {
  16. if (isset(self::$_sharedOptions)) {
  17. return self::$_sharedOptions;
  18. }
  19. $optEmpty = new Option();
  20. $optBoolFalse = new CustomOption(array(
  21. 'validate' => function($value) { return (bool) $value; },
  22. 'default' => function() { return false; },
  23. ));
  24. $optBoolTrue = new CustomOption(array(
  25. 'validate' => function($value) { return (bool) $value; },
  26. 'default' => function() { return true; },
  27. ));
  28. self::$_sharedOptions = array(
  29. 'scheme' => new CustomOption(array(
  30. 'default' => function() { return 'tcp'; },
  31. )),
  32. 'host' => new CustomOption(array(
  33. 'default' => function() { return '127.0.0.1'; },
  34. )),
  35. 'port' => new CustomOption(array(
  36. 'validate' => function($value) { return (int) $value; },
  37. 'default' => function() { return 6379; },
  38. )),
  39. 'path' => $optEmpty,
  40. 'database' => $optEmpty,
  41. 'password' => $optEmpty,
  42. 'connection_async' => $optBoolFalse,
  43. 'connection_persistent' => $optBoolFalse,
  44. 'connection_timeout' => new CustomOption(array(
  45. 'validate' => function($value) { return (float) $value; },
  46. 'default' => function() { return 5; },
  47. )),
  48. 'read_write_timeout' => new CustomOption(array(
  49. 'validate' => function($value) { return (float) $value; },
  50. )),
  51. 'alias' => $optEmpty,
  52. 'weight' => $optEmpty,
  53. 'iterable_multibulk' => $optBoolFalse,
  54. 'throw_errors' => $optBoolTrue,
  55. );
  56. return self::$_sharedOptions;
  57. }
  58. public static function define($parameter, IOption $handler) {
  59. self::getSharedOptions();
  60. self::$_sharedOptions[$parameter] = $handler;
  61. }
  62. public static function undefine($parameter) {
  63. self::getSharedOptions();
  64. unset(self::$_sharedOptions[$parameter]);
  65. }
  66. protected function parseURI($uri) {
  67. if (!is_string($uri)) {
  68. throw new \InvalidArgumentException('URI must be a string');
  69. }
  70. if (stripos($uri, 'unix') === 0) {
  71. // Hack to support URIs for UNIX sockets with minimal effort.
  72. $uri = str_ireplace('unix:///', 'unix://localhost/', $uri);
  73. }
  74. $parsed = @parse_url($uri);
  75. if ($parsed === false || !isset($parsed['host'])) {
  76. throw new \InvalidArgumentException("Invalid URI: $uri");
  77. }
  78. if (isset($parsed['query'])) {
  79. foreach (explode('&', $parsed['query']) as $kv) {
  80. @list($k, $v) = explode('=', $kv);
  81. $parsed[$k] = $v;
  82. }
  83. unset($parsed['query']);
  84. }
  85. return $this->filter($parsed);
  86. }
  87. protected function filter(Array $parameters) {
  88. $handlers = self::getSharedOptions();
  89. foreach ($parameters as $parameter => $value) {
  90. if (isset($handlers[$parameter])) {
  91. $parameters[$parameter] = $handlers[$parameter]($value);
  92. }
  93. }
  94. return $parameters;
  95. }
  96. public function __get($parameter) {
  97. if (isset($this->_parameters[$parameter])) {
  98. return $this->_parameters[$parameter];
  99. }
  100. if (isset(self::$_sharedOptions[$parameter])) {
  101. $value = self::$_sharedOptions[$parameter]->getDefault();
  102. $this->_parameters[$parameter] = $value;
  103. return $value;
  104. }
  105. return null;
  106. }
  107. public function __isset($parameter) {
  108. return isset($this->_userDefined[$parameter]);
  109. }
  110. public function __toString() {
  111. $str = null;
  112. if ($this->scheme === 'unix') {
  113. $str = "{$this->scheme}://{$this->path}";
  114. }
  115. else {
  116. $str = "{$this->scheme}://{$this->host}:{$this->port}";
  117. }
  118. $query = array();
  119. $reject = array('scheme', 'host', 'port', 'password', 'path');
  120. foreach ($this->_parameters as $k => $v) {
  121. if (in_array($k, $reject) || !isset($this->_userDefined[$k])) {
  122. continue;
  123. }
  124. $query[] = $k . '=' . ($v === false ? '0' : $v);
  125. }
  126. return count($query) > 0 ? ($str . '/?' . implode('&', $query)) : $str;
  127. }
  128. public function toArray() {
  129. return $this->_parameters;
  130. }
  131. }