namespace GuzzleHttp\Psr7;
use InvalidArgumentException;
use Psr\Http\Message\StreamInterface;
use Psr\Http\Message\UploadedFileInterface;
class UploadedFile implements UploadedFileInterface
private static $errors = [
private $clientMediaType;
* @var StreamInterface|null
* @param StreamInterface|string|resource $streamOrFile
* @param int $errorStatus
* @param string|null $clientFilename
* @param string|null $clientMediaType
public function __construct(
$this->setError($errorStatus);
$this->setClientFilename($clientFilename);
$this->setClientMediaType($clientMediaType);
$this->setStreamOrFile($streamOrFile);
* Depending on the value set file or stream variable
* @param mixed $streamOrFile
* @throws InvalidArgumentException
private function setStreamOrFile($streamOrFile)
if (is_string($streamOrFile)) {
$this->file = $streamOrFile;
} elseif (is_resource($streamOrFile)) {
$this->stream = new Stream($streamOrFile);
} elseif ($streamOrFile instanceof StreamInterface) {
$this->stream = $streamOrFile;
throw new InvalidArgumentException(
'Invalid stream or file provided for UploadedFile'
* @throws InvalidArgumentException
private function setError($error)
if (false === is_int($error)) {
throw new InvalidArgumentException(
'Upload file error status must be an integer'
if (false === in_array($error, UploadedFile::$errors)) {
throw new InvalidArgumentException(
'Invalid error status for UploadedFile'
* @throws InvalidArgumentException
private function setSize($size)
if (false === is_int($size)) {
throw new InvalidArgumentException(
'Upload file size must be an integer'
private function isStringOrNull($param)
return in_array(gettype($param), ['string', 'NULL']);
private function isStringNotEmpty($param)
return is_string($param) && false === empty($param);
* @param string|null $clientFilename
* @throws InvalidArgumentException
private function setClientFilename($clientFilename)
if (false === $this->isStringOrNull($clientFilename)) {
throw new InvalidArgumentException(
'Upload file client filename must be a string or null'
$this->clientFilename = $clientFilename;
* @param string|null $clientMediaType
* @throws InvalidArgumentException
private function setClientMediaType($clientMediaType)
if (false === $this->isStringOrNull($clientMediaType)) {
throw new InvalidArgumentException(
'Upload file client media type must be a string or null'
$this->clientMediaType = $clientMediaType;
* Return true if there is no upload error
return $this->error === UPLOAD_ERR_OK;
public function isMoved()
* @throws RuntimeException if is moved or not ok
private function validateActive()
if (false === $this->isOk()) {
throw new RuntimeException('Cannot retrieve stream due to upload error');
throw new RuntimeException('Cannot retrieve stream after it has already been moved');
* @throws RuntimeException if the upload was not successful.
public function getStream()
if ($this->stream instanceof StreamInterface) {
return new LazyOpenStream($this->file, 'r+');
* @see http://php.net/is_uploaded_file
* @see http://php.net/move_uploaded_file
* @param string $targetPath Path to which to move the uploaded file.
* @throws RuntimeException if the upload was not successful.
* @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.
public function moveTo($targetPath)
if (false === $this->isStringNotEmpty($targetPath)) {
throw new InvalidArgumentException(
'Invalid path provided for move operation; must be a non-empty string'
$this->moved = php_sapi_name() == 'cli'
? rename($this->file, $targetPath)
: move_uploaded_file($this->file, $targetPath);
new LazyOpenStream($targetPath, 'w')
if (false === $this->moved) {
throw new RuntimeException(
sprintf('Uploaded file could not be moved to %s', $targetPath)
* @return int|null The file size in bytes or null if unknown.
public function getSize()
* @see http://php.net/manual/en/features.file-upload.errors.php
* @return int One of PHP's UPLOAD_ERR_XXX constants.
public function getError()
* @return string|null The filename sent by the client or null if none
public function getClientFilename()
return $this->clientFilename;
public function getClientMediaType()
return $this->clientMediaType;