#1
  1. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Location
    Iran
    Posts
    149
    Rep Power
    140

    Question A question about the move_uploaded_file function


    Dear all,

    OS: Fedora Core 17 (x86_64)
    Browser: Firefox 19.0
    PHP version: 5.4.11
    Apache version: 2.2.22
    I have a question about the move_uploaded_file function. Currently I'm reading the Chapter 9: Handling HTML Forms with PHP of a very interesting book named Beginning PHP 5.3 in order to learn how to upload files using forms.

    Here is the test scenario. We have a very simple form including just a file browser allowing to select an image file followed by a submit button for sending the image to the server (I'm working on my laptop, both client and the server are actually on the same physical machine).

    What I want to do is to let the user select an image from the local hard drive, submit it to the server and once received at the PHP server side, the image will be shown in the browser within an <img> element (it's just a first example for learning how to upload a file)

    The following code that I've written is not 100% complete and it lacks some additional tests such as verifying the uploaded file type, the length of the file name, etc. But it is normally (I think) enough at least for a file upload. So here is what I have written so far
    Code:
    <!doctype html>
        <head>
            <title>MyPHPScript</title>
            <meta charset="UTF-8">
        </head>
        <body>
            <?php
                /* If the user has already pushed
                 * the submit button, just show
                 * the submitted image in the browser
                 * by calling the printImage() function
                 */
                if (array_key_exists("submit", $_POST))
                    printImage();
                else
                    homePage();
            ?>
            
            <?php
                function homePage()
                {
            ?>
                    <!--
                        * So here is the form that I use to
                        * upload an image. It's very simple
                        * just a file browser and a submit
                        * button to send the image
                    -->
                    <form action="myscript.php" method="post" 
                        enctype="multipart/form-data">
                        <label for="fileBrowser">Image file</label>
                        <input type="file" name="fileBrowser" id="fileBrowser"
                            value=""/>
                        <input type="submit" name="submit" id="submit" 
                            value="submit"/>
                    </form>
            <?php
                }
            ?>
            
            
            <?php
                function printImage()
                {
                    /*
                     * So here I check whether the file
                     * was uploaded successfully. If it
                     * is the case, then I move the file
                     * from the PHP tmp directory to a 
                     * directory named "images" in the 
                     * DOCUMENT_ROOT. And finally I will
                     * show the image by <img> within
                     * the browser
                     */
                    if (array_key_exists("fileBrowser", $_FILES))
                    {
                        switch ($_FILES["fileBrowser"]["error"])
                        {
                            case UPLOAD_ERR_OK:
                            {
                                $fileInfo = $_FILES["fileBrowser"];
                                $fileName = $fileInfo["name"];
                                $filePath = $fileInfo["tmp_name"];
                                $fileAbsPath = $filePath . "/" . $fileName;
                                $destPath =  $_SERVER["DOCUMENT_ROOT"] . 
                                    "/images/" . $fileName;
                                if (move_uploaded_file($fileAbsPath, $destPath)) 
                                    echo "Ok the file was successfully moved";
                                else
                                    echo "No the file was not moved";
                                break;
                            }
                            case UPLOAD_ERR_INI_SIZE:
                            case UPLOAD_ERR_FORM_SIZE:
                            {
                                echo "The file is too big";
                                break;
                            }
                            case UPLOAD_ERR_NO_FILE:
                            {
                                echo "no file was uploaded";
                                break;
                            }
                            case UPLOAD_ERR_NO_TMP_DIR:
                            {
                                echo "Permission denied: no access to tmp dir";
                                break;
                            }
                            case UPLOAD_ERR_CANT_WRITE:
                            {
                                echo "File cannot be written on server HDD";
                                break;
                            }
                            case UPLOAD_ERR_EXTENSION:
                            {
                                echo "File upload stopeed by one of ".
                                    "PHP extensions";
                                break;
                            }
                            default:
                                echo "Please contact the administrator";
                        }
                    }
                    else
                        echo "no file was uploaded";
            ?>
                    <img src="<?php echo "$destPath"; ?>">
            <?php
                }
            ?>
              
        </body>
    </html>
    According to what I checked in the switch statement, case UPLOAD_ERR_OK is executed when I upload the file but move_uploaded_file() returns False and I don't understand why. Under Linux I gave all privileges on the images/ directory (chmod -R 777 images/) so I don't think there is a privilege problem.

    Also I checked the following directives from the output of php info:

    - file_uploads : On
    - max_file_uploads : 20
    - upload_max_filesize: 2M
    - upload_tmp_dir: No value


    upload_tmp_dir has no value, but then I checked the online documentation about this directive and here is what I found:
    http://www.php.net/manual/en/ini.core.php#ini.upload-tmp-dir
    ... The temporary directory used for storing files when doing file upload. Must be writable by whatever user PHP is running as. If not specified PHP will use the system's default. ...
    Consequently, albeit not specified, PHP takes the default system tmp dire, which in the case of linux as I understand is /tmp.

    There is also something that I found strange, as you can see I query the following information in my code
    Code:
    . . . 
    $fileInfo = $_FILES["fileBrowser"];
    $fileName = $fileInfo["name"];
    $filePath = $fileInfo["tmp_name"];
    $fileAbsPath = $filePath . "/" . $fileName;
    $destPath =  $_SERVER["DOCUMENT_ROOT"]
    . . .
    Just for some debugging I did some echo within my code on these variables just to see whether they return something. However there is something strange:

    - $fileInfo["tmp_name"] returns the path to the directory inluding the file and not the absolute path to the file (that is, the absolute path of the file without the filename)

    - Once the PHP script is run, if I open a linux terminal and try to see the content of the directory returned by $fileInfo["tmp_name"], there is nothing there.

    I'm really confused.

    Could you kindly make some clarification?


    Regards,
    Dariyoosh
  2. #2
  3. No Profile Picture
    Lost in code
    Devshed Supreme Being (6500+ posts)

    Join Date
    Dec 2004
    Posts
    8,316
    Rep Power
    7170
    $fileInfo['tmp_name'] contains the absolute path to the file, appending $fileInfo['name'] to it isn't correct. move_uploaded_file should receive $fileInfo['tmp_name'] directly as its first argument.
    PHP FAQ

    Originally Posted by Spad
    Ah USB, the only rectangular connector where you have to make 3 attempts before you get it the right way around
  4. #3
  5. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Location
    Iran
    Posts
    149
    Rep Power
    140
    Well, this is one of the strange things that happen. Because as you said and also according to the book, _FILES[". . ."]["tmp_name"] return the absolute path to the file (image file in the case of my program). Yet when I write the following in my program:
    Code:
    $fileInfo = $_FILES["fileBrowser"];
    echo $fileInfo["tmp_name"];
    I got a strange directory name inside the /tmp (each time that I run the script, this strange name changes)
    Code:
    /tmp/phpjWlf32
    So the very fact that it doesn't give me the absolute path (unlike what has been spcecified in PHP specification) is not normal, could this be related to php.ini?

    Thanks,

    Regards,
    Dariyoosh
  6. #4
  7. --
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Jul 2012
    Posts
    3,959
    Rep Power
    1014
    Hi,

    Originally Posted by dariyoosh
    So the very fact that it doesn't give me the absolute path (unlike what has been spcecified in PHP specification) is not normal, could this be related to php.ini?
    This is an absolute path. It's a file called "phpjWlf32" in the "tmp" directory below the root directory. What else did you expect? A Windows-style path like "C:\php\tmp\upload.jpg"?

    The file name is chosen randomly, because taking the user-defined name would obviously a bad idea -- you'd get collisions all the time. PHP also doesn't append the user-defined file extension

    You should actually be very careful with where you put those files. As far as I can I see, you just move them into the document root. That's a bad idea, because people can then upload their own PHP scripts and execute them -- pretty much the worst case scenario. Google for "secure file upload" to avoid typical mistakes.
    The 6 worst sins of security ē How to (properly) access a MySQL database with PHP

    Why canít I use certain words like "drop" as part of my Security Question answers?
    There are certain words used by hackers to try to gain access to systems and manipulate data; therefore, the following words are restricted: "select," "delete," "update," "insert," "drop" and "null".

IMN logo majestic logo threadwatch logo seochat tools logo