Kenneth .J
Kenneth .J

Reputation: 1433

Why does mkdir not work without recursion set to true?

I was fiddling with my code, trying to write some code that will take data(including pictures) uploaded from a form via POST which will then create a directory complete with its associated subdirectories to store the image.

While writing the code, i kept getting the error

Warning: mkdir(): No such file or directory in C:\Users\Admin\Desktop\UniServer\www\AddItem.php on line 94

HOWEVER, when i set mkdir's resursion to true, mkdir suddenly works and the directory is created without any problems.

My Code:

if(isset($_FILES['upload']['tmp_name']))
 {
 $numfile=count($_FILES['upload']['tmp_name']);
{
    for($i=0;$i<$numfile;$i++)
    {
        if(is_uploaded_file($_FILES['upload']['tmp_name'][$i]))
        {
            //Conditionals for uploaded file
            $foldername=$_SESSION['UserId'];
            $cat=$_POST['category'];
            $sub=$_POST['subcat'];
            $itemname=$_POST['itemname'];
            $allowed_filetypes=array('.jpg','.gif','.bmp','.png');
            $max_filesize = 2097152; // Maximum filesize in BYTES (currently 2.0MB).
            $upload_path = 'C:\Users\Admin\Desktop\UniServer\www\images\\'.$foldername.'\\'.$cat.'\\'.$sub.'\\'.$itemname.'\\'; // The place the files will be uploaded to.
            //Checks if Folder for User exists
            //If not, A folder for the user is created to store the user's images
            if(!file_exists($upload_path))
            {
                $upload_path=mkdir($upload_path,0644,true);<-- This is the line
            }

            $filename = $_FILES['upload']['name'][$i]; // Get the name of the file (including file extension).
            $ext = substr($filename, strpos($filename,'.'), strlen($filename)-1); // Get the extension from the filename.

            // Check if the filetype is allowed, if not DIE and inform the user.
            if(!in_array($ext,$allowed_filetypes))
            {
                die('The file you attempted to upload is not allowed.');
            }

            // Now check the filesize, if it is too large then DIE and inform the user.
            if(filesize($_FILES['upload']['tmp_name'][$i]) > $max_filesize)
            {
                die('The file you attempted to upload is too large.');
            }

            // Check if we can upload to the specified path, if not DIE and inform the user.
            if(!is_writable($upload_path))
            {
                $errormsg="Image Upload Failed.";
            }

            if(!move_uploaded_file($_FILES['upload']['tmp_name'][$i],"$upload_path" . $filename))
            {
                $errormsg= 'Your file upload was successful, view the file <a href="' . $upload_path . $filename . '" title="Your File">here</a>'; // It worked.
            }

        }
    }
}




 }
   else{echo"Upload failed";}

While my code is working now that i've set recursion to true, i still DON't understand exactly WHY it is working, so i would really appreciate it if someone could explain why exactly my code is working.

The closest i've come is with Why mkdir fails with recursive option set true?

Though i couldnt understand any of what was said in the link.

Thanks!

Upvotes: 1

Views: 210

Answers (2)

ep0
ep0

Reputation: 710

It fails because it parses the path provided as argument and "changes" path to parent of new directory.

Try this (in a folder test with a subfolder s):

  • mkdir s/s2/s3 <- will fail because s2 does not exist in s
  • mkdir s/s2 <- ok
  • mkdir s/s2/s3 <- ok

When calling with recursive set to TRUE, it does something different: splits the path as usual, but checks existence of each prefix.

Again in folder test:

  • mkdir -p s/s1/s2/s3/s4 will yield the following prefixes:
    • s
    • s/s1
    • s/s1
    • s/s1/s2
    • s/s1/s2/s3
    • s/s1/s2/s3/s4

Note: I've used mkdir under linux and p argument tells it to create parent directories if they do not exist (same as recursive).

Upvotes: 1

Ioannis Lalopoulos
Ioannis Lalopoulos

Reputation: 1511

The mkdir() needs the recursive set to true since you ask it to create nested directories that do not exist, i.e.:

$upload_path = 'C:\Users\Admin\Desktop\UniServer\www\images\\'.$foldername.'\\'.$cat.'\\'.$sub.'\\'.$itemname.'\\';

So since the variable $foldername gets its value from the user session, if the user session change it changes. The same goes for the rest of the $upload_path parts, if something of them changes you have to create the whole path. Only the last part of the path ($itemname) can change without using the recursive option.

Upvotes: 1

Related Questions