ResponseReader.php 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  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 the handler for the specified prefix identifying the response type.
  48. *
  49. * @param string $prefix Identifier of the type of response.
  50. * @param Handler\ResponseHandlerInterface $handler Response handler.
  51. */
  52. public function setHandler($prefix, Handler\ResponseHandlerInterface $handler)
  53. {
  54. $this->handlers[$prefix] = $handler;
  55. }
  56. /**
  57. * Returns the response handler associated to a certain type of response.
  58. *
  59. * @param string $prefix Identifier of the type of response.
  60. * @return ResponseHandlerInterface
  61. */
  62. public function getHandler($prefix)
  63. {
  64. if (isset($this->handlers[$prefix])) {
  65. return $this->handlers[$prefix];
  66. }
  67. }
  68. /**
  69. * {@inheritdoc}
  70. */
  71. public function read(ComposableConnectionInterface $connection)
  72. {
  73. $header = $connection->readLine();
  74. if ($header === '') {
  75. $this->onProtocolError($connection, 'Unexpected empty header');
  76. }
  77. $prefix = $header[0];
  78. if (!isset($this->handlers[$prefix])) {
  79. $this->onProtocolError($connection, "Unknown prefix: '$prefix'");
  80. }
  81. $handler = $this->handlers[$prefix];
  82. return $handler->handle($connection, substr($header, 1));
  83. }
  84. /**
  85. * Handles protocol errors generated while reading responses from the
  86. * connection.
  87. *
  88. * @param ComposableConnectionInterface $connection Connection to Redis that generated the error.
  89. * @param string $message Error message.
  90. */
  91. protected function onProtocolError(ComposableConnectionInterface $connection, $message)
  92. {
  93. CommunicationException::handle(
  94. new ProtocolException($connection, $message)
  95. );
  96. }
  97. }