Image upload/receive API

18,190

Solution 1

The easiest way is to store the file in a folder on your server. Then store the URL of the file in a MySQL Database, and pull the file URL (assuming you have a login function) if the user does not know the file location.

For instance:

(UPLOAD.PHP or the script you are using to upload the file to your server)

<?php
    $connect_to_db = mysqli_connect('localhost', 'user', 'pass', 'db');

    $user = $_POST['user'];

    $allowedExts = array("gif", "jpeg", "jpg", "png");
    $temp = explode(".", $_FILES["file"]["name"]);
    $extension = end($temp);

    if ((($_FILES["file"]["type"] == "image/gif")
    || ($_FILES["file"]["type"] == "image/jpeg")
    || ($_FILES["file"]["type"] == "image/jpg")
    || ($_FILES["file"]["type"] == "image/pjpeg")
    || ($_FILES["file"]["type"] == "image/x-png")
    || ($_FILES["file"]["type"] == "image/png"))
    && in_array($extension, $allowedExts)) {

      if ($_FILES["file"]["error"] > 0) {

        echo "Error: " . $_FILES["file"]["error"] . "<br>";

      } else {

        //Move the file to the uploads folder
        move_uploaded_file($_FILES["file"]["tmp_name"], "uploads/" . $_FILES["file"]["name"]);

        //Get the File Location
        $filelocation = 'http://yourdomain.com/uploads/'.$_FILES["file"]["name"];

        //Get the File Size
        $size = ($_FILES["file"]["size"]/1024).' kB';

        //Save to your Database
        mysqli_query($connect_to_db, "INSERT INTO images (user, filelocation, size) VALUES ('$user', '$filelocation', '$size')");

        //Redirect to the confirmation page, and include the file location in the URL
        header('Location: confirm.php?location='.$filelocation);
      }
    } else {
      //File type was invalid, so throw up a red flag!
      echo "Invalid File Type";
    }
?>

Now what you can do is make a table in a page, and have it list all the uploaded files based on who is logged in (again, assuming you use this feature). This will allow the person to know have to keep a log of all the files they upload.

The following example is if you are posting the data using Ajax, and it returns the JSON formatted data, so you can have the user not have to reload the page.

<?php
    $connect_to_db = mysqli_connect('localhost', 'user', 'pass', 'db');

    $user = $_POST['user'];

    $allowedExts = array("gif", "jpeg", "jpg", "png");
    $temp = explode(".", $_FILES["file"]["name"]);
    $extension = end($temp);

    if ((($_FILES["file"]["type"] == "image/gif")
    || ($_FILES["file"]["type"] == "image/jpeg")
    || ($_FILES["file"]["type"] == "image/jpg")
    || ($_FILES["file"]["type"] == "image/pjpeg")
    || ($_FILES["file"]["type"] == "image/x-png")
    || ($_FILES["file"]["type"] == "image/png"))
    && in_array($extension, $allowedExts)) {

      if ($_FILES["file"]["error"] > 0) {

        echo json_encode(array('status' => 'error', 'msg' => 'File could not be uploaded.'));

      } else {

        //Move the file to the uploads folder
        move_uploaded_file($_FILES["file"]["tmp_name"], "uploads/" . $_FILES["file"]["name"]);

        //Get the File Location
        $filelocation = 'http://yourdomain.com/uploads/'.$_FILES["file"]["name"];

        //Get the File Size
        $size = ($_FILES["file"]["size"]/1024).' kB';

        //Save to your Database
        mysqli_query($connect_to_db, "INSERT INTO images (user, filelocation, size) VALUES ('$user', '$filelocation', '$size')");

        //Return the data in JSON format
        echo json_encode(array('status' => 'success', 'data' => array('filelocation' => $filelocation, 'size' => $size)));
      }
    } else {
      //File type was invalid, so throw up a red flag!
      echo json_encode(array('status' => 'error', 'msg' => 'Invalid File Format'));
    }
?>

If you would also like to restrict the file size, you can add a simple line of code that will also check for the file size, and if it is to big, won't let it go through:

if ((($_FILES["file"]["type"] == "image/gif")
|| ($_FILES["file"]["type"] == "image/jpeg")
|| ($_FILES["file"]["type"] == "image/jpg")
|| ($_FILES["file"]["type"] == "image/pjpeg")
|| ($_FILES["file"]["type"] == "image/x-png")
|| ($_FILES["file"]["type"] == "image/png"))
&& ($_FILES["file"]["size"] < 20000) //Must be smaller than 20KB
&& in_array($extension, $allowedExts)) {

If you need any more help, feel free to let me know. :)

Solution 2

You can encode_base64 the raw php input - image file - and store in a mysql row which is ASCII BIN, LONG TEXT structure, and then pull the data back from mysql and show like this:

<img alt="Embedded Image" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIA..." />

Solution 3

I would also recommend to use fileinfo or even some libraries like imagemagic to be sure that image is an image - and if it is convert it to the ones that can be shown on page.

