ConnectionBase.php 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. <?php
  2. /*
  3. * This file is part of the Predis package.
  4. *
  5. * (c) Daniele Alessandri <suppakilla@gmail.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Predis\Network;
  11. use Predis\Helpers;
  12. use Predis\IReplyObject;
  13. use Predis\IConnectionParameters;
  14. use Predis\ClientException;
  15. use Predis\NotSupportedException;
  16. use Predis\Commands\ICommand;
  17. use Predis\Protocol\ProtocolException;
  18. /**
  19. * Base class with the common logic used by connection classes to communicate with Redis.
  20. *
  21. * @author Daniele Alessandri <suppakilla@gmail.com>
  22. */
  23. abstract class ConnectionBase implements IConnectionSingle
  24. {
  25. private $resource;
  26. private $cachedId;
  27. protected $parameters;
  28. protected $initCmds;
  29. /**
  30. * @param IConnectionParameters $parameters Parameters used to initialize the connection.
  31. */
  32. public function __construct(IConnectionParameters $parameters)
  33. {
  34. $this->initCmds = array();
  35. $this->parameters = $this->checkParameters($parameters);
  36. $this->initializeProtocol($parameters);
  37. }
  38. /**
  39. * Disconnects from the server and destroys the underlying resource when
  40. * PHP's garbage collector kicks in.
  41. */
  42. public function __destruct()
  43. {
  44. $this->disconnect();
  45. }
  46. /**
  47. * Checks some of the parameters used to initialize the connection.
  48. *
  49. * @param IConnectionParameters $parameters Parameters used to initialize the connection.
  50. */
  51. protected function checkParameters(IConnectionParameters $parameters)
  52. {
  53. switch ($parameters->scheme) {
  54. case 'unix':
  55. if (!isset($parameters->path)) {
  56. throw new \InvalidArgumentException('Missing UNIX domain socket path');
  57. }
  58. case 'tcp':
  59. return $parameters;
  60. default:
  61. throw new \InvalidArgumentException("Invalid scheme: {$parameters->scheme}");
  62. }
  63. }
  64. /**
  65. * Initializes some common configurations of the underlying protocol processor
  66. * from the connection parameters.
  67. *
  68. * @param IConnectionParameters $parameters Parameters used to initialize the connection.
  69. */
  70. protected function initializeProtocol(IConnectionParameters $parameters)
  71. {
  72. // NOOP
  73. }
  74. /**
  75. * Creates the underlying resource used to communicate with Redis.
  76. *
  77. * @return mixed
  78. */
  79. protected abstract function createResource();
  80. /**
  81. * {@inheritdoc}
  82. */
  83. public function isConnected()
  84. {
  85. return isset($this->resource);
  86. }
  87. /**
  88. * {@inheritdoc}
  89. */
  90. public function connect()
  91. {
  92. if ($this->isConnected()) {
  93. throw new ClientException('Connection already estabilished');
  94. }
  95. $this->resource = $this->createResource();
  96. }
  97. /**
  98. * {@inheritdoc}
  99. */
  100. public function disconnect()
  101. {
  102. unset($this->resource);
  103. }
  104. /**
  105. * {@inheritdoc}
  106. */
  107. public function pushInitCommand(ICommand $command)
  108. {
  109. $this->initCmds[] = $command;
  110. }
  111. /**
  112. * {@inheritdoc}
  113. */
  114. public function executeCommand(ICommand $command)
  115. {
  116. $this->writeCommand($command);
  117. return $this->readResponse($command);
  118. }
  119. /**
  120. * {@inheritdoc}
  121. */
  122. public function readResponse(ICommand $command)
  123. {
  124. $reply = $this->read();
  125. if ($reply instanceof IReplyObject) {
  126. return $reply;
  127. }
  128. return $command->parseResponse($reply);
  129. }
  130. /**
  131. * Helper method to handle connection errors.
  132. *
  133. * @param string $message Error message.
  134. * @param int $code Error code.
  135. */
  136. protected function onConnectionError($message, $code = null)
  137. {
  138. Helpers::onCommunicationException(new ConnectionException($this, $message, $code));
  139. }
  140. /**
  141. * Helper method to handle protocol errors.
  142. *
  143. * @param string $message Error message.
  144. */
  145. protected function onProtocolError($message)
  146. {
  147. Helpers::onCommunicationException(new ProtocolException($this, $message));
  148. }
  149. /**
  150. * Helper method to handle not supported connection parameters.
  151. *
  152. * @param string $option Name of the option.
  153. * @param IConnectionParameters $parameters Parameters used to initialize the connection.
  154. */
  155. protected function onInvalidOption($option, $parameters = null)
  156. {
  157. $message = "Invalid option: $option";
  158. if (isset($parameters)) {
  159. $message .= " [$parameters]";
  160. }
  161. throw new NotSupportedException($message);
  162. }
  163. /**
  164. * {@inheritdoc}
  165. */
  166. public function getResource()
  167. {
  168. if (isset($this->resource)) {
  169. return $this->resource;
  170. }
  171. $this->connect();
  172. return $this->resource;
  173. }
  174. /**
  175. * {@inheritdoc}
  176. */
  177. public function getParameters()
  178. {
  179. return $this->parameters;
  180. }
  181. /**
  182. * Gets an identifier for the connection.
  183. *
  184. * @return string
  185. */
  186. protected function getIdentifier()
  187. {
  188. if ($this->parameters->scheme === 'unix') {
  189. return $this->parameters->path;
  190. }
  191. return "{$this->parameters->host}:{$this->parameters->port}";
  192. }
  193. /**
  194. * {@inheritdoc}
  195. */
  196. public function __toString()
  197. {
  198. if (!isset($this->cachedId)) {
  199. $this->cachedId = $this->getIdentifier();
  200. }
  201. return $this->cachedId;
  202. }
  203. /**
  204. * {@inheritdoc}
  205. */
  206. public function __sleep()
  207. {
  208. return array('parameters', 'initCmds');
  209. }
  210. }