Last active
December 29, 2015 10:09
-
-
Save zacscott/7655076 to your computer and use it in GitHub Desktop.
Utility to handle file uploads.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace \net\zeddev\util; | |
/** An error while uploading. */ | |
class UploaderException extends \Exception { } | |
/** An invalid type for uploaded file. */ | |
class UploaderTypeException extends UploaderException { } | |
/** An oversize uploaded file. */ | |
class UploaderSizeException extends UploaderException { } | |
/** | |
* Utility to handle file uploads. Can be used like so: | |
* | |
* $uploader = new Uploader(); | |
* $uploader->upload('formNameOfFile', 'path/to/store'); | |
* | |
* **NOTE:** This file is released as a stand-alone utility. The original | |
* file and the associated unit test can be found on GitHub Gist - | |
* [here](https://gist.github.com/zscott92/7655076). | |
* | |
* @author Zachary Scott <zscott.dev@gmail.com> | |
*/ | |
class Uploader { | |
public $imageMimes; | |
public $pdfMimes; | |
/** The name of the uploaded file. */ | |
public $name; | |
/** The size of the uploaded file. */ | |
public $size; | |
/** The mime type of the uploaded file. */ | |
public $type; | |
/** The location of the uploaded file. */ | |
public $path; | |
public function __construct() { | |
// valid mime types for images | |
$this->imageMimes = array( | |
"image/gif", | |
"image/jpeg", | |
"image/jpg", | |
"image/pjpeg", | |
"image/x-png", | |
"image/png" | |
); | |
// valid mime type for PDF files | |
$this->pdfMimes = array( | |
"application/pdf", | |
"application/x-pdf" | |
); | |
} | |
// returns english error message for file error code | |
private function uploadError($code) { | |
assert($code != null && is_int($code)); | |
switch ($code) { | |
case UPLOAD_ERR_INI_SIZE: | |
case UPLOAD_ERR_FORM_SIZE: | |
return "File is too large to upload!"; | |
case UPLOAD_ERR_PARTIAL: | |
return "File upload was interrupted!"; | |
case UPLOAD_ERR_NO_FILE: | |
return "No file was uploaded, please try again."; | |
case UPLOAD_ERR_NO_TMP_DIR: | |
case UPLOAD_ERR_CANT_WRITE: | |
case UPLOAD_ERR_EXTENSION: | |
return "File upload failed due to an internal error, please try again later."; | |
default: | |
return "Unknown file error!"; | |
} | |
} | |
/** | |
* Handles checking and moving an uploaded file. | |
* | |
* @param $name The form name of the uploaded file. | |
* @param $dir The directory in which to place the file. | |
* @param $size The maximum size of the uploaded file. `null` for no limit. | |
* @param $mimes The valid mime types to accept. `null` for none. | |
*/ | |
public function upload($name, $dir, $overwrite = false, $size = null, $mimes = null) { | |
// check exists | |
if (!isset($_FILES[$name])) | |
throw new UploaderException("No file was uploaded, please try again"); | |
// check for upload error | |
if ($_FILES[$name]["error"] > 0) { | |
throw new UploaderException( | |
$this->uploadError($_FILES[$name]["error"]) | |
); | |
} | |
// check the size of the file | |
if ($size != null) { | |
if ($_FILES[$name]['size'] > $size) | |
throw new UploaderSizeException($_FILES[$name]['size']); | |
} | |
// check mime type of uploaded file | |
if ($mimes != null) { | |
$type = $_FILES[$name]['type']; | |
if (!in_array($type, $mimes)) | |
throw new UploaderTypeException($type); | |
} | |
$file = $_FILES[$name]['name']; | |
$filePath = $dir.'/'.$_FILES[$name]['name']; | |
// check file does not already exist | |
if (!$overwrite && file_exists($filePath)) | |
throw new UploaderException("File $file already exists."); | |
// relocate | |
move_uploaded_file( | |
$_FILES[$name]['tmp_name'], | |
$filePath | |
); | |
// set file info | |
$this->name = $_FILES[$name]['name']; | |
$this->size = $_FILES[$name]['size']; | |
$this->type = $_FILES[$name]['type']; | |
$this->path = $filePath; | |
} | |
} | |
?> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// NOTE requires class.ErrorList.php vvvv | |
require_once dirname(__FILE__).'/code/class.ErrorList.php'; | |
require_once dirname(__FILE__).'/code/class.Uploader.php'; | |
$err = new ErrorList(); | |
$uploader = new Uploader(); | |
// handle form | |
if (isset($_POST['form'])) { | |
try { | |
// handle file upload | |
$uploader->upload( | |
'file', | |
'upload', | |
isset($_POST['overwrite']), | |
204800, // 200KB limit | |
$uploader->imageMimes | |
); | |
// upload successful at this point | |
$msg = "File uploaded successfully."; | |
} catch (UploaderTypeException $ex) { | |
$err->err("File must be an image"); | |
} catch (UploaderSizeException $ex) { | |
$err->err("File must be 100KB or less"); | |
} catch (UploaderException $ex) { | |
$err->err($ex->getMessage()); | |
} | |
} | |
?> | |
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" | |
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> | |
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> | |
<head> | |
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" /> | |
<title>Uploader Test</title> | |
<style type="text/css"> | |
.error { | |
color: red; | |
} | |
.msg { | |
color: green; | |
} | |
</style> | |
</head> | |
<body> | |
<h1>Uploader Test</h1> | |
<?php | |
// report any errors | |
echo $err->geterr(); | |
// display message | |
if (isset($msg)) | |
echo "<p class='msg'>$msg</p>"; | |
// output uploaded file info | |
if (isset($_POST['form'])) { | |
echo "<p class='msg'>"; | |
echo "Name: ". $uploader->name ."<br />"; | |
echo "Size: ". sprintf('%.2f KiB', $uploader->size / 1024) ."<br />"; | |
echo "Type: ". $uploader->type ."<br />"; | |
echo "Path: ". $uploader->path ."<br />"; | |
echo "</p>\n"; | |
} | |
?> | |
<form action="upload.php" | |
method="post" | |
enctype="multipart/form-data"> | |
<input type="file" name="file"/> | |
<input type="checkbox" name="overwrite" value="1"/>Overwrite?<br /> | |
<input type="submit" name="form" value="Upload"/> | |
</form> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment