Add type hints to Stream, UploadedFile, and Uri

This commit is contained in:
PJ Dietz 2020-08-09 13:29:05 -04:00
parent 7ade042b4b
commit c339512f01
5 changed files with 51 additions and 35 deletions

View File

@ -17,6 +17,7 @@
<DocblockTypeContradiction>
<errorLevel type="suppress">
<file name="src/Message/ServerRequest.php" />
<file name="src/Message/Uri.php" />
</errorLevel>
</DocblockTypeContradiction>
<MissingClosureParamType>

View File

@ -166,6 +166,7 @@ class Stream implements StreamInterface
* PHP $whence values for `fseek()`. SEEK_SET: Set position equal to
* offset bytes SEEK_CUR: Set position to current location plus offset
* SEEK_END: Set position to end-of-stream plus offset.
* @return void
* @throws \RuntimeException on failure.
*/
public function seek($offset, $whence = SEEK_SET)
@ -191,6 +192,7 @@ class Stream implements StreamInterface
*
* @see seek()
* @link http://www.php.net/manual/en/function.fseek.php
* @return void
* @throws \RuntimeException on failure.
*/
public function rewind()

View File

@ -10,12 +10,19 @@ use Psr\Http\Message\UploadedFileInterface;
*/
class UploadedFile implements UploadedFileInterface
{
/** @var string */
private $clientFilename;
/** @var string */
private $clientMediaType;
/** @var int */
private $error;
/** @var bool */
private $moved = false;
/** @var int */
private $size;
/** @var StreamInterface */
private $stream;
/** @var string|null */
private $tmpName;
/**
@ -57,10 +64,11 @@ class UploadedFile implements UploadedFileInterface
$this->size = $size;
if (file_exists($tmpName)) {
$this->stream = new Stream(fopen($tmpName, 'r'));
$this->tmpName = $tmpName;
$this->stream = new Stream(fopen($tmpName, "r"));
} else {
$this->stream = new NullStream();
$this->tmpName = null;
}
}
@ -82,8 +90,11 @@ class UploadedFile implements UploadedFileInterface
*/
public function getStream()
{
if ($this->tmpName === null) {
throw new \RuntimeException("Unable to read uploaded file.");
}
if ($this->moved) {
throw new \RuntimeException("File has already been moved");
throw new \RuntimeException("File has already been moved.");
}
if (php_sapi_name() !== "cli" && !is_uploaded_file($this->tmpName)) {
throw new \RuntimeException("File is not an uploaded file.");
@ -105,6 +116,7 @@ class UploadedFile implements UploadedFileInterface
* @see http://php.net/is_uploaded_file
* @see http://php.net/move_uploaded_file
* @param string $path Path to which to move the uploaded file.
* @return void
* @throws \InvalidArgumentException if the $path specified is invalid.
* @throws \RuntimeException on any error during the move operation, or on
* the second or subsequent call to the method.

View File

@ -40,36 +40,36 @@ class Uri implements UriInterface
/**
* @param string $uri A string representation of a URI.
*/
public function __construct($uri = "")
public function __construct(string $uri = '')
{
if (is_string($uri) && $uri !== "") {
$parsed = parse_url($uri);
if ($parsed !== false) {
if (isset($parsed["scheme"])) {
$this->scheme = $parsed["scheme"];
}
if (isset($parsed["host"])) {
$this->host = strtolower($parsed["host"]);
}
if (isset($parsed["port"])) {
$this->port = $parsed["port"];
}
if (isset($parsed["user"])) {
$this->user = $parsed["user"];
}
if (isset($parsed["pass"])) {
$this->password = $parsed["pass"];
}
if (isset($parsed["path"])) {
$this->path = $parsed["path"];
}
if (isset($parsed["query"])) {
$this->query = $parsed["query"];
}
if (isset($parsed["fragment"])) {
$this->fragment = $parsed["fragment"];
}
}
$parsed = parse_url($uri);
if (!$parsed) {
return;
}
if (isset($parsed['scheme'])) {
$this->scheme = $parsed['scheme'];
}
if (isset($parsed['host'])) {
$this->host = strtolower($parsed['host']);
}
if (isset($parsed['port'])) {
$this->port = $parsed['port'];
}
if (isset($parsed['user'])) {
$this->user = $parsed['user'];
}
if (isset($parsed['pass'])) {
$this->password = $parsed['pass'];
}
if (isset($parsed['path'])) {
$this->path = $parsed['path'];
}
if (isset($parsed['query'])) {
$this->query = $parsed['query'];
}
if (isset($parsed['fragment'])) {
$this->fragment = $parsed['fragment'];
}
}
@ -538,7 +538,7 @@ class Uri implements UriInterface
$reserved = ':/?#[]@!$&\'()*+,;=';
$reserved = preg_quote($reserved);
$pattern = '~(?:%(?![a-fA-F0-9]{2}))|(?:[^%a-zA-Z0-9\-\.\_\~' . $reserved . ']{1})~';
$callback = function ($matches) {
$callback = function (array $matches): string {
return urlencode($matches[0]);
};
return preg_replace_callback($pattern, $callback, $subject);

View File

@ -40,7 +40,7 @@ class UploadedFileTest extends TestCase
public function testGetStreamReturnsStreamInterface()
{
$file = new UploadedFile("", "", 0, "", 0);
$file = new UploadedFile("", "", 0, $this->tmpName, 0);
$this->assertInstanceOf(StreamInterface::class, $file->getStream());
}
@ -53,10 +53,11 @@ class UploadedFileTest extends TestCase
$this->assertEquals($content, (string) $stream);
}
public function testGetStreamReturnsEmptyStreamForNoFile()
public function testGetStreamThrowsRuntimeExceptionForNoFile()
{
$file = new UploadedFile("", "", 0, "", 0);
$this->assertTrue($file->getStream()->eof());
$this->expectException(RuntimeException::class);
$file->getStream();
}
public function testGetStreamThrowsExceptionAfterMoveTo()