Skip to content
Advertisement

Uploading images to MySQL (blob) with PHP

For security reasons I’ve decided that uploading user profile images to a database, rather than just a folder and uploading the image addresses, would be a good idea.

I’ve never dealt with file uploads in a backend before, but having read up about this from various sources, I believe that I’m doing everything correctly. However no useful binary data is being uploaded.

in php.ini

file_uploads=On

In the frontend

<form enctype="multipart/form-data" method="post" autocomplete="on" action="upload/">       
    <p>
        <input type="file" id="avatar" name="avatar" accept="image/png, image/jpeg" required />
        <label for="avatar">*Profile photo</label>

    </p>

    <p class="submitter two-thirds columns">
        <input type="submit" value="Apply" />
    </p>
     
</form>

In the backend

if(isset($_SESSION['id']))
    $UserID = $_SESSION['id'];
else exit(1);

if (!empty($_FILES['avatar'])){
    $photo = fopen($_FILES['avatar']["tmp_name"], 'rb');
    $photo_mime = $_FILES['avatar']["type"]; 
}
else exit(1);

$values_data = array(
    $UserID,
    $photo,
    $photo_mime,
);


$sql = "INSERT INTO `user`
    (
        UserID,
        photo,
        photo_mime
    )
    VALUES
    (
        :UserID,
        :photo,
        :photo_mime
    )
    ON DUPLICATE KEY UPDATE
        photo = :photo,
        photo_mime = :photo_mime
    ";

$sth = $dbh->prepare($sql);


$sth->bindValue(':UserID', $values_data[0]);
$sth->bindValue(':photo', $values_data[1]);
$sth->bindValue(':photo_mime', $values_data[2]);
$sth->execute();

And the database does get some information

mysql phpmyadmin

However those image binaries are all 1KB. Looking inside them they have data that is like this

Resource id #13

So the binaries are getting messed up or dropped somewhere along the line… but where?

Advertisement

Answer

fopen() doesn’t return the contents of the file. It returns a file pointer resource, which you then can pass to something like fread() to get the contents.

Something like:

$handler = fopen($_FILES['avatar']["tmp_name"], 'r');
$file = fread($handler, filesize($_FILES['avatar']["tmp_name"]));
fclose($handler);

An easier way would be to use file_get_contents():

$file = file_get_contents($_FILES['avatar']["tmp_name"]);

which will give you the contents in one line.

User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement