Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 80 additions & 1 deletion miniRedis.php
Original file line number Diff line number Diff line change
@@ -1 +1,80 @@
<?phpclass miniRedis { private $count; private $socket; public function __construct($hostname = 'localhost', $port = 6379) { $this->count = 0; $this->socket = fsockopen($hostname, $port); } public function write($s) { fwrite($this->socket, $s . "\r\n"); return $this->count++; } public function read() { $s = ''; $r = array(); $bulk = false; $multibulk = 0; while ($this->count) { $s .= fread($this->socket, 1024); while (strpos($s, "\r\n") !== false) { $a = substr($s, 0, strpos($s, "\r\n")); $s = substr($s, strpos($s, "\r\n") + 2); if ($bulk === false) switch ($a[0]) { case '+': $r[] = substr($a, 1); $this->count--; break; case '-': $r[] = substr($a, 1); $this->count--; break; case ':': $r[] = intval(substr($a, 1)); $this->count--; break; case '$': $bulk = intval(substr($a, 1)); if ($bulk != -1) $a = false; break; case '*': $multibulk = intval(substr($a, 1)); $t = array(); break; } if ($bulk !== false && $a !== false) { if ($bulk == -1) $a = null; $bulk = false; if ($multibulk) { $t[] = $a; $multibulk--; if (!$multibulk) { $r[] = $t; $this->count--; } } else { $r[] = $a; $this->count--; } } } } return $r; }}
<?php
class miniRedis {
private $count;
private $socket;
private $buffer = '';

public function __construct($hostname = 'localhost', $port = 6379) {
$this->count = 0;
$this->socket = fsockopen($hostname, $port);
}

public function write($s) {
fwrite($this->socket, $s . "\r\n");
return $this->count++;
}

public function read() {
if ($this->count > 0) {
$this->count--;
return $this->parseResponse();
}
return null;
}

private function parseResponse() {
$line = $this->readLine();
if ($line === false) return null;

$type = $line[0];
$payload = substr($line, 1);

switch ($type) {
case '+': // Simple String
return $payload;
case '-': // Error
return $payload; // Return error message
case ':': // Integer
return intval($payload);
case '$': // Bulk String
$len = intval($payload);
if ($len == -1) return null;
$data = $this->readBytes($len);
$this->readBytes(2); // Discard CRLF
return $data;
case '*': // Array
$count = intval($payload);
if ($count == -1) return null;
$data = array();
for ($i = 0; $i < $count; $i++) {
$data[] = $this->parseResponse();
}
return $data;
default:
// Handle unknown types or protocol errors
return null;
}
}

private function readLine() {
while (($pos = strpos($this->buffer, "\r\n")) === false) {
$chunk = fread($this->socket, 1024);
if ($chunk === false || $chunk === '') return false;
$this->buffer .= $chunk;
}
$line = substr($this->buffer, 0, $pos);
$this->buffer = substr($this->buffer, $pos + 2);
return $line;
}

private function readBytes($len) {
while (strlen($this->buffer) < $len) {
$chunk = fread($this->socket, 1024);
if ($chunk === false || $chunk === '') return false;
$this->buffer .= $chunk;
}
$data = substr($this->buffer, 0, $len);
$this->buffer = substr($this->buffer, $len);
return $data;
}
}