Search code examples
phpuploadimage-uploading

PHP - Frequent error on multiple images upload



I created a multiple image upload form (the images are stored in a folder, and the informations in a MySQL database). To the images are associated some informations, like a description, a name, etc.
Often, when I upload many images (like 3,4), one/two of them aren't uploaded, and an error message appears (An error has occurred while uploading the file). Then, if I retry to upload the image not uploaded, no error occurs. Sometimes it appends, sometimes not, and I don't understand what the problem is (I think it is not normal).
Here you can see my PHP code and also my HTML form:


When the user clicks on the input type="file", my code just creates another input and hides the old one (so that, if the user wants upload more files, those already uploaded are not deleted).

function boomFunction(obj) {
            obj.style.display = 'none';
            $(".upload-container").append("<input name='upload[]' type='file' multiple='multiple' id='upload' class='upload' onclick='boomFunction(this)' title='Carica un altro file!'>");
         }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form action="result.php" method="post" enctype="multipart/form-data" class="form-inline" autocomplete="off" novalidate>          
            <div class="upload-container">
              <input name="upload[]" type="file" multiple="multiple" id="upload" class="upload" required="required" aria-required="true" onclick="boomFunction(this)" title="Choose a file!">
            </div><br>
            
            <label>Subjects:</label>
            <textarea type="text" id="argomenti" name="argomenti" required="required" aria-required="true" placeholder="Subjects..."></textarea><br>
                
            <label for="anno">Year:</label>
            <select id="anno" name="anno" required="required" aria-required="true">
                <option value="" disabled selected>Choose year</option>
                <option value="2016-2017">2016-2017</option>
                <option value="2017-2018">2017-2018</option>
                <option value="2018-2019">2018-2019</option>
            </select><br>
            
            <input type="submit" value="Carica i file" class="upload_button"><br><br><br>
               
</form>



Then, here is my result.php page.

<?php
                    $total = count(array_filter($_FILES['upload']['name'])); // Count the number of uploaded files
                    $timestamp = time();
                    if ($total==0) {
                        echo "<h2>You must upload at least one file.</h2>";
                        $uploadOk = 0;
                    } else {
                        for($i = 0; $i < $total; $i++) {
                            $tmpFilePath = $_FILES['upload']['tmp_name'][$i];
                            if ($tmpFilePath != '') {
                                $newFilePath = "./uploadFiles/" . $_FILES['upload']['name'][$i];
                                $nomeCompletoFile = basename($_FILES["upload"]["name"][$i]);
                                $target_file = "uploads/$nomeCompletoFile"; $uploadOk = 1;
                                $estensione = strtolower(pathinfo($target_file, PATHINFO_EXTENSION));
                                if($estensione != 'jpg' && $estensione != 'png' && $estensione != 'jpeg') {
                                    echo "<h2>Just JPG e PNG files are allowed.</h2>";
                                    $uploadOk = 0;
                                }
                                elseif (empty($_POST["argomenti"]) or empty($_POST["anno"])) {
                                    echo "<h2>You cannot leave empty fields</h2>";
                                    $uploadOk = 0;
                                } else {
                                    $nomeFile = str_replace(".$estensione", '', $nomeCompletoFile);
                                    $string = base64_encode(openssl_random_pseudo_bytes(15)); // Random 15 letters for the new file name
                                    $id = rand(1, 100000); $nomeFinaleFile = 'uploads/'.$string.$id.'.'.$estensione;
                                    if (move_uploaded_file($_FILES["upload"]["tmp_name"][$i], $nomeFinaleFile)) {
                                        $argomenti = stripslashes(htmlspecialchars($_POST['argomenti']));
                                        $anno = $_POST['anno'];
                                        $mysqli = new mysqli('localhost', 'name', '', 'my_name');
                                        $mysqli->query("INSERT INTO uploads (timestamp, file, argomenti, anno, nFile) VALUES ('$timestamp', '$nomeFinaleFile', '$argomenti', '$anno', '$i')");
                                          echo "<h2>The file <i>$nomeFile</i> has been uploaded.</h2>";
                                    } else echo "<h2>An error has occurred while uploading the file</h2>";
                                }
                            }
                        }
                    }
                ?>



There seems to be no mistakes, indeed sometimes all works correctly.
Any help will be appreciated


Solution

  • Use base64encode url safe

    replace

    $string = base64_encode(openssl_random_pseudo_bytes(15)); // Random 15 letters for the new file name
    

    to

    $string = rtrim(strtr(base64_encode(openssl_random_pseudo_bytes(15)), ['+' => '-', '/' => '_']), '=');