1


My website allows the user to upload an album of images to their profile and share them with others on the site.
The script is broken down into two files:

uploadAnAlbum.php

<?php
session_start();
set_time_limit (0);
$email = $_SESSION["accountEmailAddress"];
$accountDir = str_replace("@", "at", $email);
$accountDir = str_replace(".", "dot", $accountDir);
$folderStructure = "./albums/" . $accountDir . "/" . round(microtime(true));
$folderCreation = mkdir($folderStructure, 0755, true);
$host = "localhost";
$username = "XXXXXX";
$password = "XXXXXX";
$database = "XXXXXX";
$connection = mysql_connect($host, $username, $password) or die(mysql_error() . "connection");
  mysql_select_db($database) or die(mysql_error() . "database");
$tableName = $accountDir . round(microtime(true));
$createTable = "CREATE TABLE `" . $tableName . "` (
    `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
    `path` TEXT DEFAULT NULL
    ) ENGINE = MYISAM;";
$createTableResult = mysql_query($createTable) or die(mysql_error() . "sql<br>" . mysql_errno());
echo "<h1>" . count($_FILES['files']['name']) . "</h1>";
$count = 0;
foreach ($_FILES['files']['name'] as $i => $name) {
    if (strlen($_FILES['files']['name'][$i]) > 1 && getimagesize($_FILES['files']['tmp_name'][$i]) !== false) {
        $extensionArray = explode(".", $_FILES["files"]["name"][$i]);
        $extension = end($extensionArray);
        $newfilename = $count . '.' . $extension;
        if (move_uploaded_file($_FILES['files']['tmp_name'][$i], $folderStructure . "/" . $newfilename)) {
            $photoPath = $folderStructure . "/" . $newfilename;
            $sql = "INSERT INTO `" . $tableName . "` (path) VALUES ('$photoPath')";
            $result = mysql_query($sql) or die(mysql_error() . "hhh");
            $count = $count + 1;
        }//MOVES INDEX TO FOLDER; UPDATES $COUNT
    } else {  //CHECK IF FILE IS REAL BEFORE MOVING INTO DIRECTORY
        continue;
    }
    echo $count;
}//END FOREACH ITERATING ARRAY OF UPLOADED FILES
$name = $_REQUEST['albumName'];
$author = $_SESSION['accountEmailAddress'];
$date = date("y/m/d");
$teams = $_REQUEST['teamOne'] . "," . $_REQUEST['teamTwo'];
if($_SESSION['accountStatus'] == "pro"){
    $proOrNo = "pro";
} else {
    $proOrNo = "no";
}
$sport = $_REQUEST['sport'];
$path = $tableName;
$views = 0;
$host = "XXXXXX";
$username = "XXXXXX";
$password = "XXXXXX";
$database = "XXXXXX";
$connection = mysql_connect($host, $username, $password);
mysql_select_db($database);
$sql = "INSERT INTO albums (name, author, dateUploaded, teams, sport, views, path, proOrNo) VALUES ('$name', '$author', '$date', '$teams', '$sport', '$views', '$path', '$proOrNo')";
$result = mysql_query($sql) or die(mysql_error() . "nn");
header("Location: myAccount.php");
?>

chooseFile.php (HTML form)

    <form action="uploadAlbum.php" method="post" enctype="multipart/form-data">
  Choose album:<br>
      <input type="file" name="files[]" id="files" multiple="" directory="" webkitdirectory="" mozdirectory=""><br>
      Name:<input type="text" name="albumName" style="width:100%;"/><br><br>
      Sport:
      <select name="sport">
                <option name="nothing">Select</option>
                <option name="football">Football</option>
                <option name="crossCountry">Cross country</option>
                <option name="fieldHockey">Field hockey</option>
                <option name="golf">Golf</option>
                <option name="gymnastics">Gymnastics</option>
                <option name="soccer">Soccer</option>
                <option name="softball">Softball</option>
                <option name="tennis">Tennnis</option>
                <option name="volleyball">Volleyball</option>
                <option name="basketball">Basketball</option>
                <option name="hockey">Hockey</option>
                <option name="swimming">Swimming</option>
                <option name="wrestling">Wrestling</option>
                <option name="baseball">Baseball</option>
                <option name="lacrosse">Lacrosse</option>
                <option name="track">Track and field</option>
        </select><br><br>
      Teams competing: <br>
            <select name="teamOne">
              <option value="empty">Choose school #1</option>
              <!-- Lots and lots of options for school districts. I took them out to eliminated needless scrolling while you are reading this -->
            </select>
            <select name="teamTwo">
              <option value="empty">Choose school #2</option>
              <!-- Lots and lots of options for school districts. I took them out to eliminated needless scrolling while you are reading this -->
            </select>
              <br>
      <input type="submit" name="submit" value="Upload album" />
  </form>

For some reason, only 20 indexes of the $_FILES array are passing from the html input form to the php upload script. Before any code manipulating the photos on uploadAnAlbum.php is run, I can see the $_FILES array (passed from chooseFile.php) is limited to the first 20 photos in the user's uploaded directory.
I have spoke on the phone with my web hosting company for three hours and configured the php.ini to be accepting of very large files no matter the upload time.
I have still gotten no where.
If you could take a look at this code to see if anything jumps out at you I would greatly appreciate it.

2 Answers2

2

Check the max_file_uploads setting in your php.ini file. No matter what the file sizes are, your scripts will not receive more than the number of files specified in max_file_uploads. The default setting is 20, so that's almost certainly your problem.

Related points:

  • Please don't use mysql_*; the mysql_* functions are outdated, deprecated, and insecure. Use MySQLi or PDO instead.
  • You are wide open to SQL injection. You need to use prepared statements.
  • Before you go much further with this, you really should consider breaking your code apart to separate functions (business logic, database interactions, display logic including redirect headers). You are at risk of creating "spaghetti code" by putting multiple types of code in one file. I'd recommend checking out PHP The Right Way.
Community
  • 1
  • 1
elixenide
  • 44,308
  • 16
  • 74
  • 100
  • Thanks a lot for the help Ed. I will be sure to tighten up the security issues. The php.ini max_file_uploads setting has already been adjusted to allow more than 20 files. This seems to be an issue of file count, not size, as it is the first 20 files passed regardless of their size. – Nick Pitoniak Sep 29 '15 at 15:36
  • Also, how would you suggest to prepare the statements? I plan on passing everything through mysql_real_escape_string() before inserting it into the database. Would this be secure enough in your opinion? Thanks – Nick Pitoniak Sep 29 '15 at 15:38
  • Are you sure the *`max_file_uploads`* setting is higher than 20? You mention talking to your hosting company about file sizes; that's a very different issue. – elixenide Sep 29 '15 at 15:38
  • No, using `mysql_real_escape_string()` is not enough. First, there are some theoretical ways around that that can still lead to injection. Second, using that requires you to be *perfect* about it and never miss escaping anything; this is harder than it sounds as your code grows in complexity. Third, and most important, the `mysql_*` functions are all deprecated and should not be used at all. Use a modern library, instead. – elixenide Sep 29 '15 at 15:39
  • Customer support guided me through changing all of the php.ini settings to 'allow maximum files of any size to be uploaded'. I think I remember modifying max_file_uploads, however I will check and get back to you once I get home from school. – Nick Pitoniak Sep 29 '15 at 15:41
  • Definitely double-check that. The default value of `max_file_uploads` is 20, and it is not one of the things you would change just to allow larger files to be uploaded. – elixenide Sep 29 '15 at 15:42
2

First check this param in the php.ini file its default is 20

max_file_uploads = 20

Now you need to make sure that this equation works

post_max_size = ( upload_max_filesize * max_file_uploads ) + 
                    space for normal fields passed in the POST buffer

In other words, you can upload maximum number of files all of the maximum file size as well as providing space for all the normal field on a form.

RiggsFolly
  • 93,638
  • 21
  • 103
  • 149