AbstractConnection.php 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  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(
  120. new ConnectionException(
  121. $this, "$message [{$this->parameters->scheme}://{$this->getIdentifier()}]", $code
  122. )
  123. );
  124. }
  125. /**
  126. * Helper method to handle protocol errors.
  127. *
  128. * @param string $message Error message.
  129. */
  130. protected function onProtocolError($message)
  131. {
  132. CommunicationException::handle(
  133. new ProtocolException(
  134. $this, "$message [{$this->parameters->scheme}://{$this->getIdentifier()}]"
  135. )
  136. );
  137. }
  138. /**
  139. * {@inheritdoc}
  140. */
  141. public function getResource()
  142. {
  143. if (isset($this->resource)) {
  144. return $this->resource;
  145. }
  146. $this->connect();
  147. return $this->resource;
  148. }
  149. /**
  150. * {@inheritdoc}
  151. */
  152. public function getParameters()
  153. {
  154. return $this->parameters;
  155. }
  156. /**
  157. * Gets an identifier for the connection.
  158. *
  159. * @return string
  160. */
  161. protected function getIdentifier()
  162. {
  163. if ($this->parameters->scheme === 'unix') {
  164. return $this->parameters->path;
  165. }
  166. return "{$this->parameters->host}:{$this->parameters->port}";
  167. }
  168. /**
  169. * {@inheritdoc}
  170. */
  171. public function __toString()
  172. {
  173. if (!isset($this->cachedId)) {
  174. $this->cachedId = $this->getIdentifier();
  175. }
  176. return $this->cachedId;
  177. }
  178. /**
  179. * {@inheritdoc}
  180. */
  181. public function __sleep()
  182. {
  183. return array('parameters', 'initCmds');
  184. }
  185. }