I am a senior PHP developer. It’s what I tell myself, anyway.
That means I should know how to do stuff life this.
I had to handle a file-upload in a project recently, without the hand-holding of a framework, and I found it harder than I remembered.
Here’s all the bits and pieces I nearly forgot about.
Is PHP going to let you upload your file? How big a file can I upload?
Check the following section in your php.ini
file and check your settings.
;;;;;;;;;;;;;;;;
; File Uploads ;
;;;;;;;;;;;;;;;;; Whether to allow HTTP file uploads.
; http://php.net/file-uploads
file_uploads = On; Temporary directory for HTTP uploaded files (will use system default if not
; specified).
; http://php.net/upload-tmp-dir
; upload_tmp_dir = /tmp; Maximum allowed size for uploaded files.
; http://php.net/upload-max-filesize
upload_max_filesize = 150M; Maximum number of files that can be uploaded via a single request
max_file_uploads = 20
The most important thing here is file_uploads (which is normally on by default) and upload_max_filesize (which is normally smaller than you need by default). Also, pay attention to upload_tmp_dir… you’ll need this shortly.
You’re not done yet. One more setting to change.
; Maximum size of POST data that PHP will accept.
; Its value may be 0 to disable the limit. It is ignored if POST data reading
; is disabled through enable_post_data_reading.
; http://php.net/post-max-size
post_max_size = 150M
If you haven’t changed this setting, you’ll see error messages like these:
PHP Warning: POST Content-Length of 63023816 bytes exceeds the limit of 8388608 bytes in Unknown on line 0, referer: https://mywebsite.com/upload
If you don’t have easy access to your PHP.ini file, or you’re not sure which php.ini
file Apache is running you can also figure this out by creating a quick and dirty PHP script.
<?php
phpinfo();
Is your HTML form going to let you upload your file?
<form action="/upload" enctype="multipart/form-data"><input type="hidden" name="MAX_FILE_SIZE" value="150000000">
<input type="file" name="myfile" accept="application/zip">
<input type="submit" value="Upload"></form>
The sections in bold are actually important. The enctype tells HTML to send up a file. PHP pays attention to the magic MAX_FILE_SIZE form field and will dis-allow your file if it’s too small. You should also set the MIME type of the file, if you know what you’re going to be dealing with.
Hit your fancy Upload button, and assume you’ve got PHP sitting at that /upload
endpoint.
What has PHP done with my file?
PHP sticks your file in one it’s magical autoglobals, $_FILES
. If all has gone according to plan, $_FILES
will be populated with details about the file you’ve just uploaded. Note that PHP is set up to handle multiple file-uploads at the same time, so $_FILES
is an array of files, and will be keyed by the name used in the file field. Above, we used the string myfile
, so we’ll use the same below.
It has also taken the uploaded file, and stuck it in a temporary folder with a temporary name.
If you have set the upload_tmp_dir directory above, then you’ll know exactly where it is.
If you haven’t or can’t, it will upload it to the default system temp directory. Normally, (and what is normal, exactly?) this is /tmp
but this is not information you can go to the bank with. You should double-check. To do this, you can use the standard function: sys_get_temp_dir()
.
The files will also be uploaded with a temporary name, so you’ll need to rename it. Normally we’ll use the value of $_FILES['myfile']['name']
.
How do I use this file?
If you want to keep your file around, you’ll need to move it out of the temp directory to a permanent location, and rename it.
Normally you’d do something like this:
$properName = $_FILES['myfile']['name'];
$properPath = '/my/app/uploads/'.$properName;move_uploaded_file($_FILES['myfile']['tmp_name'], $properName);
Can I do something with a Zip file?
Yes, you’re in luck.
PHP has a standard library that you can use, and it is straightforward.
(Also, you can and should validate by checking the MIME type.)
$uploadedFilename = $_FILES['articulate-zip']['tmp_name'];if (mime_content_type($uploadedFilename) !== 'application/zip') {
throw new Exception("This ain't a ZIP file compadre.");
}$zip = new ZipArchive();
if ($zip->open($uploadedFilename)) {
$zip->extractTo($localDirectory);
$zip->close();
} else {
throw new Exception('Unable to process ZIP file');
}
Conclusion
That’s it!
I say it’s for you, but this article is really for me so I can continue to look like a senior PHP dev.