|
@@ -268,89 +268,104 @@ abstract class MultiBulkCommand extends Command {
|
|
|
|
|
|
/* ------------------------------------------------------------------------- */
|
|
|
|
|
|
-class Response {
|
|
|
- const NEWLINE = "\r\n";
|
|
|
- const OK = 'OK';
|
|
|
- const ERROR = 'ERR';
|
|
|
- const QUEUED = 'QUEUED';
|
|
|
- const NULL = 'nil';
|
|
|
+interface IResponseHandler {
|
|
|
+ function handle($socket, $prefix, $payload);
|
|
|
+}
|
|
|
|
|
|
- private static $_prefixHandlers;
|
|
|
+class ResponseStatusHandler implements IResponseHandler {
|
|
|
+ public function handle($socket, $prefix, $status) {
|
|
|
+ if ($status === Response::OK) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ else if ($status === Response::QUEUED) {
|
|
|
+ return new ResponseQueued();
|
|
|
+ }
|
|
|
+ return $status;
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
- private static function initializePrefixHandlers() {
|
|
|
- return array(
|
|
|
- // status
|
|
|
- '+' => function($socket, $prefix, $status) {
|
|
|
- if ($status === Response::OK) {
|
|
|
- return true;
|
|
|
- }
|
|
|
- else if ($status === Response::QUEUED) {
|
|
|
- return new ResponseQueued();
|
|
|
- }
|
|
|
- return $status;
|
|
|
- },
|
|
|
-
|
|
|
- // error
|
|
|
- '-' => function($socket, $prefix, $errorMessage) {
|
|
|
- throw new ServerException(substr($errorMessage, 4));
|
|
|
- },
|
|
|
-
|
|
|
- // bulk
|
|
|
- '$' => function($socket, $prefix, $dataLength) {
|
|
|
- if (!is_numeric($dataLength)) {
|
|
|
- throw new ClientException("Cannot parse '$dataLength' as data length");
|
|
|
- }
|
|
|
+class ResponseErrorHandler implements IResponseHandler {
|
|
|
+ public function handle($socket, $prefix, $errorMessage) {
|
|
|
+ throw new ServerException(substr($errorMessage, 4));
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
- if ($dataLength > 0) {
|
|
|
- $value = stream_get_contents($socket, $dataLength);
|
|
|
- if ($value === false) {
|
|
|
- throw new ClientException('An error has occurred while reading from the network stream');
|
|
|
- }
|
|
|
- fread($socket, 2);
|
|
|
- return $value;
|
|
|
- }
|
|
|
- else if ($dataLength == 0) {
|
|
|
- fread($socket, 2);
|
|
|
- return '';
|
|
|
- }
|
|
|
+class ResponseBulkHandler implements IResponseHandler {
|
|
|
+ public function handle($socket, $prefix, $dataLength) {
|
|
|
+ if (!is_numeric($dataLength)) {
|
|
|
+ throw new ClientException("Cannot parse '$dataLength' as data length");
|
|
|
+ }
|
|
|
|
|
|
- return null;
|
|
|
- },
|
|
|
+ if ($dataLength > 0) {
|
|
|
+ $value = stream_get_contents($socket, $dataLength);
|
|
|
+ if ($value === false) {
|
|
|
+ throw new ClientException('An error has occurred while reading from the network stream');
|
|
|
+ }
|
|
|
+ fread($socket, 2);
|
|
|
+ return $value;
|
|
|
+ }
|
|
|
+ else if ($dataLength == 0) {
|
|
|
+ fread($socket, 2);
|
|
|
+ return '';
|
|
|
+ }
|
|
|
|
|
|
- // multibulk
|
|
|
- '*' => function($socket, $prefix, $rawLength) {
|
|
|
- if (!is_numeric($rawLength)) {
|
|
|
- throw new ClientException("Cannot parse '$rawLength' as data length");
|
|
|
- }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
- $listLength = (int) $rawLength;
|
|
|
- if ($listLength === -1) {
|
|
|
- return null;
|
|
|
- }
|
|
|
+class ResponseMultiBulkHandler implements IResponseHandler {
|
|
|
+ public function handle($socket, $prefix, $rawLength) {
|
|
|
+ if (!is_numeric($rawLength)) {
|
|
|
+ throw new ClientException("Cannot parse '$rawLength' as data length");
|
|
|
+ }
|
|
|
|
|
|
- $list = array();
|
|
|
+ $listLength = (int) $rawLength;
|
|
|
+ if ($listLength === -1) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
|
|
|
- if ($listLength > 0) {
|
|
|
- for ($i = 0; $i < $listLength; $i++) {
|
|
|
- $list[] = Response::read($socket);
|
|
|
- }
|
|
|
- }
|
|
|
+ $list = array();
|
|
|
|
|
|
- return $list;
|
|
|
- },
|
|
|
+ if ($listLength > 0) {
|
|
|
+ for ($i = 0; $i < $listLength; $i++) {
|
|
|
+ $list[] = Response::read($socket);
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- // integer
|
|
|
- ':' => function($socket, $prefix, $number) {
|
|
|
- if (is_numeric($number)) {
|
|
|
- return (int) $number;
|
|
|
- }
|
|
|
- else {
|
|
|
- if ($number !== Response::NULL) {
|
|
|
- throw new ClientException("Cannot parse '$number' as numeric response");
|
|
|
- }
|
|
|
- return null;
|
|
|
- }
|
|
|
+ return $list;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+class ResponseIntegerHandler implements IResponseHandler {
|
|
|
+ public function handle($socket, $prefix, $number) {
|
|
|
+ if (is_numeric($number)) {
|
|
|
+ return (int) $number;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ if ($number !== Response::NULL) {
|
|
|
+ throw new ClientException("Cannot parse '$number' as numeric response");
|
|
|
}
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+class Response {
|
|
|
+ const NEWLINE = "\r\n";
|
|
|
+ const OK = 'OK';
|
|
|
+ const ERROR = 'ERR';
|
|
|
+ const QUEUED = 'QUEUED';
|
|
|
+ const NULL = 'nil';
|
|
|
+
|
|
|
+ private static $_prefixHandlers;
|
|
|
+
|
|
|
+ private static function initializePrefixHandlers() {
|
|
|
+ return array(
|
|
|
+ '+' => new ResponseStatusHandler(),
|
|
|
+ '-' => new ResponseErrorHandler(),
|
|
|
+ ':' => new ResponseIntegerHandler(),
|
|
|
+ '$' => new ResponseBulkHandler(),
|
|
|
+ '*' => new ResponseMultiBulkHandler()
|
|
|
);
|
|
|
}
|
|
|
|
|
@@ -371,7 +386,7 @@ class Response {
|
|
|
}
|
|
|
|
|
|
$handler = self::$_prefixHandlers[$prefix];
|
|
|
- return $handler($socket, $prefix, $payload);
|
|
|
+ return $handler->handle($socket, $prefix, $payload);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -383,6 +398,8 @@ class ResponseQueued {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+/* ------------------------------------------------------------------------- */
|
|
|
+
|
|
|
class CommandPipeline {
|
|
|
private $_redisClient, $_pipelineBuffer, $_returnValues, $_running;
|
|
|
|