AbstractConnection.php 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  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\Connection;
  11. use InvalidArgumentException;
  12. use Predis\ClientException;
  13. use Predis\CommunicationException;
  14. use Predis\NotSupportedException;
  15. use Predis\Command\CommandInterface;
  16. use Predis\Protocol\ProtocolException;
  17. /**
  18. * Base class with the common logic used by connection classes to communicate
  19. * with Redis.
  20. *
  21. * @author Daniele Alessandri <suppakilla@gmail.com>
  22. */
  23. abstract class AbstractConnection implements SingleConnectionInterface
  24. {
  25. private $resource;
  26. private $cachedId;
  27. protected $parameters;
  28. protected $initCommands = array();
  29. /**
  30. * @param ParametersInterface $parameters Initialization parameters for the connection.
  31. */
  32. public function __construct(ParametersInterface $parameters)
  33. {
  34. $this->parameters = $this->assertParameters($parameters);
  35. }
  36. /**
  37. * Disconnects from the server and destroys the underlying resource when
  38. * PHP's garbage collector kicks in.
  39. */
  40. public function __destruct()
  41. {
  42. $this->disconnect();
  43. }
  44. /**
  45. * Checks some of the parameters used to initialize the connection.
  46. *
  47. * @param ParametersInterface $parameters Initialization parameters for the connection.
  48. */
  49. protected function assertParameters(ParametersInterface $parameters)
  50. {
  51. $scheme = $parameters->scheme;
  52. if ($scheme !== 'tcp' && $scheme !== 'unix') {
  53. throw new InvalidArgumentException("Invalid scheme: $scheme");
  54. }
  55. if ($scheme === 'unix' && !isset($parameters->path)) {
  56. throw new InvalidArgumentException('Missing UNIX domain socket path');
  57. }
  58. return $parameters;
  59. }
  60. /**
  61. * Creates the underlying resource used to communicate with Redis.
  62. *
  63. * @return mixed
  64. */
  65. protected abstract function createResource();
  66. /**
  67. * {@inheritdoc}
  68. */
  69. public function isConnected()
  70. {
  71. return isset($this->resource);
  72. }
  73. /**
  74. * {@inheritdoc}
  75. */
  76. public function connect()
  77. {
  78. if ($this->isConnected()) {
  79. throw new ClientException('Connection already estabilished');
  80. }
  81. $this->resource = $this->createResource();
  82. }
  83. /**
  84. * {@inheritdoc}
  85. */
  86. public function disconnect()
  87. {
  88. unset($this->resource);
  89. }
  90. /**
  91. * {@inheritdoc}
  92. */
  93. public function addConnectCommand(CommandInterface $command)
  94. {
  95. $this->initCommands[] = $command;
  96. }
  97. /**
  98. * {@inheritdoc}
  99. */
  100. public function executeCommand(CommandInterface $command)
  101. {
  102. $this->writeRequest($command);
  103. return $this->readResponse($command);
  104. }
  105. /**
  106. * {@inheritdoc}
  107. */
  108. public function readResponse(CommandInterface $command)
  109. {
  110. return $this->read();
  111. }
  112. /**
  113. * Helper method to handle connection errors.
  114. *
  115. * @param string $message Error message.
  116. * @param int $code Error code.
  117. */
  118. protected function onConnectionError($message, $code = null)
  119. {
  120. CommunicationException::handle(
  121. new ConnectionException(
  122. $this, "$message [{$this->parameters->scheme}://{$this->getIdentifier()}]", $code
  123. )
  124. );
  125. }
  126. /**
  127. * Helper method to handle protocol errors.
  128. *
  129. * @param string $message Error message.
  130. */
  131. protected function onProtocolError($message)
  132. {
  133. CommunicationException::handle(
  134. new ProtocolException(
  135. $this, "$message [{$this->parameters->scheme}://{$this->getIdentifier()}]"
  136. )
  137. );
  138. }
  139. /**
  140. * {@inheritdoc}
  141. */
  142. public function getResource()
  143. {
  144. if (isset($this->resource)) {
  145. return $this->resource;
  146. }
  147. $this->connect();
  148. return $this->resource;
  149. }
  150. /**
  151. * {@inheritdoc}
  152. */
  153. public function getParameters()
  154. {
  155. return $this->parameters;
  156. }
  157. /**
  158. * Gets an identifier for the connection.
  159. *
  160. * @return string
  161. */
  162. protected function getIdentifier()
  163. {
  164. if ($this->parameters->scheme === 'unix') {
  165. return $this->parameters->path;
  166. }
  167. return "{$this->parameters->host}:{$this->parameters->port}";
  168. }
  169. /**
  170. * {@inheritdoc}
  171. */
  172. public function __toString()
  173. {
  174. if (!isset($this->cachedId)) {
  175. $this->cachedId = $this->getIdentifier();
  176. }
  177. return $this->cachedId;
  178. }
  179. /**
  180. * {@inheritdoc}
  181. */
  182. public function __sleep()
  183. {
  184. return array('parameters', 'initCommands');
  185. }
  186. }