diff --git a/src/Component/Collection.php b/src/Component/Collection.php index 2bcadf3..2b74de2 100644 --- a/src/Component/Collection.php +++ b/src/Component/Collection.php @@ -70,7 +70,7 @@ public function get(string $name, $default = null) public function add($name, $value) { if (isset($this[$name])) { - return null; + return $this; } $this[$name] = $value; @@ -85,7 +85,9 @@ public function add($name, $value) */ public function set($name, $value) { - return $this[$name] = $value; + $this[$name] = $value; + + return $this; } /** diff --git a/src/Cookies.php b/src/Cookies.php index 2dab59d..6c24501 100644 --- a/src/Cookies.php +++ b/src/Cookies.php @@ -64,6 +64,20 @@ public function set($name, $value): self return $this; } + /** + * @param string $name + * @param mixed $value + * @return self + */ + public function add($name, $value): self + { + if (!\is_array($value)) { + $value = ['value' => (string)$value]; + } + + return parent::add($name, \array_replace($this->defaults, $value)); + } + /** * Convert to `Set-Cookie` headers * @return string[] @@ -72,7 +86,7 @@ public function toHeaders(): array { $headers = []; foreach ($this as $name => $properties) { - $headers[] = $this->toHeader($name, $properties); + $headers[] = $this->toHeaderLine($name, $properties); } return $headers; @@ -84,7 +98,7 @@ public function toHeaders(): array * @param array $properties Cookie properties * @return string */ - protected function toHeader(string $name, array $properties): string + protected function toHeaderLine(string $name, array $properties): string { $result = \urlencode($name) . '=' . \urlencode($properties['value']); diff --git a/src/Headers.php b/src/Headers.php index fffde45..0e12e98 100644 --- a/src/Headers.php +++ b/src/Headers.php @@ -113,7 +113,10 @@ public function add($key, $value) return $this; } - return parent::add($this->normalizeKey($key), $value); + return parent::add($this->normalizeKey($key), [ + 'value' => (array)$value, + 'originalKey' => $key + ]); } /** @@ -136,12 +139,12 @@ public function remove($key) * @param string $key * @return bool|string */ - public function normalizeKey($key) + public function normalizeKey(string $key) { - $key = str_replace('_', '-', strtolower($key)); + $key = \str_replace('_', '-', \strtolower($key)); - if (strpos($key, 'Http-') === 0) { - $key = substr($key, 5); + if (\strpos($key, 'Http-') === 0) { + $key = \substr($key, 5); } return $key; @@ -157,12 +160,12 @@ public function getAcceptLanguages(): array $ls = []; if ($value = $this->getLine('Accept-Language')) { - if (strpos($value, ';')) { - list($value,) = explode(';', $value, 2); + if (\strpos($value, ';')) { + list($value,) = \explode(';', $value, 2); } - $value = str_replace(' ', '', $value); - $ls = explode(',', $value); + $value = \str_replace(' ', '', $value); + $ls = \explode(',', $value); } return $ls; @@ -178,32 +181,32 @@ public function getAcceptEncodes(): array $ens = []; if ($value = $this->getLine('Accept-Encoding')) { - if (strpos($value, ';')) { - list($value,) = explode(';', $value, 2); + if (\strpos($value, ';')) { + list($value,) = \explode(';', $value, 2); } - $value = str_replace(' ', '', $value); - $ens = explode(',', $value); + $value = \str_replace(' ', '', $value); + $ens = \explode(',', $value); } return $ens; } /** - * @param bool $toString - * @return array + * @param bool $join to String + * @return array|string */ - public function toHeaderLines(bool $toString = false): array + public function toHeaderLines(bool $join = false) { $output = []; foreach ($this as $name => $info) { - $name = ucwords($name, '-'); - $value = implode(',', $info['value']); + $name = \ucwords($name, '-'); + $value = \implode(',', $info['value']); $output[] = "$name: $value\r\n"; } - return $toString ? implode('', $output) : $output; + return $join ? \implode('', $output) : $output; } /** @@ -214,8 +217,8 @@ public function getLines(): array $output = []; foreach ($this as $name => $info) { - $name = ucwords($name, '-'); - $output[$name] = implode(',', $info['value']); + $name = \ucwords($name, '-'); + $output[$name] = \implode(',', $info['value']); } return $output; diff --git a/src/Response.php b/src/Response.php index 7054fd5..df9f4cf 100644 --- a/src/Response.php +++ b/src/Response.php @@ -365,6 +365,10 @@ public function getStatusCode(): int */ public function getReasonPhrase(): string { + if ($this->reasonPhrase === null && ($code = $this->status)) { + $this->reasonPhrase = self::$messages[$code] ?? ''; + } + return $this->reasonPhrase; } diff --git a/src/ServerRequest.php b/src/ServerRequest.php index 56efd44..2310817 100644 --- a/src/ServerRequest.php +++ b/src/ServerRequest.php @@ -667,7 +667,7 @@ public function withAttribute($name, $value) * @param array $attributes * @return ServerRequest */ - public function withAttributes(array $attributes): ServerRequest + public function withAttributes(array $attributes): self { $clone = clone $this; $clone->attributes = new Collection($attributes); diff --git a/src/Traits/RequestTrait.php b/src/Traits/RequestTrait.php index 8034a14..dc2d51d 100644 --- a/src/Traits/RequestTrait.php +++ b/src/Traits/RequestTrait.php @@ -174,7 +174,12 @@ public function isMethod($method): bool return $this->getMethod() === strtoupper($method); } - public function withMethod($method): RequestTrait + /** + * @param $method + * @return RequestTrait + * @throws \InvalidArgumentException + */ + public function withMethod($method): self { $method = (string)$this->filterMethod($method); diff --git a/test/ResponseTest.php b/test/ResponseTest.php new file mode 100644 index 0000000..c3c16af --- /dev/null +++ b/test/ResponseTest.php @@ -0,0 +1,29 @@ +assertInstanceOf(ResponseInterface::class, $res); + $this->assertSame(200, $res->getStatusCode()); + $this->assertInternalType('string', $res->getReasonPhrase()); + } +} diff --git a/test/ServerRequestTest.php b/test/ServerRequestTest.php new file mode 100644 index 0000000..7cad8fe --- /dev/null +++ b/test/ServerRequestTest.php @@ -0,0 +1,32 @@ +assertInstanceOf(RequestInterface::class, $req); + + $req = $req->withAttribute('key', 'value'); + + $this->assertInstanceOf(RequestInterface::class, $req); + $this->assertSame('value', $req->getAttribute('key')); + } +}