Handling file uploads - phpgt/Input GitHub Wiki

The library wraps uploaded files in FileUpload objects so we can work with them consistently, regardless of how PHP shaped $_FILES.

Reading one uploaded file

$photo = $input->getFile("photo");

The result can be:

  • null if the field was not submitted
  • FileUpload if the upload succeeded
  • FailedFileUpload if PHP received the field but the upload failed

That means it is worth checking the concrete type before moving the file:

use GT\Input\InputData\Datum\FailedFileUpload;

$photo = $input->getFile("photo");

if($photo instanceof FailedFileUpload) {
	throw new RuntimeException($photo->getErrorMessage());
}

if($photo) {
	$photo->moveTo("data/photos/" . $photo->getOriginalName());
}

Reading multiple uploaded files

For a field such as <input type="file" name="gallery[]" multiple />, use getMultipleFile():

foreach($input->getMultipleFile("gallery") as $name => $file) {
	$file->moveTo("data/gallery/$name");
}

The returned array is keyed by the original client filename.

Inspecting upload metadata

FileUpload provides:

  • getOriginalName()
  • getOriginalExtension()
  • getMimeType()
  • getSize()
  • getRealPath()
  • getFileInfo()
  • getStream()
  • getError()
  • getClientFilename()
  • getClientMediaType()

Example:

$document = $input->getFile("document");

if($document && !$document instanceof FailedFileUpload) {
	printf(
		"%s (%s, %d bytes)",
		$document->getOriginalName(),
		$document->getMimeType(),
		$document->getSize()
	);
}

Moving an uploaded file

Use moveTo() to move the temporary upload into permanent storage:

$photo->moveTo("data/avatar/user-42.jpg");

The method creates the target directory if it does not already exist.

Internally it still uses PHP's upload checks, so it will reject paths that do not refer to a real uploaded file and it will throw an exception if the move fails.

Handling upload failures

FailedFileUpload carries the PHP upload error code and a readable message:

if($file instanceof FailedFileUpload) {
	error_log($file->getErrorMessage());
}

This is useful when the field existed but PHP could not complete the upload because of size limits, missing temporary directories, interrupted uploads, or similar server-side problems.

A note on security

Treat client-provided filenames and MIME types as descriptive, not authoritative.

  • Generate your own storage filenames when possible.
  • Validate file contents if the application depends on a trusted format.
  • Store uploads outside the public document root unless they are intended to be served directly.

If you want the low-level background for why this wrapper exists, see how PHP handles files.