PHP Upload

A PHP class that makes handling uploads and file validation a lot simpler. You can use the chainable methods to set up the upload parameters such as min/max file size, mime types, and file extensions. Once set up, you can simply turn on the ignition().


For a more advanced upload option, this class allows you to add callbacks and loop through the files awaiting upload to perform your own validation and checks.


Tested to work with PHP 5.6 and PHP 7.


GitHub/BitBucket


Installation with composer

You can now install the upload class with composer:

composer require benhall14/phpUpload

Please make sure that you include the composer autoloader and use the correct namespace.

require 'vendor/autoload.php'; use benhall14\phpUpload\Upload as Upload;

API Options


->version()

The version() method will return the class version.

$upload->version();

->submitted()

The submitted() method will return either true or false depending on if the selected input element has been submitted or not.

$upload->submitted();

->setMessages()

You can override the default messages by passing an array of custom messages to the setMessages() method.

$upload->setMessages($custom_messages);

The default messages are:

$messages = [ # When the file element in the class is invalid. 'invalid_file_element' => 'Invalid File Element ID', # When no files have been selected for upload. 'nothing_uploaded' => 'No files have been selected to upload.', # When the destination path is invalid. 'invalid_destination' => 'Invalid Destination Path', # When the upload path could not be created. 'could_not_create_path' => 'The %s doesn\'t exist and could not be created.', # When the file element is missing from the __construct() method. 'file_input_missing' => 'The file id %s is missing from the upload form.', # When the uploaded file(s) don't fit the criteria for the minimum file size. 'too_small' => 'Too small', # When the uploaded file(s) don't fit the criteria for the maximum file size. 'too_large' => 'Too large', # When the uploaded file(s) don't fit the criteria for the allowed mime types. 'invalid_mime' => 'Invalid mime type uploaded (%s). Allowed mime types are: %s.', # When the uploaded file(s) don't fit the criteria for the allowed file extensions. 'invalid_ext' => 'Invalid file type uploaded (%s). Allowed file types are: %s.', # When the uploaded file(s) could not be moved due to a server or permission error. 'upload_move_error' => 'The file could not be uploaded: Permission Error', # When the destination path set does not exist and/or could not be created. 'destination_missing' => 'The destination path configuration setting is missing.', ];

->getAllowedExtensions()

This will return the current list of allowed file extensions.

$extensions = $upload->getAllowedExtensions();

->setAllowedFileExtensions()

This is a basic, although insecure, method of matching the file extension uploaded with a preset list of allowable extensions. Allowed file types can be either an array of file extensions array('jpg', 'png', 'gif'), a pipe-separated list 'jpg|png|gif', or the '*' wild-card string.

$upload->setAllowedFileExtensions('jpg|png|gif'); # or $upload->setAllowedFileExtensions('*'); # or $upload->setAllowedFileExtensions(array('jpg', 'png', 'gif'));

->setAllowedMimeTypes()

This is a more secure method of matching the file mime types uploaded with a preset list of allowable mime types. The allowed mime types can be either an array of mime types array('image/jpg', 'image/png') or the '*' wild-card string.

# to allow all types $upload->setAllowedMimeTypes('*'); # to only allow jpg and png images. $upload->setAllowedMimeTypes(array('image/jpg', 'image/png'));

->getAllowedMimeTypes()

This will return the current list of allowed mime types.

$mime_types = $upload->getAllowedMimeTypes();

->getMaxFileSize()

This will return the current maximum set file size in bytes.

$size = $upload->getMaxFileSize();

->setMaxFileSize($maximum_file_size = false, $type = 'b')

This will set the MAXIMUM size that is permitted for the upload. The first parameter is the integer size and the second parameter is the type - such as b, kb, mb or gb.

$upload->setMaxFileSize(10, 'mb');

->getMinFileSize()

This will return the current minimum set file size in bytes.

$size = $upload->getMaxFileSize();

->setMinFileSize($minimum_file_size = false, $type = 'b')

This will set the MINIMUM size that is permitted for the upload. The first parameter is the integer size and the second parameter is the type - such as b, kb, mb or gb.

$upload->setMinFileSize(1, 'mb');

->setDestinationPath($path = false)

Sets the destination path for the uploads. It can either be a absolute path or a relative path to the script.

$upload->setDestinationPath('uploads/');

->setExtensionAs($extension = null)

Forces the uploaded file to use the passed $extension. This doesn't change the mime type - just forces the new file extension. Useful if you only want to accept a certain file type - such as jpg, it allows the forcing of the jpg extension.

$upload->setExtensionAs('jpg');

->setName($name = false, $clean = true)

Sets the overriding file name - using the cleanFilename method. This can only be used with single element files

$upload->setName('my-image');

->generateName($bool)

Sets the configuration option to create random filenames on the fly.

$upload->generateNames(true);

->ignition()

This is the main ignition switch. This must be called after all of the configuration options have been set.

This will populate the file counts & internal file objects. This starts the upload engine.

$upload->ignition();

->hasErrors()

This will return true or false depending on if an error has occurred. It can be combined with errors() to show a list of errors.

if($upload->hasErrors()){ foreach($upload->errors() as $error){ echo '<li>ERROR: ' . $error . '</li>'; } }

->errors()

This returns an array of errors that occurred during the upload process. It can be combined with hasError().

if($upload->hasErrors()){ foreach($upload->errors() as $error){ echo '<li>ERROR: ' . $error . '</li>'; } }

->isMultiple()

This will return true or false is the there are multiple files being uploaded.

$is_multiple = $upload->isMultiple();

->fileCount()

This will return the number of file uploads submitted.

$count = $upload->fileCount();

->debug()

This will print a debug message for development and testing.

$upload->debug();

->successes()

This will return an array of successfully uploaded files.

foreach($upload->successes() as $files){ echo $file->name . ' has been uploaded'; }

->files()

This will return an array of file objects. If called after the upload() will also return the status of the upload.

foreach($upload->files() as $files){ echo $file->name; }

->upload()

This automatically performs the validation and processing on the uploaded files without additional coding.

$upload->upload();

Callback Options

The reason for this class is to provide the easiest way to handle uploads and validation without having to manually perform all of the checks. The following callback methods can be used for advanced upload integration. If you are looking for a simple integration - see upload() above.


->each($callback)

The each() accepts a callback and it loops through each file waiting to be uploaded.

$upload->each(function($file){ # this will print the file object for each upload found. print_r($file); });

->success($callback)

Applies the callback to all of the successfully upload files.

$upload->success(function($file){ echo $file->name . ' has been successfully uploaded.'; });

->error($callback)

Applies the callback to all of the uploads that have had an error.

$upload->error(function($file){ echo $file->name . ' could not be uploaded due to an error.'; });

->validate($file)

Runs the validation method on the $file supplied. This is for use within an each() callback.

$upload->each(function($file){ $isValid = $this->validate($file); });

->process($file)

Runs the actual upload on the $file supplied. This is for use within an each() callback.

$upload->each(function($file){ $isValid = $this->validate($file); if($isValid){ $this->process($file); } });

$file

All of the methods that return a $file object will have the following properties.

$file->id; # The id of the upload. $file->source->path; # the source tmp_path $file->source->filename; # the source file name $file->source->extension; # the source file extension $file->source->name; # the source file name $file->source->size; # the source size $file->source->type; # the source type from $_FILES $file->source->mime_type; # the source mime type $file->source->error; # the $_FILES error. $file->destination->size; # the destination file size $file->destination->mime_type; # the destination mime type $file->destination->extension; # the destination file extension $file->destination->filename; # the destination file nameof $file->destination->path; # the destination file path $file->success # returns boolean true/false $file->isValid # returns boolean true/false

Example: Simple Upload

In this example, we show the uploader in its simplest form. We are using the following HTML code:

HTML:

<!DOCTYPE html> <html> <body> <form method="post" enctype="multipart/form-data"> Select image to upload: <input type="file" name="image_upload[]" id="image_upload"> <input type="file" name="image_upload[]" id="image_upload"> <input type="file" name="image_upload[]" id="image_upload"> <input type="file" name="image_upload[]" id="image_upload"> <input type="submit" value="Upload Image" name="submit"> </form> </body> </html>

PHP:

try { $upload = new Upload('image_upload'); if ($upload->submitted()) { $upload ->setDestinationPath('uploads/') ->setAllowedMimeTypes(array('image/jpg', 'image/jpeg', 'image/png', 'text/plain')) ->setMaxFileSize(2, 'mb') ->ignition() ->upload(); if ($upload->hasErrors()) { # loop through each file that has error'd foreach ($upload->errors() as $file) { foreach ($file->errors as $error) { echo '<li>' . $error . '</li>'; } } } else { echo 'Upload(s) Complete!'; } } } catch (Exception $e) { die($e->getMessage()); }

Example: Advanced Upload

In this advanced example, we can showcase the callback methods. Again, we use the following HTML code:

HTML:

<!DOCTYPE html> <html> <body> <form method="post" enctype="multipart/form-data"> Select image to upload: <input type="file" name="image_upload[]" id="image_upload"> <input type="file" name="image_upload[]" id="image_upload"> <input type="file" name="image_upload[]" id="image_upload"> <input type="file" name="image_upload[]" id="image_upload"> <input type="submit" value="Upload Image" name="submit"> </form> </body> </html>

PHP:

try { $upload = new Upload('image_upload'); if ($upload->submitted()) { $upload ->setDestinationPath('uploads/') ->setAllowedMimeTypes(array('image/jpg', 'image/jpeg', 'image/png', 'text/plain')) ->setMaxFileSize(2, 'mb') ->ignition(); $upload->each(function ($file) use ($upload) { if ($upload->validate($file)) { # we can use $file here and perform additional checks or manipulations. # now we process the upload if ($upload->process($file)) { echo '<li>' . $file->destination->name . ' has been uploaded <b>SUCCESSFULLY</b>.</li>'; return; } } echo '<li><b>ERROR:</b> ' . $file->source->name . ' could not be uploaded.</li>'; return; }); } } catch (Exception $e) { die($e->getMessage()); }

Requirements

Tested to work with PHP 5.6 and PHP 7


License

Copyright (c) Benjamin Hall, ben@conobe.co.uk https://conobe.co.uk

Licensed under the MIT license


If you find this project helpful or useful in any way, please consider getting me a cup of coffee - It's really appreciated :)

Donate

More Projects?
Benjamin, is brilliant at what he does, he really knows what he is at. Gives real useful advice and guidance. He is fast and timely provides updates and always provides solutions and listens well. Trust me Benjamin is a breath of fresh air.

- Alexander T.

★★★★★

Ben had a great idea for my project and completed the project to our requirements very quickly. He also helped me tweak a few issues and answered my questions quickly. We'll work with Ben again!

- Gordon S.

★★★★★

I was impressed: a freelancer who could give me inputs and details on how he'd implement the solution, kept me updated in the meanwhile, understood my requirements and proposed pretty nice tweaks to make things even better. Ben, you are amazing. I will need no more time to find any other dev's, and will surely deal with you again if I need something related to these things in the future. Full stop.

- Marco F.

★★★★★

Absolutely superb, a great work ethic, outstanding knowledge and a great eye for detail. I thoroughly recommend him!

- Gary J.

★★★★★

Benjamin is a talented developer who can tackle technically challenging projects with great service and communication. Thoroughly recommended.

- Steven M.

★★★★★

Ben truly went above and beyond. He's fantastic at communication, coding, getting round problems, fixing issues, WordPress, custom plugins and much more. I will be using Ben again for other projects.

- Rachael R.

★★★★★

Ben went the extra mile and not only resolved the problem but provided a more suitable solution for the long term. Cheers!

- William R.

★★★★★

Ben is an amazing developer. He took the project and delivered it on time and within budget, whilst maintaining excellent communication. He also worked beyond what was asked to make sure the project was functioning correctly. Would highly recommend A++++!

- David B.

★★★★★

Fantastic work on our JS script. Ben worked beyond the goals of the project and overcame extra issues that were not defined in the project. He is very quick to respond and patent when waiting for our response. One of our top 5 Developers, We had to deal with many Interfaces including server firewalls/Java-scripting/JSON/PHP/PHP APIs/Remote Databases and automation.

- Kevin J.

★★★★★

Ben is just great to work with. Efficient, clearly communicating, understanding very quickly, and also giving great advice. I will continue working with Ben on any other WordPress stuff. Sorry for all those other PPH'ers :-)

- Bruno V.

★★★★★

Absolutely amazing experience. Ben is an expert in this field, I was amazed at how quickly he jumped on our platform and decoded the code, db etc. He will go over and above to find solutions for clients. Highly recommended.

- Harrus A.

★★★★★

Interested in working together to make something great? Hire CONOBE