How do I upload and work with an image?
This article will show you how to create an upload form that you can use to upload image files to a server, and how to then work with the uploaded data using LiveCode Server.
Creating a HTML upload form
There are many ways to transfer a local file to a server. The method we're going to use today is very simple - we will have a HTML form which allows us to post a file to the page. This is much like using a HTML form to allow the user to input text that is posted to the page for processing, except that we give it a file - the type parameter of the <input> tag is "file" instead of "text". This type creates a button which will display a file picker dialog when clicked.
<form action="upload.lc" method="post" enctype="multipart/form-data"> <input type="file" name="uploadedfile"><br> <input type="submit" name="submit" value="Submit"> </form>
I'll briefly explain the parameters we give each of the form elements. In the form tag, the filename of our upload form is "upload.lc", we're going to do this all in one file so the form posts back to itself. The method is post, as we are posting data to the server. The encoding type needs to be "multitype/form-data" for a file upload to work.
The first input tag is the file upload button. The type is "file", as we're sending a file. The name is "uploadedfile", which is was we will use to identify the file we uploaded when we come to process it in LiveCode Server code. The second input tag is just our submit button.
Handling the uploaded image
We now have a form which will allow us to choose an image on our computer, and post it to the page. Now that the data is on the server, we need to access it and perform whatever actions we want to do on it. In this instance, we're just going to save the image to a file. Accessing the uploaded data is done using the $_FILES array. As we used 'uploadedfile' as the name parameter in the file input tag, the data will be in $_FILES["uploadedfile"]. This contains 4 keys: 'filename', 'name', 'type', and 'size'. They are the filepath, filename, error that occurred during upload (if applicable), and the file size.
The main one we're interested in here is the filename. This is the path to the temporary file that was created on the server to hold the uploaded data. This will generally be in the server's temp directory, i.e. /tmp on Linux systems. We're going to access the contents of this file using url() and then copy it into the same directory as the server script, so that we have a more permanent copy to work with:
if $_FILES["uploadedfile"]["filename"] is not empty then put url("binfile:" & $_FILES["uploadedfile"]["filename"]) into url("binfile:" & $_FILES["uploadedfile"]["name"]) end if
In this example, we also use the contents of $_FILES["uploadedfile"]["name"] to name the file we copied it to. Note that in this instance we are accessing an image, which is a binary file type, so we need to use "binfile:" in the url() function instead of "file:".
When allowing a file to be uploaded like this, we need to do a little more work in order to verify that the file the user has uploaded is the type of file we expect, and does not actually contain malicious code instead. A good place to start with this is to check the contents of $_FILES["uploadedfile"]["type"]. This should be something like "image/png" or "image/gif" if it's an image file:
if ($_FILES["uploadedfile"]["filename"] is not empty) and ("image" is in $_FILES["uploadedfile"]["type"]) then put url("binfile:" & $_FILES["uploadedfile"]["filename"]) into url("binfile:" & $_FILES["uploadedfile"]["name"]) end if
However, this isn't a strong way of detecting a malicious file, as this information can easily be tampered with and forged, and image files can have malicious code embedded in them. There are many approaches to more thoroughly checking a file. An extremely effective way is to export a brand new image file from the original image, as this will not preserve code that has been embedded in the original image file - we're going to be doing this in the next lesson. You should also make sure that the file extension is what you would expect for an image file.