ConnectionParameters.php 4.9 KB

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