Image from database is not being displayed!?

just like i wrote:

Alright, do I still incorporate the input type="file" name="avatar" /> ?? How do I use the $_FILES with the image and how do I use the file_get_contents() with the avatar to insert it into the database within the query?

type=“file” stays. did you have a look at $_FILES after upload and what does it tell you?

When putting var_dump($_FILES); underneath the query execute where it inserts the file name into database and all the other input(s) it simply displays:

A:\wamp64\www\heartfx\register.php:159:
array (size=0)
  empty

line 159 is where I put the var_dump($_FILES);

maybe there’s the enctype="multipart/formdata" attribute missing within your form. But i can’t imagine how it ever worked then.

That was missing, yes but when I added it with the var_dump($_FILES); at the end of the execute query, it still displayed nothing but:

A:\wamp64\www\heartfx\register.php:159:
array (size=0)
  empty

can you provide an example? and it has to be enctype="multipart/form-data" as stated in the manual:

http://php.net/manual/en/features.file-upload.post-method.php

This is now how my form looks :slight_smile:

<form enctype="multipart/form-data" method="post" class="register_module">

    <h2 style="text-align:left;font-family:'Roboto',sans-serif;">Account Credentials<span style="font-size:12px;font-weight:400;"> (required)</span></h2>

    <div class="account_credentials">
      <input class="register_module protect_from_spaces" type="text" name="username" placeholder="choose a username*" maxlength="30" required><br />
      <input class="register_module protect_from_spaces" type="email" name="email" placeholder="email address*" required><br />

      <div class="row_inline">
        <input class="register_module input protect_from_spaces" type="password" name="password" placeholder="password*" maxlength="18" required>
        <input class="register_module input protect_from_spaces" type="password" name="cpassword" placeholder="confirm password*" maxlength="18" required><br />
      </div>
    </div>
      <br />

      <!-- here add user details section (name, avatar, birthday, etc...) -->
      <h2 style="text-align:left;font-family:'Roboto',sans-serif;">Account Details<span style="font-size:12px;font-weight:400;"> (optional)</span></h2>

      <br />
      <div class="account_details">
        <p style="text-align:left;font-family:'Roboto',sans-serif;font-weight:400;">Name:</p>
        <input class="register_module_short protect_from_spaces" style="margin-right:1%;" type="text" name="first_name" placeholder="first name" />
        <input class="register_module_short protect_from_spaces" type="text" name="last_name" placeholder="last name" />

        <p style="text-align:left;font-family:'Roboto',sans-serif;font-weight:400;">Birthday:</p>
        <input style="margin-top:-10px;" class="register_module protect_from_spaces" type="date" name="birthday" />

        <p style="text-align:left;font-family:'Roboto',sans-serif;font-weight:400;">Social Link(s):</p>
        <input class="register_module protect_from_spaces" style="margin-top:-10px;" type="url" name="steam_profile" placeholder="steam profile (http://www.steamcommunity.com/id/lowheartrate/)" />
        <input class="register_module protect_from_spaces" type="text" name="twitter_profile" placeholder="twitter profile (https://twitter.com/lowheartrate)" />
        <input class="register_module protect_from_spaces" type="text" name="facebook_profile" placeholder="facebook profile (https://www.facebook.com/officiallowheartrate)" />
        <input class="register_module protect_from_spaces" type="text" name="instagram_profile" placeholder="instagram profile (https://instagram.com/lowheartrate)" />

        <!-- image upload for avatar... -->
        <div class="image_uploader">
          <h2 style="text-align:left;font-family:'Roboto',sans-serif;">✌ Avatar Uploader</h2><br />

          <p style="margin-top:-20px;font-size:12px;text-align:left;">Select image to upload:</p>
          <div style="text-align:left;font-size:12px;margin-top:-5px;margin-bottom:25px;">
            <input type="file" name="avatar" class="" />
          </div>
        </div>
      </div>

      <!-- check errors in registration -->
      <?php checkRegisterErrors(); ?>

      <br />
      <p class="pull-left" style="max-width:50%;">by signing up, you agree to our <a href="#">terms</a> and that you have read our <a href="#">privacy policy</a> and <a href="#">content policy</a>.</p>
      <div class="g-recaptcha pull-right" data-sitekey="6Levrg4TAAAAAN-pL6Xl2tndj3ZDn5nJ3PRUhMV-"></div><br />

      <br />

      <button type="submit" class="btn-register" style="margin-top:10px;">sign up</button>
  </form>

