phpapachefile-uploadbroken-image

PHP file upload results in broken files on Windows Apache server


I have written a file upload script for PHP. I'm testing on a Windows Apache server, but it will finaly have to work on a CentOS server with Apache. Because I am still debugging, I haven't tested it on the live linux machine. Have Googled it, but can't find a good solution.

What happens? When I upload a .png or .jp(e)g file, everything is going well. The script moves my file to the right dir, but then output a non readable file. Check the image below. My upload part of the script:

if ($posting_photo === true) {
    $uploaded_file = $_FILES['review_photo'];
    $uploaded_file['ext'] = explode('.', $uploaded_file['name']);

    //Only continue if a file was uploaded with a name and an extension
    if ((!empty($uploaded_file['name'])) && (is_array($uploaded_file['ext']))) {
        $uploaded_file['ext'] = secure(strtolower(end($uploaded_file['ext'])));
        $upload_session = secure($_COOKIE[COOKIE_NAME_POST_REVIEW_SESSION]);
        $upload_dir = realpath(getcwd() . DIR_REVIEW_IMAGES) . DIRECTORY_SEPARATOR . $upload_session . DIRECTORY_SEPARATOR;
        $upload_ext = array('jpg', 'jpeg', 'png');

        //Only continue if a file was uploaded in a right way
        if (($uploaded_file['error'] == 0) && ($uploaded_file['size'] > 0) && ($uploaded_file['size'] <= MAX_FILESIZE_REVIEW_PHOTO_BYTES) && (in_array($uploaded_file['ext'], $upload_ext))) {

            //Check if upload dir already exists. If so, there will be probably files in it. So we check for that too. If not, we can start with the first file.
            if (is_dir($upload_dir)) {
                //
                //
                //Part where a new file name gets generated. Not very interesting and it works well, so I left it out on Stack Overflow
                //
                //


            } else {
                mkdir($upload_dir, 0777, true);
                $upload_name = $upload_session . '-1.' . $uploaded_file['ext'];

            }


            //Check if new upload name was generated. If not, something is wrong and we will not continue
            if (!empty($upload_name)) {
                chmod($upload_dir, 0777);

                if (move_uploaded_file($uploaded_file['tmp_name'], $upload_dir . $upload_name)) {
                    $files = array_diff(@scandir($upload_dir), array('.', '..'));

                    //Change slashes on Windows machines for showing the image later
                    $upload_dir = str_replace('\\', '/', $upload_dir);


                }

            }

        }

    }

}

All variables not initialized here are initialized earlier. The cookie is set and checked before, and is used for unique directory and file names. Check this image for the output file. The x leftunder is from Dropbox (Dropbox says: Can't sync ... access denied). The Photo Viewer window says: Cannot open this picture becasue you have no access to the file location. Viewing the file in the browser results in a permission denied. Link to image

Who is familiar with this problem and/or knows a solution? Hope you can help me out here!


Solution

  • Had this once too. It's a bug in PHP 5.3.x. After upgrading from 5.3.3 to 5.6 the problems were gone!