1

I am still having trouble hashing my pictures when I upload them . I have this code :

$target_dir = "images/uploads/";
$target_file = $target_dir . basename($_FILES["fileToUpload"]["name"]);
$uploadOk = 1;
$imageFileType = pathinfo($target_file,PATHINFO_EXTENSION);
   hash_file('sha256', $target_file );

  // Check if image file is a actual image or fake image

      if(isset($_POST["change"])) {

    move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file);
    $sql = "UPDATE users SET userPic = '".$_FILES['fileToUpload']['name']."' WHERE username = '" . $username . "'";

    $check = $conn->query($sql);

    if($check !== false) {
    echo "<a href = profile.php> Profile pciture has been changed </a>" . 
    $check["mime"] . ".";
    $uploadOk = 1;

    } else {
    echo "File is not an image.";
    $uploadOk = 0; 
    }
    } else {

     echo"did not change";

     }

and I am getting this error :

Warning: hash_file(images/uploads/english_royal_family_tree.jpg): failed to open stream: No such file or directory

I have been trying for more than a week . No one is really helping and people just keep on voting down my question and aren't giving any help . Can someone please help me ?

Isaac Bennetch
  • 11,830
  • 2
  • 32
  • 43
  • So, why do you hash file before creating it? – u_mulder Jan 27 '18 at 17:47
  • check the permissions then and make sure the path is correct and it does exist. – Funk Forty Niner Jan 27 '18 at 17:47
  • @u_mulder I've tried every way I possibly can . That was the last way I tried so that's why I posted the code that way . –  Jan 27 '18 at 17:49
  • `$target_file` does not exist when you call `hash_file`, you should call `hash_file` after `move_uploaded_file`, it's a simple logic, isn't it? – u_mulder Jan 27 '18 at 17:50
  • @FunkFortyNiner it is correct . The images are going into the directory and the database but they aren't hashed . And I can't upload the same picture twice –  Jan 27 '18 at 17:50
  • I put this `hash_file('sha256', $target_file );` between the `move_uploaded_file` and `$sql` and I'm getting the same error –  Jan 27 '18 at 17:51
  • 1
    Then check result of `move_uploaded_file`, if it's `false` then your file failed to copy. – u_mulder Jan 27 '18 at 17:52
  • How do I do that ? `echo` ? –  Jan 27 '18 at 17:54
  • I just did this ` move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file); $display_message = "file moved successfully"; hash_file('sha256', $target_file ); $sql = "UPDATE users SET userPic = '".$_FILES['fileToUpload']['name']."' WHERE username = '" . $username . "'";` –  Jan 27 '18 at 17:56
  • And I'm getting the same warning message and the statement saying that the image changed successfully –  Jan 27 '18 at 17:57
  • you should be hashing the "file" and not the entire path and file. – Funk Forty Niner Jan 27 '18 at 18:01
  • I just did this `hash_file('sha256', $_FILES['fileToUpload']['name'] );` and I'm getting the same error . I am missing something here because I really don't see the problem –  Jan 27 '18 at 18:03

1 Answers1

3

Firstly, hash_file() is expecting a file to already exist and you're trying use that method before the file gets uploaded; that's why your code failed and threw you that error.

What you need to do is to see if that file exists and then hash it.

If this is really want you want to do, then you can base yourself on the following and remember to store the renamed file while retaining its original extension; there are links at the end of the answer.

Note: As I mentioned in comments, you need to hash the file and not the whole destination folder and the file. That would be impossible to retrieve.

Echo the variable for what was assigned to hash_file(). You will also get your hash name (only) shown minus its extension.

Check for errors and make sure the folder has been granted proper permissions.

<?php 

// check for errors
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

$file_name = $_FILES['fileToUpload']['name'];
$sent_file = move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file);

 if (file_exists("images/uploads/" . $_FILES["fileToUpload"]["name"]))
  {
  echo $the_file = $_FILES["fileToUpload"]["name"] . " exists.";
  
    // its new location and hashing the filename only.
   $var = hash_file('sha256', $the_file );
   echo $var;
   
   // store your renamed file here in your database
   // using the assigned $var variable.
  
  }

Also check for errors on the query with mysqli_error($conn).

