Search code examples
phpfilefile-uploadstrpos

Attempt at running a condition based on file type using strpos


I am in the process of creating a condition. The condition is to check if any of the files are not basic image files (png, jpg, etc -- files shown in the condition) right away (in the if). If this is the case then the file_put_contents should run. If there are only basic image files being uploaded then the else should run.

As of now, the else never runs. For example, if I upload one file that is a .png the else statement should run.

When someone adds a file, I check the file type with $uploadedFileTypes = $fu->getImageFileTypes(); and then implode it to a list. This 100% works.

Here is an example of what I am wanting to happen:

If someone uploads two files - a .png and .stp, then the if should run. I am wanting the else to run only if the files being uploaded are the basic image files. Is there a better way to do this?

Then I am using the strpos function to check each type of image file I specified.

if (strpos($fileTypeString,$pdf) || strpos($fileTypeString,$jpg) || strpos($fileTypeString,$jpeg) || strpos($fileTypeString,$png) || strpos($fileTypeString,$gif) === false) {

Does anyone see what I am doing wrong?

$date = new DateTime();
$fu = new fileUpload();
$filename = $fu->upload();
$uploadedFileTypes = $fu->getImageFileTypes();
$fileTypeString = implode( ", ", $uploadedFileTypes );
$pdf = "pdf";
$jpg = "jpg";
$jpeg = "jpeg";
$png = "png";
$gif = "gif";
file_put_contents('file_type_log', "\n[{$date->format('Y-m-d H:i:s')}]" . print_r($uploadedFileTypes, true), FILE_APPEND);

foreach ($_FILES as $file) {
    foreach($file['name'] as $key => $value) {
        if (!empty($value)) { //empty string
            if ($file['error'][$key] != 4) {
                if (strpos($fileTypeString,$pdf) || strpos($fileTypeString,$jpg) || strpos($fileTypeString,$jpeg) || strpos($fileTypeString,$png) || strpos($fileTypeString,$gif) === false) {
                    file_put_contents('file_norm_log', "\n[{$date->format('Y-m-d H:i:s')}]" . print_r('There were other types of files uploaded', true), FILE_APPEND);
                } else {
                    $out = (count($filename) > 1 ? 'Multiple files were' : 'A file was'). '  uploaded. You can download ' . (count($filename) > 1 ? 'them' : 'the file'). ' from:</ul>';
                    foreach ($filename as $indFile) {
                        //print_r($template);
                        $out .= "<li><a href='/php/uploads/{$indFile}'>{$indFile}</a></li>";
                    }
                    $out .= '</ul>';
                    $template = str_replace("{filename}", $out, $template);
                }
            } else { //error code IS #4
                //echo "error code is 4";
            }
        } else {
            //echo "name is empty!";
            $template = str_replace("{filename}", '', $template);
        }
    }
}

Edit, New code with different approach:

$date = new DateTime();
$fu = new fileUpload();
$filename = $fu->upload();
$uploadedFileTypes = $fu->getImageFileTypes();
$fileTypeString = implode( ", ", $uploadedFileTypes);
$imageTypes = ["pdf","jpg", "jpeg", "png", "gif"];
$nonImgFiles = false;
$imgFiles = false;

if (!in_array($uploadedFileTypes, $imageTypes)) {
    $nonImgFiles = true;
}

if (in_array($uploadedFileTypes, $imageTypes)) {
    $imgFiles = true;
}

foreach ($_FILES as $file) {
    foreach($file['name'] as $key => $value) {
        if (!empty($value)) { //empty string
            if ($file['error'][$key] != 4) {        
                if ($nonImgFiles == true) {
                    file_put_contents('file_norm_log', "\n[{$date->format('Y-m-d H:i:s')}]" . print_r('There were other types of files uploaded', true), FILE_APPEND);
                } else {
                    }

Solution

  • You have to add === false to all the conditionals and change the operator to &&, like:

    if (
        strpos($fileTypeString,$pdf) === false && 
        strpos($fileTypeString,$jpg) === false && 
        strpos($fileTypeString,$jpeg) === false && 
        strpos($fileTypeString,$png) === false && 
        strpos($fileTypeString,$gif) === false
    ) {
        //do something    
    } else {
       //do something
    }
    

    But it seems that you can achieve that using less code in that if doing:

    $date = new DateTime();
    $fu = new fileUpload();
    $filename = $fu->upload();
    file_put_contents('file_type_log', "\n[{$date->format('Y-m-d H:i:s')}]" . print_r($uploadedFileTypes, true), FILE_APPEND);
    
    $extensions = ['pdf', 'jpg', 'jpeg', 'png', 'gif']; //an array with your extensions
    foreach ($_FILES as $file) {
        foreach($file['name'] as $key => $value) {
            if (!empty($value)) { //empty string
                if ($file['error'][$key] != 4) {
                    $fileData = pathinfo($file['name']); //explod file path to array
                    if (!in_array($fileData['extension'], $extensions)) { //if file extension not in your $extensions array
                        file_put_contents('file_norm_log', "\n[{$date->format('Y-m-d H:i:s')}]" . print_r('There were other types of files uploaded', true), FILE_APPEND);
                    } else {
                        $out = (count($filename) > 1 ? 'Multiple files were' : 'A file was'). '  uploaded. You can download ' . (count($filename) > 1 ? 'them' : 'the file'). ' from:</ul>';
                        foreach ($filename as $indFile) {
                            //print_r($template);
                            $out .= "<li><a href='/php/uploads/{$indFile}'>{$indFile}</a></li>";
                        }
                        $out .= '</ul>';
                        $template = str_replace("{filename}", $out, $template);
                    }
                } else { //error code IS #4
                    //echo "error code is 4";
                }
            } else {
                //echo "name is empty!";
                $template = str_replace("{filename}", '', $template);
            }
        }
    }
    

    EDIT:

    I reread your question. I believe you will need to remove the file extension checking outside the loop. Something like this would work:

    $date = new DateTime();
    $fu = new fileUpload();
    $filename = $fu->upload();
    $uploadedFileTypes = $fu->getImageFileTypes();
    
    file_put_contents('file_type_log', "\n[{$date->format('Y-m-d H:i:s')}]" . print_r($uploadedFileTypes, true), FILE_APPEND);
    
    //your per-file validation loop can go here
    
    $extensions = 'pdf', 'jpg', 'jpeg', 'png', 'gif'];
    
    //fill $differentExtensions with all $uploadedFileTypes elements that 
    //does not exist inside $extensions
    $differentExtensions = array_diff($uploadedFileTypes, $extensions);
    if (count($differentExtensions) > 0) {
        file_put_contents('file_norm_log', "\n[{$date->format('Y-m-d H:i:s')}]" . print_r('There were other types of files uploaded', true), FILE_APPEND);  
    } else {
        $out = (count($filename) > 1 ? 'Multiple files were' : 'A file was'). '  uploaded. You can download ' . (count($filename) > 1 ? 'them' : 'the file'). ' from:</ul>';
        foreach ($filename as $indFile) {
            //print_r($template);
            $out .= "<li><a href='/php/uploads/{$indFile}'>{$indFile}</a></li>";
        }
        $out .= '</ul>';
        $template = str_replace("{filename}", $out, $template);
    }
    
    //your per-file validation loop can go here
    

    The loop you are using to validate errors would be a separate code block. You could place it before or after the file extension checking, depending on what you need (I mentioned suggested places as comments in the code above):

    foreach ($_FILES as $file) {
        foreach($file['name'] as $key => $value) {
            if (empty($value)) {
                //echo "name is empty!";
                $template = str_replace("{filename}", '', $template);
            }
            if ($file['error'][$key] == 4) {
                //echo "error code is 4";
            }
        }
    }