Also because you check file size after it was already sent to server, you can check if you can convert its size to be smaller instead of just rejecting it.

PS: http://www.plupload.com/ this is library that you can user free or with small one time fee - it also have some php written receiver for itself.

Solution 4

The upload method that Brian's answer mentioned is a ideal solution. And it is easy to store the pictures. You should create a table in the db of your server and to store the file name of the picture, for example, as format of "filename.+filetype". Then store the pictures in some folder of server.

You don't need to store the whole path of the picture like www.xxx.com/upload/temp/1.png, try to use a php function to create the absolute path for www.xxx.com/upload/temp/, then once you want to show the picture. Just use

<img src="<?php echo func("1.png")?>" alt=""> 

func() is a function that create the absolute path.

For more information, you could check w3c tutorial PHP file upload

I use this way in my website. Hope it could help you.

Solution 5

You're thinking too low-level

Your API really ought to be built atop some other protocol that has already solved presentational issues of this sort.

Over HTTP, for example, one would just transmit the file in its raw binary form—sure, one can specify in the protocol headers that an encoding has been applied to the content or the transfer, but pretty much only compression encodings (that result in yet more binary) are supported.

Share:
18,190

Related videos on Youtube

Forivin
Author by

Forivin

Open source, security, Linux, DIY electronics enthusiast and privacy advocate.

Updated on May 25, 2022

Comments

  • Forivin
    Forivin almost 2 years

    I'd like to offer a simple API on my website that allows people to upload images to it (and receive the URL to access it).

    But I have several questions:

    • Would it be better if the user would have to send the image in binary code or would it be better if the user would have to send it in idk ASCII or so? What is the conventional way? (I'm asking that because I can imagine that some languages only have functions to read files as textfiles.)

    • Where do I store the images on the server and how? Can I put them in a MySQL database and would that perform well? Or should I put them all in one folder?

    • How should the user be able to specify the file type? In the header or in the body?

    • How do I receive and the data save it as a file?

    I found this code somewhere else:

    <?php
    
    /* PUT data comes in on the stdin stream */
    $putdata = fopen("php://input", "r");
    
    /* Open a file for writing */
    $fp = fopen("myputfile.ext", "w");
    
    /* Read the data 1 KB at a time
       and write to the file */
    while ($data = fread($putdata, 1024))
      fwrite($fp, $data);
    
    /* Close the streams */
    fclose($fp);
    fclose($putdata);
    
    ?>
    

    Does this work for binary files like images?
    Is it a good idea to "Read the data 1 KB at a time"?

    • Forivin
      Forivin almost 10 years
      I'm just asking for the more conventional and thereby better way of doing it, not for opinions. I don't think that my question is opinion-BASED.
    • kennypu
      kennypu almost 10 years
      for storing, you can either 1. store it in the database as BLOB data. in this case, you also need to store file size, and file format as well (unless you're only allowing one type of image), or 2. store the file on the web server, or file server etc. and just store the path to the file in the database. Latter is easier to implement.
    • kannetkeifer
      kannetkeifer almost 10 years
      there is a lot of ways to make a better file upload handler besides the issues you have been listed @Forivin for example how to handle the file with the same name as basic as this if you go further more different issues will arise so i suggest try to find some API instead if not looking for any opinion here
    • Forivin
      Forivin almost 10 years
      I was planning to random generate new names anyway. What are the other issues that might arise? And I don't want to use "some" random API, I want to inform myself about how I should make the API... @kennypu Thanks, I'll go with the second option.
  • Forivin
    Forivin almost 10 years
    So how would the user have to send the picture to the script? Just as binary code in the request body?
  • Brian Logan
    Brian Logan almost 10 years
    Depends on a couple of things. If it is an API, it is a little more tricky than if it was just a form on a website. What is your end goal? Being able to just have users push data through an API, or through a form?
  • Forivin
    Forivin almost 10 years
    Like I mentioned it in the question, I want to write an API. I want it to be simple, but it should also be usable in most common programming languages. On the website there won't be a form, users can only upload pictures though the API.
  • Brian Logan
    Brian Logan almost 10 years
    Let me play with a couple things in a sec and I will let you know :)
  • Forivin
    Forivin almost 10 years
    After what I read, databases can get really slow when they are too crowded with data. So I think that I'll stand aloof this for now. I also only have one database available. :/ But thank you anyway!
  • Brian Logan
    Brian Logan almost 10 years
    Forivin, what languages are you looking to have your API in? PHP, JS? Or more?
  • Forivin
    Forivin almost 10 years
    Well, pretty much all common languages. Python, Ruby, VB Script, AutoIt/Autohotkey, Javascript, PHP, ... and of course C++, Java, C#, ...
  • Forivin
    Forivin almost 10 years
    I just tried this: pastebin.com/sP51Tj7h an it works pretty well. But only for PUT requests. But since POST seems to be the more used one, I think POST would be better.
  • Forivin
    Forivin almost 10 years
    But what he posted is meant to use for HTML form uploads, if I understood it correctly. Sot this is not really ideal for people who are using a completely different language.