0

I am reading "Head first PHP book" and stumbled at chapter 5 where file upload is implmented. I did it on XAMPP on windows 7. The path to the file is the following:

htdocs-->chapter5-->form.php

Here is my simplified version of the original code.

<html>
   <head>
       <title>Guitar Wars - Add Your High Score</title>
       <link rel="stylesheet" type="text/css" href="style.css" />
   <head>
   <body>
      <?php
        if (isset($_POST['submit'])) 
        {
            // Grab the score data from the POST
            $name = $_POST['name'];
            $score = $_POST['score'];
            $screenshot=$_FILES['screenshot']['name'];
            if (!empty($name) && !empty($score) && !empty($screenshot)) 
            {
              // Connect to the database
              $dbc = mysqli_connect('localhost', 'root', '') or die("could not connect to the database");
              mysqli_select_db($dbc, "store") or die("could not choose the database");
              move_uploaded_file($_FILES['screenshot']['tmp_name'], $_SERVER['DOCUMENT_ROOT'].'/image/.$screenshot') or die("problem uploading");
            // Write the data to the database
              $query = "INSERT INTO scores VALUES (0, NOW(), '$name', '$score', '$screenshot')";
              mysqli_query($dbc, $query) or mysqli_errno();//die ("could not create record");
              // Confirm success with the user
              echo '<p>Thanks for adding your new high score!</p>';
              echo '<p><strong>Name:</strong> ' . $name . '<br />';
              echo '<strong>Score:</strong> ' . $score . '</p>';
              echo '<p><a href="index.php">&lt;&lt; Back to high scores</a></p>';
              // Clear the score data to clear the form
              $name = "";
              $score = "";
              mysqli_close($dbc);
           }
         else 
        {
                echo '<p class="error">Please enter all of the information to add your high score.</p>';
        }
    }
?>
 <hr />

    <h2>Guitar Wars - Add Your High Score</h2>
    <form enctype="multipart/form-data" method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
           <input type="hidden" name="MAX_FILE_SIZE" value="32768">   
           <label for="name">Name:</label>
           <input type="text" id="name" name="name" value="<?php if (!empty($name)) echo $name; ?>" /><br />
           <label for="score">Score:</label>
           <input type="text" id="score" name="score" value="<?php if (!empty($score)) echo $score; ?>" />
 <br />
           <label for="screenshot">Screenshot:</label> <input type="file" id="screenshot" name="screenshot"> <hr/>          
           <input type="submit" value="Add" name="submit" />
   </form>
</body>

The whole idea is the following. User enters his name and score and selects file for upload via self-submitting html form:

    <form enctype="multipart/form-data" method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
           <input type="hidden" name="MAX_FILE_SIZE" value="32768">   
           <label for="name">Name:</label>
           <input type="text" id="name" name="name" value="<?php if (!empty($name)) echo $name; ?>" /><br />
           <label for="score">Score:</label>
           <input type="text" id="score" name="score" value="<?php if (!empty($score)) echo $score; ?>" />
 <br />
           <label for="screenshot">Screenshot:</label> <input type="file" id="screenshot" name="screenshot"> <hr/>          
           <input type="submit" value="Add" name="submit" />
   </form>