However, you're going to end up with problems here to show that image, since now and for example in using "file.jpg" will produce the following hash:

cf80cd8aed482d5d1527d7dc72fceff84e6326592848447d2dc0b0e87dfc9a90

I don't know how you plan on showing the image(s), but it will no longer keep the .jpg extension.

In order to retain the image's file extension, you basically need to rename the uploaded file(s).

Here are a few good references on Stack (that I've had success with in the past) that you can look at and implement it in your code. :

There is indeed no better way to learn, IMHO.


Edit:

This is an excerpt from a script I wrote recently. Base yourself on the following.

Note: You shouldn't use hashing methods such as anything from the SHA family or MD5 as the file name, since those produce the same hash and has no uniqueness to them.

Important: If people upload from a mobile device, most of them have "image.jpg" as the default name, so it needs to be renamed and given a unique method.

Using the date and time is one way. You can also add uniqid() to it by assigning a variable to it and append to the new file name, or a combination of MD5 and uniqid() is a good bet.

You will need to do a few modifications to it of course. The $year variable is something I used but you can get rid of those instances and replace them with your own.

$year = date("Y");
$pdf_file = $_FILES['fileToUpload']["name"];

$uploaded_date = date("Y-m-d_h-i-s_A"); // this could be another unique method.

$target_dir = "../upload_folder/" . $year . "/";

$ext = explode('.',$_FILES['fileToUpload']['name']);
$extension = $ext[1];

$newname = $ext[0].'_'.$uploaded_date;

$full_local_path = $target_dir.$newname.'.'.$extension;
$new_full_name = $newname.'.'.$extension;

    if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $full_local_path)) {
        echo "The file ". $newname . " has been uploaded.";
        echo "<hr>";

$file_link = "/upload_folder/$year/$new_full_name";

    // other code such as saving to a database...

    }
Community
  • 1
  • 1
Funk Forty Niner
  • 74,450
  • 15
  • 68
  • 141
  • Would everything make sense and be safe if I don't hash the images ? –  Jan 29 '18 at 01:01
  • @JacobsJohnson I don't see the need really to do that, unless you want to not let people know the original filename or its location. What social networks use are rewriting methods that hide the original filename and is a bit more complex. If you're looking for uniqueness, then rename the file as the hash, or use another hashing method and there are many and ones that don't require to fetch a file even before it's uploaded or exists. – Funk Forty Niner Jan 29 '18 at 01:05
  • Well I'll leave it how it is because there's no conflict . But thanks for your answer –  Jan 29 '18 at 01:12
  • @JacobsJohnson I've made an edit to the answer. Reload it and look under **Edit:**. Note that I didn't write it all out for you, I want you to learn from it. You will get success, just keep at it and concentrate. – Funk Forty Niner Jan 29 '18 at 12:22
  • Do I need to add the `$year` in my database ? –  Jan 29 '18 at 15:33
  • @JacobsJohnson That is up to you. What I posted was merely an example that you could implement if you want. – Funk Forty Niner Jan 29 '18 at 15:34
  • I'm getting an error on this line ` move_uploaded_file($file_tmp,"uploads/" . $year . .$file_name.);` –  Jan 29 '18 at 15:37
  • This error `Parse error: syntax error, unexpected '.' ` I know what it means but if I remove the `.$file_name.` wouldn't that be a problem ? –  Jan 29 '18 at 15:38
  • @JacobsJohnson I'd have to do a total rewrite and I don't have the time to do that right now; I'm right in the middle of something. Trial and error; use what you need and remove what isn't needed. The parse error comes probably from the missing `" "` in `$year . .$file_name`. or the extra dot. – Funk Forty Niner Jan 29 '18 at 15:43
  • Oh I got it . I removed the two dots in front and behind the `$file_name` –  Jan 29 '18 at 15:46
  • Ok so I have this now `$t=time();` and this `$info = date("Y-m-d,$t");` –  Jan 29 '18 at 16:18
  • And this `move_uploaded_file($file_tmp,"uploads/" . $info . $file_name);` –  Jan 29 '18 at 16:19
  • The image goes into the folder with the date and time and file name but in the db, it just has the name and not the time . How do I put the date and time into the db also ? No examples on YouTube helped me –  Jan 29 '18 at 16:30