AutorÃa | Ultima modificación | Ver Log |
<?php/*** Slim Framework (https://slimframework.com)** @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)*/declare(strict_types=1);namespace Slim;use Psr\Http\Message\ResponseInterface;use function connection_status;use function header;use function headers_sent;use function in_array;use function min;use function sprintf;use function strlen;use function strtolower;use const CONNECTION_NORMAL;class ResponseEmitter{private int $responseChunkSize;public function __construct(int $responseChunkSize = 4096){$this->responseChunkSize = $responseChunkSize;}/*** Send the response the client*/public function emit(ResponseInterface $response): void{$isEmpty = $this->isResponseEmpty($response);if (headers_sent() === false) {$this->emitHeaders($response);// Set the status _after_ the headers, because of PHP's "helpful" behavior with location headers.// See https://github.com/slimphp/Slim/issues/1730$this->emitStatusLine($response);}if (!$isEmpty) {$this->emitBody($response);}}/*** Emit Response Headers*/private function emitHeaders(ResponseInterface $response): void{foreach ($response->getHeaders() as $name => $values) {$first = strtolower($name) !== 'set-cookie';foreach ($values as $value) {$header = sprintf('%s: %s', $name, $value);header($header, $first);$first = false;}}}/*** Emit Status Line*/private function emitStatusLine(ResponseInterface $response): void{$statusLine = sprintf('HTTP/%s %s %s',$response->getProtocolVersion(),$response->getStatusCode(),$response->getReasonPhrase());header($statusLine, true, $response->getStatusCode());}/*** Emit Body*/private function emitBody(ResponseInterface $response): void{$body = $response->getBody();if ($body->isSeekable()) {$body->rewind();}$amountToRead = (int) $response->getHeaderLine('Content-Length');if (!$amountToRead) {$amountToRead = $body->getSize();}if ($amountToRead) {while ($amountToRead > 0 && !$body->eof()) {$length = min($this->responseChunkSize, $amountToRead);$data = $body->read($length);echo $data;$amountToRead -= strlen($data);if (connection_status() !== CONNECTION_NORMAL) {break;}}} else {while (!$body->eof()) {echo $body->read($this->responseChunkSize);if (connection_status() !== CONNECTION_NORMAL) {break;}}}}/*** Asserts response body is empty or status code is 204, 205 or 304*/public function isResponseEmpty(ResponseInterface $response): bool{if (in_array($response->getStatusCode(), [204, 205, 304], true)) {return true;}$stream = $response->getBody();$seekable = $stream->isSeekable();if ($seekable) {$stream->rewind();}return $seekable ? $stream->read(1) === '' : $stream->eof();}}