then the data is processed by php script in the same file:

 <?php
    if (isset($_POST['submit'])) 
    {
        // Grab the score data from the POST
        $name = $_POST['name'];
        $score = $_POST['score'];
        $screenshot=$_FILES['screenshot']['name'];
        if (!empty($name) && !empty($score) && !empty($screenshot)) 
        {
          // Connect to the database
          $dbc = mysqli_connect('localhost', 'root', '') or die("could not connect to the database");
          mysqli_select_db($dbc, "store") or die("could not choose the database");
          move_uploaded_file($_FILES['screenshot']['tmp_name'], $_SERVER['DOCUMENT_ROOT'].'/image/.$screenshot') or die("problem uploading");
        // Write the data to the database
          $query = "INSERT INTO scores VALUES (0, NOW(), '$name', '$score', '$screenshot')";
          mysqli_query($dbc, $query) or mysqli_errno();//die ("could not create record");
          // Confirm success with the user
          echo '<p>Thanks for adding your new high score!</p>';
          echo '<p><strong>Name:</strong> ' . $name . '<br />';
          echo '<strong>Score:</strong> ' . $score . '</p>';
          echo '<p><a href="index.php">&lt;&lt; Back to high scores</a></p>';
          // Clear the score data to clear the form
          $name = "";
          $score = "";
          mysqli_close($dbc);
       }
     else 
    {
            echo '<p class="error">Please enter all of the information to add your high score.</p>';
    }
}
?>

When i try to submit the form for processig the message is

   problem uploading

which suggests that move_uploaded file failed. What i did are the following:

  1. Chagged permission of the entire htdocs folder - did not work.

  2. Created image folder within the chapter5 directory and changed its permission it did not work. I.e. created directory image as

      htdocs-->chapter5-->image
    

    and changed permissions of the directory. then I called move_uploaded_file as

      move_uploaded_file($_FILES['screenshot']['tmp_name'], 
     '/image/.$screenshot') or die("problem uploading");
    

    this approach did not work

  3. Created image directory in the htdocs directory and tried the following call

    move_uploaded_file($_FILES['screenshot']['tmp_name'], $_SERVER['DOCUMENT_ROOT'].'/image/.$screenshot') or die("problem uploading"); 
    

every time i have

    probem uploading

text written on the page after form submission. I looked at file_upload record in the php.ini file everyhting seem fine:

    ; Temporary directory for HTTP uploaded files (will use system default if not
    ; specified).
    ; http://php.net/upload-tmp-dir
      upload_tmp_dir="C:\xampp1\tmp"

    ; Maximum allowed size for uploaded files.
    ; http://php.net/upload-max-filesize
      upload_max_filesize=40M

    ; Maximum number of files that can be uploaded via a single request
    max_file_uploads=2

I also changed the permmision of 'C:\xampp1\tmp'

Nothing worked. Can anybody suggest what am i doing wrong?

olzha bala
  • 177
  • 1
  • 5
  • 13

2 Answers2

1

First things first, turn on error reporting so you can see the actual error/warning that is happening - How do I get PHP errors to display?

I ran your code and it works if the destination directory actually exists. One approach to ensuring that it exists is to create the directory on the fly.

Not sure if this is the right location for you, but using ./image/ will create the image in the directory where your script is executing. You can play around with $destinationDirectory until you get your desired location and it should continue to work.

<?php

ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

...
if (!empty($name) && !empty($score) && !empty($screenshot)) {

    $destinationDirectory = './image/';

    // Check if the destination is a directory. If not, create it. 
    if (!is_dir($destinationDirectory) && !mkdir($destinationDirectory)) {
        die("Error creating folder $destinationDirectory");
    }

    $finalPath = $destinationDirectory . $screenshot;

    if (!move_uploaded_file($_FILES['screenshot']['tmp_name'], $finalPath)) {
        die("problem uploading");
    }

    ...

'/image/.$screenshot' likely should be '/image/'.$screenshot

@waterloomatt, yes, this is just typo

You should edit your question with the real code then otherwise, it will throw people off.

And final note - $query = "INSERT INTO scores VALUES (0, NOW(), '$name', '$score', '$screenshot')"; This code is fully susceptiable to SQL injection because you're passing user supplied data directly to your database. Look into prepared statements - https://phpdelusions.net/pdo#prepared

waterloomatt
  • 3,134
  • 1
  • 16
  • 21
0

The solution was pretty obvious. I created simple form.html file and separate form.php form handler. When 2 are separate then everything works fine. When the form is self-submitting it gave me error messages. Looks like this is related to form submission.

olzha bala
  • 177
  • 1
  • 5
  • 13