There we go, Now after registration I get the following from the var_dump($_FILES);

A:\wamp64\www\heartfx\register.php:154:
array (size=1)
  'avatar' => 
    array (size=5)
      'name' => string '13124806_582930801867475_3656494793348492958_n.jpg' (length=50)
      'type' => string 'image/jpeg' (length=10)
      'tmp_name' => string 'A:\wamp64\tmp\php1BC.tmp' (length=24)
      'error' => int 0
      'size' => int 57127

now that you know where the file is located through tmp_name you can insert the results from file_get_contents()

1 Like

How would I go about using file_get_contents() with the tmp_name and how would I put that statement in my query for it to insert into the database?

is this a joke? as the manual states

the only parameter that is required is the filename! so how do you think this works together with tmp_name?

file_get_contents('tmp_name'); ?

I have tried the following:

$fileName = $_FILES['avatar']['name'];
$tmpName = $_FILES['avatar']['tmp_name'];
$fileSize = $_FILES['avatar']['size'];
$fileType = $_FILES['avatar']['type'];

$fp = fopen($tmpName, 'r');
$avatar = fread($fp, filesize($tmpName));
$avatar = addslashes($avatar);
fclose($fp);

$query = dbConnect()->prepare("INSERT INTO users (username, password, email, activated, activation_id, avatar) VALUES (:username, :password, :email, :activated, :activation_id, :avatar)");
$query->bindParam(':username', $username);
$query->bindParam(':email', $email);
$query->bindParam(':avatar', $avatar);
$query->bindParam(':password', $hash);
$query->bindValue(':activated', "0");
$query->bindValue(':activation_id', $activation_id);
$query->execute();

and the image is inserted into my database now and it looks like the following:
https://puu.sh/sqFeT/20da1785af.png
How should I be echo’ing this in my page now? Should I use the same method with $row['avatar']; ?

When trying to use:
echo '<img src="' .$avatar. '" class="user_avatar" alt="' .$username. ' avatar" />';

It displays the following on my navigation-bar where the image should appear (the fuzzy characters you spoke of earlier):
https://puu.sh/sqFqx/22c56851c1.png

After messing around throughout the day I still cannot find out what is wrong with my statement(s). The only thing that is being echo’d is the weird characters here instead of the actual image being displayed :frowning:
https://puu.sh/sqFqx/22c56851c1.png

Here is how the file is being inserted into the database:

<input type="file" name="avatar" class="" />

$fileName = $_FILES['avatar']['name'];
$tmpName = $_FILES['avatar']['tmp_name'];
$fileSize = $_FILES['avatar']['size'];
$fileType = $_FILES['avatar']['type'];

$fp = fopen($tmpName, 'r');
$avatar = fread($fp, filesize($tmpName));
$avatar = addslashes($avatar);
fclose($fp);

$query = dbConnect()->prepare("INSERT INTO users (username, password, email, activated, activation_id, avatar) VALUES (:username, :password, :email, :activated, :activation_id, :avatar)");
$query->bindParam(':avatar', $avatar);

This is how I am trying to echo that avatar:

$username = $_SESSION['username'];

// run query to get users avatar
 $getAvatar = dbConnect()->prepare("SELECT * FROM users WHERE username = :username");
 $getAvatar->bindParam(':username', $username);
// execute query
$getAvatar->execute();
// set each column as row
$row = $getAvatar->fetch(PDO::FETCH_ASSOC);
// set $avatar as users set avatar
$avatar = $row['avatar'];

