3v4l.org

run code in 150+ php & hhvm versions
Bugs & Features
<?php class HTTPGETResponse { const RECVPROGRESS_NODATA = 0; const RECVPROGRESS_HEAD = 1; const RECVPROGRESS_BODY = 2; const RECVPROGRESS_TRAIL = 3; const RECVPROGRESS_END = 4; const ERR_NOERROR = 0; const ERR_MALFORMEDRESPONSE = 1; const ERR_INVALIDCONTENTLENGTH = 2; private $buffer = ''; private $unchunk = FALSE; public $error = 0; public $recvProgress = 0; public $httpVersion; public $responseCode; public $responseMsg; public $body = ''; public $contentLength = 0; public $headers = array(); public function create() { return new $this(); } private function setErrorState($state) { $this->error = $state; $this->buffer = NULL; } private function getBufferLine() { $line = FALSE; if (FALSE !== $pos = strpos($this->buffer, "\r\n")) { $line = substr($this->buffer, 0, $pos); $this->buffer = substr($this->buffer, $pos + 2); } return $line; } private function processBufferLine($line) { if ($this->recvProgress === self::RECVPROGRESS_NODATA) { $this->processResponseLine($line); } else { $this->processHeaderLine($line); } } private function processResponseLine($line) { if (!preg_match('#^HTTP/(1\.[01]) (\d{3}) (.+)$#i', rtrim($line), $matches)) { $this->setErrorState(self::ERR_MALFORMEDRESPONSE); } else { $this->httpVersion = $matches[1]; $this->responseCode = (int) $matches[2]; $this->responseMsg = $matches[3]; $this->recvProgress = self::RECVPROGRESS_HEAD; } } private function processHeaderLine($line) { if ($line === "\r\n") { if ($this->recvProgress === self::RECVPROGRESS_HEAD) { $this->unchunk = isset($this->headers['transfer-encoding']) && strtolower($this->headers['transfer-encoding']) === 'chunked'; $this->recvProgress = self::RECVPROGRESS_BODY; } } else { list($key, $val) = explode(':', $line, 2); $key = strtolower(trim($key)); $val = trim($val); if (!isset($this->headers[$key])) { $this->headers[$key] = array(); } $this->headers[$key][] = $val; } } private function processBodyData() { if ($this->unchunk) { $this->processBodyChunks(); } else { $this->body .= $this->buffer; $this->buffer = ''; } } private function processBodyChunks() { if (strlen($this->buffer)) { if (!preg_match('/^([\da-f]+)\r\n/i', $this->buffer, $matches)) { $chunkLen = hexdec($matches[1]); if ($chunkLen > 0) { $headerLen = strlen($matches[1]) + 2; if (strlen($this->buffer) >= $chunkLen + $headerLen + 2) { $this->body .= substr($this->buffer, $headerLen, $chunkLen); $this->buffer = substr($this->buffer, $chunkLen + $headerLen + 2); } } else { $this->buffer = (string) substr($this->buffer, 5); $this->recvProgress = self::RECVPROGRESS_TRAIL; } } else { $this->setErrorState(self::ERR_MALFORMEDRESPONSE); } } } public function progress($str) { if (!$this->error) { $this->buffer .= $str; while ($this->recvProgress !== self::RECVPROGRESS_BODY && FALSE !== $line = $this->getBufferLine()) { $this->processBufferLine($line); if ($this->error) { break; } } if ($this->recvProgress === self::RECVPROGRESS_BODY) { $this->processBodyData(); } } return $this->error; } public function close() { $this->recvProgress = self::RECVPROGRESS_END; $this->contentLength = strlen($this->body); if (!$this->error && isset($this->headers['content-length'])) { if ($this->contentLength !== (int) $this->headers['content-length']) { $this->setErrorState(self::ERR_INVALIDCONTENTLENGTH); } } } } $factory = new HTTPGETResponse(); $response = $factory->create(); $chunks = array("HTTP/1.1 200 OK\r\nServer: yo-mama\r\n\r\nbooooooobs"); foreach($chunks as $chunk) { $response->progress($chunk); if ($response->error) { echo "Error!\n"; break; } } print_r($response);
Output for 5.3.0 - 7.1.0
Notice: Undefined offset: 1 in /in/bUmAc on line 74 HTTPGETResponse Object ( [buffer:HTTPGETResponse:private] => booooooobs [unchunk:HTTPGETResponse:private] => [error] => 0 [recvProgress] => 1 [httpVersion] => 1.1 [responseCode] => 200 [responseMsg] => OK [body] => [contentLength] => 0 [headers] => Array ( [server] => Array ( [0] => yo-mama ) [] => Array ( [0] => ) ) )
Output for 5.0.0 - 5.2.17
Notice: Undefined offset: 1 in /in/bUmAc on line 74 HTTPGETResponse Object ( [buffer:private] => booooooobs [unchunk:private] => [error] => 0 [recvProgress] => 1 [httpVersion] => 1.1 [responseCode] => 200 [responseMsg] => OK [body] => [contentLength] => 0 [headers] => Array ( [server] => Array ( [0] => yo-mama ) [] => Array ( [0] => ) ) )
Output for 4.4.2 - 4.4.9
Parse error: syntax error, unexpected T_CONST, expecting T_OLD_FUNCTION or T_FUNCTION or T_VAR or '}' in /in/bUmAc on line 5
Process exited with code 255.
Output for 4.3.0 - 4.3.1, 4.3.5 - 4.4.1
Parse error: parse error, unexpected T_CONST, expecting T_OLD_FUNCTION or T_FUNCTION or T_VAR or '}' in /in/bUmAc on line 5
Process exited with code 255.
Output for 4.3.2 - 4.3.4
Parse error: parse error, expecting `T_OLD_FUNCTION' or `T_FUNCTION' or `T_VAR' or `'}'' in /in/bUmAc on line 5
Process exited with code 255.