AbstractConnection.php 4.7 KB

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