echo '<img src="' .$avatar. '" class="user_avatar" alt="' .$username. ' avatar" />';

You’re making it harder than it should be. All you should be doing is uploading the picture to a folder along with whatever changes you made to that picture. Then at the same time, just use the file name and store it in a var data type of a text data type. Then when you want to display the image, output the file name and add your website URL and folder location to the output. I remember @felgall once argued about this topic. I don’t remember which side he was on, but the topic was about whether you should be storing the actual file in a blob or in a folder.

I strongly suggest storing it in a folder because it’s a lot simpler to work with.

Example


So pretend this is the value that is stored in your column.

this_is_just_a_test_picture.jpg

On the output page, you just do

<?php
$avatar = 'this_is_just_a_test_picture.jpg'; /// assuming $avatar is grabbed from the database
print('://example.com/user/avatar/' . $avatar);

And we use :// because at the moment, I can’t assume your preference for the HTTP protocol so using :// will use both HTTP and HTTPS.


I just noticed you are using the tmp name for renaming the file. I suggest that you generate a file name for it instead. The reason why you are having problems with it is because

  • You haven’t actually uploaded the picture.
  • You are storing the full path in the database which will end up being the wrong output anyways.

So you’ll actually end up with something like

<img src="C:/Users/spaceshiptrooper/AppData/roaming/tmp/Random_File_Name.jpg" alt="Demo avatar">

Which isn’t something you want to be displaying on screen. Doing this is basically saying “HEY HACKER! Come over here! My file locations are as such!”

1 Like

Thank you for explaining! I am actually going to be using each image as an avatar for each user so how can I make sure that I am getting the correct file for the correct user? I like to tackle this step by step in order to make sure I am doing everything correctly along the way.

So first I need to:

  • Upload the image to a folder instead of inserting it into a BLOB in the database.

My registration page currently looks like this. How should I alter this to have the image go to a folder instead of the database?

just use move_uploaded_file() for this. Save the path with the user record. Put the image folder path along with the image path from the user within your image src-attribute.

1 Like

Neither or both I guess.

Post form data to mysql table including images - #11 by felgall

https://www.sitepoint.com/community/t/inserting-and-then-retrieving-a-blob-data-from-mysql-database-using-php/98266/3

https://www.sitepoint.com/community/t/inserting-and-then-retrieving-a-blob-data-from-mysql-database-using-php/98266/3?u=mittineague

His “how to”
http://www.felgall.com/mysql06.htm

1 Like

Sorry for the dumb question but by the user record do you mean save the file name with the username input from the form as well in the directory? Also, how should that statement look - something like this?

// move uploaded file to directory (includes/uploads/avatar)
$upload_directory = 'includes/uploads/avatars';
$tmp_name = $_FILES['avatar']['tmp_name'];
move_uploaded_file($tmp_name, $upload_directory);

Quick Note: I put that statement directly under the query where it inserts the other form <input>'s into the database. I have also updated the pastebin of the register.php where I put this code in here.

i would prefer to make your own filename for two reasons:

  • ensure that you do not overwrite existing images, you can use microtime() or uniqid()
  • validating the file extension, or translating it by MIME type via finfo_file()

put this into the folder and save the name with the user record

How would I go about doing this? My code I have right now is

// move uploaded file to directory (includes/uploads/avatar)
$upload_directory = 'includes/uploads/avatars';
$tmp_name = $_FILES['avatar']['tmp_name'];
move_uploaded_file($tmp_name, $upload_directory);

Would I have to make a new variable like $file_name and make it so the code is something like:

// move uploaded file to directory (includes/uploads/avatar)
$upload_directory = 'includes/uploads/avatars';
$image = $_FILES['avatar'][$file_name];
move_uploaded_file($image, $upload_directory);

Also, how would I go about using microtime() or uniqid() to generate a random name for the $file_name variable?