ResponseReader.php 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  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\Protocol\Text;
  11. use Predis\CommunicationException;
  12. use Predis\Connection\ComposableConnectionInterface;
  13. use Predis\Protocol\ProtocolException;
  14. use Predis\Protocol\ResponseReaderInterface;
  15. /**
  16. * Response reader for the standard Redis wire protocol.
  17. *
  18. * @link http://redis.io/topics/protocol
  19. * @author Daniele Alessandri <suppakilla@gmail.com>
  20. */
  21. class ResponseReader implements ResponseReaderInterface
  22. {
  23. protected $handlers;
  24. /**
  25. *
  26. */
  27. public function __construct()
  28. {
  29. $this->handlers = $this->getDefaultHandlers();
  30. }
  31. /**
  32. * Returns the default handlers for the supported type of responses.
  33. *
  34. * @return array
  35. */
  36. protected function getDefaultHandlers()
  37. {
  38. return array(
  39. '+' => new Handler\StatusResponse(),
  40. '-' => new Handler\ErrorResponse(),
  41. ':' => new Handler\IntegerResponse(),
  42. '$' => new Handler\BulkResponse(),
  43. '*' => new Handler\MultiBulkResponse(),
  44. );
  45. }
  46. /**
  47. * Sets a response handler for a certain prefix that identifies a type of
  48. * response that can be returned by Redis.
  49. *
  50. * @param string $prefix Identifier of the type of response.
  51. * @param Handler\ResponseHandlerInterface $handler Response handler.
  52. */
  53. public function setHandler($prefix, Handler\ResponseHandlerInterface $handler)
  54. {
  55. $this->handlers[$prefix] = $handler;
  56. }
  57. /**
  58. * Returns the response handler associated to a certain type of response.
  59. *
  60. * @param string $prefix Identifier of the type of response.
  61. * @return ResponseHandlerInterface
  62. */
  63. public function getHandler($prefix)
  64. {
  65. if (isset($this->handlers[$prefix])) {
  66. return $this->handlers[$prefix];
  67. }
  68. }
  69. /**
  70. * {@inheritdoc}
  71. */
  72. public function read(ComposableConnectionInterface $connection)
  73. {
  74. $header = $connection->readLine();
  75. if ($header === '') {
  76. $this->onProtocolError($connection, 'Unexpected empty header');
  77. }
  78. $prefix = $header[0];
  79. if (!isset($this->handlers[$prefix])) {
  80. $this->onProtocolError($connection, "Unknown prefix: '$prefix'");
  81. }
  82. $handler = $this->handlers[$prefix];
  83. return $handler->handle($connection, substr($header, 1));
  84. }
  85. /**
  86. * Handles protocol errors generated while reading responses from the
  87. * connection.
  88. *
  89. * @param ComposableConnectionInterface $connection Connection to Redis that generated the error.
  90. * @param string $message Error message.
  91. */
  92. protected function onProtocolError(ComposableConnectionInterface $connection, $message)
  93. {
  94. CommunicationException::handle(
  95. new ProtocolException($connection, $message)
  96. );
  97. }
  98. }