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
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.
