0

I'm trying to upload two images in one form using ajax and php. I'm using FormData to get the form's information, which works fine. This is the HTML:

<form enctype="multipart/form-data">
    <input type="file" name="file[]" class="file">
    <input type="file" name="file[]" class="file">
    <button type="submit">Submit</button>
</form>

and here's the javascript code:

var form = document.querySelector('form');

$("form").on("submit", function(e) {

    e.preventDefault();

    var formdata = new FormData(form);

    $.ajax({
        url: 'double_image_upload_response.php',
        type: 'POST',
        data: formdata,
        cache: false,
        contentType: false,
        processData: false,
        success: function(data) {
            console.log(data);
        },
        error: function(requestObject, error, errorThrown) {
            console.log(error);
            console.log(errorThrown);
        }
    });
});

On the server side in PHP, I'm using this to get the names of the files:

$files = $_FILES['file']['name'];

and this works fine. So, for example, if I had two files, one named "tree.jpg" and the other named "orange.jpg", I would get the names in that form within an array, which is good. To get the names out of the array, I use a foreach loop:

foreach($files as $names) {

    echo $names;

}

This gives me the values "tree.jpg" and "orange.jpg" outside of the array. However, when I try to check if the extensions are valid, I have trouble. Using this php array containing the valid image extensions:

$allowed = ['image/pjpeg', 'image/jpeg', 'image/JPG', 'image/X-PNG', 'image/PNG', 'image/png', 'image/x-png'];

I then add some code to the inside of the foreach loop I just showed, resulting in this:

foreach($files as $names) {

    if (in_array($names, $allowed)) {
        echo "Valid image extension";
    } else {
        echo "Invalid image extension";
    }

}

and it keeps echoing out "Invalid image extension", but I don't know why. I already tried using the explode() and end() functions to get the extension and compare that to the $allowed array, without luck. I also tried the array_search function, which didn't work, either. Any ideas?

`

2
  • you comparing apples to oranges, file names to mime types Commented Aug 22, 2019 at 22:30
  • your $allowed array does not contain file extensions, but mime types. They are different. Commented Aug 22, 2019 at 22:31

4 Answers 4

2

Since the file extension can be modified by the end-user, you can't rely on it in terms of verifying the file type of an uploaded file. You really need to check the actual content type, which you can do with mime_content_type. To use that, you need the uploaded file name, which is in $_FILES['file']['tmp_name'][]. You can use something like this:

$allowed = ['image/pjpeg', 'image/jpeg', 'image/JPG', 'image/X-PNG', 'image/PNG', 'image/png', 'image/x-png'];
foreach ($_FILES['file']['tmp_name'] as $name) {
    $mime_type = mime_conent_type($name);
    if (!in_array($mime_type, $allowed)) {
        echo "File type is valid";
    }
    else {
        echo "File type is invalid!";
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

@CarsonD no worries. I typically also include a check that I can call imagecreatefromjpeg (or other imagecreatefrom* routine as appropriate to the mime type) successfully on the input file.
0

As mentioned by the commenters, your $allowed array contains a list of valid mime-types, not extensions. You must decide what you want to use to check the validity of the file.

If you decide to go with the pure file extension, then in the loop you must also extract the extension, and compare that to a new list, one that contains expected valid extensions. Something like this:

$files = ['orange.jpg', 'apple.jpeg'];
$allowed  = ['jpg', 'jpeg', 'png', 'gif'];

foreach($files as $names) {
    $pathinfo = pathinfo($names);  /* split path in its components */
    $extension = strtolower($pathinfo['extension']);  /* extract the extension and normalize to lowercase */

    if (in_array($extension, $allowed)) {
        echo "Valid image extension";
    } else {
        echo "Invalid image extension";
    }
}

Comments

0

You are comparing filenames like "tree.jpg" , "orange.jpg" with mime type 'image/pjpeg', 'image/jpeg'. Get the file extension using following function.then compare with required file extension in array.

$ext = pathinfo($filename, PATHINFO_EXTENSION);
$allowed = ['pjpeg', 'jpeg',...]

Comments

0

If you want to rely on the client file type which is not secure, you can do it like this,

$file_types = $_FILES["file"]["type"];
if (in_array($names, $allowed)) {
    echo "Valid image extension";
} else {
    echo "Invalid image extension";
}

But you'd better not do it.

Refer to PHP File Type Restrictions and Laravel: Form file uploads failing - incorrect type detected

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.