mkdir

(PHP 3, PHP 4, PHP 5)

mkdir -- 新建目录

说明

bool mkdir ( string pathname [, int mode] )

尝试新建一个由 pathname 指定的目录。

注意也许想用八进制数指定模式,也就是说该数应以零打头。模式也会被当前的 umask 修改,可以用 umask() 来改变。

注: Mode 在 Windows 下被忽略。自 PHP 4.2.0 起成为可选项。

默认的 mode 是 0777,意味着最大可能的访问权。有关 mode 的更多信息请阅读 chmod() 页面。

例子 1. mkdir() 例子

<?php
mkdir
("/path/to/my/dir", 0700);
?>

注: 自 PHP 5.0.0 rmdir() 也可用于某些 URL 封装协议。参见附录 L 的列表看看 rmdir() 支持哪些 URL 封装协议。

注: recursive 参数是 PHP 5.0.0 添加的。

如果成功则返回 TRUE,失败则返回 FALSE

参见 rmdir()


add a note add a note User Contributed Notes
john 4t idserver d0t org
28-Oct-2006 02:27
Windows reserves the names PRN and CON as they are devices in DOS. Back in the day, you could easily print a document via "type filename.txt > PRN".

CON is the console. To create a file from scratch under dos you do: COPY CON filename.txt

It then allows you to type until you press CTRL-D.
djneoform at gmail dot com
27-Oct-2006 10:28
Forewarning to windows users.

If you try to create a directory called "prn" or "con" windows will reject the name and cause an error.

apparently (i found this out the hard way) windows simply cannot have directories by those names, who knows why..
mroy at matthewroy dot com
11-Oct-2006 10:51
fixed bug with the previous script: 

else if (!ftp_site($connection, "CHMOD 0777 $newDir"){ // change attributes

is missing an ")" so it should read:

else if (!ftp_site($connection, "CHMOD 0777 $newDir")) { // change attributes
Lars Ptzold
29-Aug-2006 08:44
Just a small addition to Han Van den Hoof's ftp script which is really useful for scripts on shared servers.

I added a chmod command. This is necessary if you want to access the directory later via script.
I also fixed the small bug with the 2 variables connection & conn_id ;)
And last not least ftp connection is closed even if ftp commands fail.

Sometimes ftp login will fail due to bad luck. Therefore one should add a loop for retrying.

<?php
// create directory through FTP connection
function FtpMkdir($path, $newDir) {

  
$server='ftp.yourserver.com'; // ftp server
  
$connection = ftp_connect($server); // connection

   // login to ftp server
  
$user = "me";
  
$pass = "password";
  
$result = ftp_login($connection, $user, $pass);

  
// check if connection was made
  
if ((!$connection) || (!$result)) {
       return
false;
       exit();
   } else {
       if (!
ftp_chdir($connection, $path)) { // go to destination dir
          
$r = false;
       } else if (!
ftp_mkdir($connection,$newDir)) { // create directory
          
$r = false;
       } else if (!
ftp_site($connection, "CHMOD 0777 $newDir") { // change attributes
          
$r = false;
       } else {
          
$r = $newDir;
       }
   }
  
  
ftp_close($connection); // close connection
  
  
return $r;
}
?>
PHGN
14-Aug-2006 02:13
I've been wrestling with mkdir on a server with safe mode turned on (I think, I kept getting barmy permissions on the new dirs).

In the end the solution was to use:
exec (mkdir ...
exec (chmod ...

For this to work I had to use the setuid bit on the script itself. I tried this with the mkdir() function, but to no avail. (To do the setuid bit I ran chmod 4775 on the script file from the command line.)
malmsteenforce at tlen dot pl
20-Jul-2006 06:39
I have trouble with recursively of mk_dir function ,with slashes and backslashes, so I`ve solved this below :

<?
function mkpath($path)
   {
    
$dirs=array();
    
$path=preg_replace('/(\/){2,}|(\\\){1,}/','/',$path); //only forward-slash
    
$dirs=explode("/",$path);
    
$path="";
     foreach (
$dirs as $element)
         {
          
$path.=$element."/";
           if(!
is_dir($path))
             {
             if(!
mkdir($path)){ echo "something was wrong at : ".$path; return 0; }
             }         
         }
     echo(
"<B>".$path."</B> successfully created");
   }

mkpath("./dir1\dir2/dir3\\\dir4////dir5"); //this works without errors
?>
kungla at gmail dot com
18-Jul-2006 08:41
Somehow the recursive version of mkdir didn't work for me on Mac and the workaraounds listed below alsow didn't work for me, so heres my solution:

<?php
function mkdir_r($dirName, $rights=0777){
  
$dirs = explode('/', $dirName);
  
$dir='';
   foreach (
$dirs as $part) {
      
$dir.=$part.'/';
       if (!
is_dir($dir) && strlen($dir)>0)
          
mkdir($dir, $rights);
   }
}
?>

Tested and works ;)
Frank
13-Jul-2006 05:51
cost me an hour to get recursive switch to work in windows with php 5.2.0, so share it here.  The key is backward slash in windows , this php version doesn't recognize forward slash as valid path separator for mkdir(), though other functions support forward-slashed paths just fine.  The following example works in Windows:
<?php
   $mypath
="testdir\subdir\test";
  
mkdir($mypath,0777,TRUE);
?>
This doesn't work in windows:
<?php
   $mypath
="testdir/subdir/test";
  
mkdir($mypath,0777,TRUE);
?>
jamespilcher1hotmail
08-Apr-2006 08:53
one small gotcha:

mkdir(""), mkdir(false), and mkdir(null) give a "file exists" error. this is also true of a directory name consisting of any string that only contains space characters.

(this was on php 5.1.2 on Windows 2000)
bat at flurf dot net
22-Mar-2006 01:23
A little understanding of LISPlike programming makes this sort of task (recursive mkdir()ing in PHP4) much simpler.  This version works nicely:

<?php
function MakeDirectory($dir, $mode = 0755)
{
  if (
is_dir($dir) || @mkdir($dir,$mode)) return TRUE;
  if (!
MakeDirectory(dirname($dir),$mode)) return FALSE;
  return @
mkdir($dir,$mode);
}
?>

How it works: line one attempts to make the directory, and returns TRUE if it works or if it already exists.  That's the easy case if the parent directories all exist.

Line two trims off the last directory name using dirname(), and calls MakeDirectory recursively on that shorter directory.  If that fails, it returns FALSE, but otherwise we come out of it knowing that the parent directory definitely exists.

Finally, presuming the recursive call worked, once we get to line three we can create the requested directory.

Note the use of @ to suppress warning messages from mkdir.

The beauty of this is that if, say, the great-grandparent directory exists but the grandparent and parent directories don't, the function will simply call itself recursively until it gets high enough up the tree to do some work, then carry on unwinding back until all the new directories have been created.

This is pretty bog-standard recursive programming.  Anyone who can't wrap their head around it after a few minutes of concentration should probably try a career in sales.
Ali Baba
11-Mar-2006 05:26
Greg, your code does not work for me; maybe it has a bug or we have configuration changes. Anyway, this one works to create recursively the directory DIRECTORY.

<?
define
("DIRECTORY", "/tmp/mydir/mysubdir");

do {
  
$dir = DIRECTORY;
   while (!
is_dir($dir)) {
      
$basedir = dirname($dir);
       if (
$basedir == '/' || is_dir($basedir))
          
mkdir($dir,0777);
       else
          
$dir=$basedir;
   }
} while (
$dir != DIRECTORY);

?>
19-Jan-2006 01:48
function mkdirs($dir, $mode = 0777, $recursive = true) {
  if( is_null($dir) || $dir === "" ){
   return FALSE;
  }
  if( is_dir($dir) || $dir === "/" ){
   return TRUE;
  }
  if( mkdirs(dirname($dir), $mode, $recursive) ){
   return mkdir($dir, $mode);
  }
  return FALSE;
}
baldurien at club-internet dot fr
18-Jan-2006 07:14
For those wandering about the $recursive flag of mkdir in php5, this function will do what you want ( la java) in php 4:
<?php
/**
 * Create a new directory, and the whole path.
 *
 * If  the  parent  directory  does  not exists, we will create it,
 * etc.
 *
 * @param string the directory to create
 * @param int the mode to apply on the directory
 * @return bool return true on success, false else
 */
function mkdirs($dir, $mode = FS_RIGHTS_D) {
 
$stack = array(basename($dir));
 
$path = null;
 while ( (
$d = dirname($dir) ) ) {
     if ( !
is_dir($d) ) {
        
$stack[] = basename($d);
        
$dir = $d;
     } else {
        
$path = $d;
         break;
     }
 }

 if ( (
$path = realpath($path) ) === false )
     return
false;
 
 
$created = array();
 for (
$n = count($stack) - 1; $n >= 0; $n-- ) {
    
$s = $path . '/'. $stack[$n];                                     
     if ( !
mkdir($s, $mode) ) {
         for (
$m = count($created) - 1; $m >= 0; $m-- )
            
rmdir($created[$m]);
         return
false;
     }
    
$created[] = $s;     
    
$path = $s;
 }
 return
true;
}
?>

The main idea here is to use a stack to store the invalid dirname (using basename/dirname), and then pop each item on the stack to create directory from a valid path (here:  $path = realpath($path). If we fails creating one directory, we must remove them in the reverse order of creation (stackes :)).

This works on Windows XP, and it should work on Linux (actually, I did not tested it).

Note that this code is a part of one of my classes (named FileSystem), and that you should use your own basename/realpath/dirname/mkdir/rmdir function instead of php one (even if you use them behind). This will allow you to separate the item of a FileSystem from what is it really (FTP? Local ? Telnet? Teletubbies?)
Sean at seanj dot jcink dot com
24-Dec-2005 10:10
Mkdir will work on parent directories as long as file permissions are right and the openbase restriction is not on.

~Sean
trond at trondhuso dot no
14-Dec-2005 04:10
While researching for this function, I have found out that - at least on my system - mkdir only works when the parent directory is the one your script is in.
eg:
you want to create a directory tmp
mkdir ('tmp', 0775);
will create /path/to/your/script/tmp

but if you this
mkdir ('/path/to/your/tmp', 0755);
or
mkdir ('../tmp', 0755);

both will cause an error - permission denied.

Trond
Slawek Petrykowski
16-Nov-2005 03:20
Kevin Cook wrote: "I could not get the sticky bit set properly using the octal mode: 2775 (rwxrwsr-x)"

Try 02775 instead, Kevin.
killroy /at/ gmail
03-Nov-2005 01:49
Here's a 3 line version, only superficially tested on win:

<?php
function mkdir_recursive($dirName){
 foreach(
split('/',dirname($dirName)) as $dirPart)mkdir($newDir="$newDir$dirPart/");
}
?>
Kevin Cook
03-Nov-2005 01:14
I could not get the sticky bit set properly using the octal mode: 2775 (rwxrwsr-x)

$foo='my_directory';

$old_umask = umask(0);
mkdir($foo,2775);
umask($old_umask);

using the above lines renders a directory with permissions:

d-wx-wSrwt  2 www www 4096 Nov  2 11:43 my_directory

Not exactly what I was looking for.

This gets closer to the mark:

$foo='my_directory';

$old_umask = umask(0);
mkdir($foo,0777); // the default chmod
umask($old_umask);

drwxrwsrwx  2 www www 4096 Nov  2 11:46 my_directory
ephraim at coder-board dot info
11-Oct-2005 02:38
When safe_mode is enabled, and you create a directory via mkdir, you can't create a second inside the first because the first folder's user is that one of the webserver and not that one of the script. This is dumb and very annoying :(
greg at NOserberusSPAM dot co dot uk
05-Oct-2005 04:51
Recursive directory creation routine.

This could be adapted to work on Windows but this code is written for use on a Linux/Unix based machine.

<?php

$working_directory
= '/path/to/my/work';

do {
  
$dir = $working_directory;

   while (!@
mkdir($dir,0777)) {
      
$dir = dirname($dir);

       if (
$dir == '/' || is_dir($dir))
           break;
   }
} while (
$dir != $working_directory);

?>
funke
17-Sep-2005 03:51
Ive onlybeen coding in PHP for a couple of months so i Don't have all the syntax tricks down yet.

I wrote this function to create all the dirs in a path if they don't exist. its not actually recursive but i was to lazy to change the name  :)
theoretically i want it to work for both win and nix. As soon my project manager gets me a win box i'm gonna test it out.  anyrevisions to the function below would be appreciated.

<?php
// \

function recur_mkdirs($path, $mode = 0777) //creates directory tree recursively
{
  
//$GLOBALS["dirseparator"]
  
$dirs = explode($GLOBALS["dirseparator"],$path);
  
$pos = strrpos($path, ".");
   if (
$pos === false) { // note: three equal signs
       // not found, means path ends in a dir not file
      
$subamount=0;
   }
   else {
      
$subamount=1;
   }
  
   for (
$c=0;$c < count($dirs) - $subamount; $c++) {
      
$thispath="";
       for (
$cc=0; $cc <= $c; $cc++) {
          
$thispath.=$dirs[$cc].$GLOBALS["dirseparator"];
       }
       if (!
file_exists($thispath)) {
          
//print "$thispath<br>";
          
mkdir($thispath,$mode);
       }
      
      
   }
  
}
?>
Steven Ng
09-Jun-2005 02:37
I had to remove the $path in the CHMOD command before the function worked for me. The function was at the $path directory prior to initiating the CHMOD command, so it tried to go down the $path directory again.

// create directory through FTP connection
function FtpMkdir($path, $newDir) {
 
       $server='ftp.server.com'; // ftp server
       $connection = ftp_connect($server); // connection
 
 
       // login to ftp server
       $user = "me";
       $pass = "pass";
       $result = ftp_login($connection, $user, $pass);

   // check if connection was made
     if ((!$connection) || (!$result)) {
       return false;
       exit();
       } else {
         ftp_chdir($connection, $path); // go to destination dir
       if(ftp_mkdir($connection, $newDir)) { // create directory
       ftp_site($connection, "CHMOD 777 $newDir") or die("FTP SITE CMD failed.");
           return $newDir;
       } else {
           return false;   
       }
 
   ftp_close($connection); // close connection
   }

}
FtpMkdir("path","dir");
David Pullen
29-May-2005 08:20
A simple recursive mkdir function:

<?php

  
function RecursiveMkdir($path)
   {
      
// This function creates the specified directory using mkdir().  Note
       // that the recursive feature on mkdir() is broken with PHP 5.0.4 for
       // Windows, so I have to do the recursion myself.
      
if (!file_exists($path))
       {
          
// The directory doesn't exist.  Recurse, passing in the parent
           // directory so that it gets created.
          
RecursiveMkdir(dirname($path));

          
mkdir($path, 0777);
       }
   }

   if (!
file_exists("/path/to/my/file"))
   {
      
// Call the recursive mkdir function since the "recursive" feature
       // built in to mkdir() is broken.
      
RecursiveMkdir("/path/to/my/file");
   }

?>
roth at egotec dot com
23-May-2005 02:43
The 'mkdir' function doesn't function correctly on Windows when the path
contains forward slashes. The part of the path with the forward slashes
doesn't get created.

mkdir('c:/a/b/c/d', 0775, true);

You get the error message:
Warning: mkdir() [function.mkdir]: No such file or directory

Please use backslashes under Windows or use the constant DIRECTORY_SEPARATOR.

mkdir('c:\a\b\c\d', 0775, true);
mkdir('c:'.DIRECTORY_SEPARATOR.'a'.
DIRECTORY_SEPARATOR.'b'.
DIRECTORY_SEPARATOR.'c'.
DIRECTORY_SEPARATOR.'d', 0775, true);
webmaster2007 at home dot nl
28-Apr-2005 11:27
Maybe you can use this:

<?php
  
function open_dir($dir, $newdir){    //The function that will copy the files
      
if(file_exists($dir) && file_exists($newdir)){
          
$open_dir=opendir($dir);
           while (
false !== ($file = readdir($open_dir))) {
               if(
$file != "." && $file != ".."){
                   if(
file_exists($newdir."/".$file) && filetype($newdir."/".$file."/") != "dir"){
                      
unlink($newdir."/".$file);
                   }
                   if(
filetype($dir."/".$file."/") == "dir"){
                       if(!
file_exists($newdir."/".$file."/")){
                          
mkdir($newdir."/".$file."/");
                          
open_dir($dir."/".$file."/", $newdir."/".$file."/");
                       }
                   }
                   else {
                      
copy($dir."/".$file."/", $newdir."/".$file);
                   }
               }
           }
       }
   }
  
  
  
open_dir("Your source map", "Your destination map"); //Here you can fill in your source en destination map
?>
yknot7 at hotmail dot com
14-Apr-2005 02:59
Add permission using CHMOD in the above mentioned

// create directory through FTP connection
function FtpMkdir($path, $newDir) {
 
       $server='ftp.server.com'; // ftp server
       $connection = ftp_connect($server); // connection
 
 
       // login to ftp server
       $user = "me";
       $pass = "pass";
       $result = ftp_login($connection, $user, $pass);

   // check if connection was made
     if ((!$connection) || (!$result)) {
       return false;
       exit();
       } else {
         ftp_chdir($connection, $path); // go to destination dir
       if(ftp_mkdir($connection, $newDir)) { // create directory
       ftp_site($connection, "CHMOD 777 $path/$newDir") or die("FTP SITE CMD failed.");
           return $newDir;
       } else {
           return false;     
       }
  
   ftp_close($connection); // close connection
   }

}
FtpMkdir("path","dir");
mdap at dap dot ro
05-Apr-2005 05:26
at this example (from mkdir) :
<?php
// create directory through FTP connection
function FtpMkdir($path, $newDir) {
  
      
$server='ftp.yourserver.com'; // ftp server
      
$connection = ftp_connect($server); // connection
  
 
       // login to ftp server
      
$user = "me";
      
$pass = "password";
      
$result = ftp_login($connection, $user, $pass);

  
// check if connection was made
    
if ((!$connection) || (!$result)) {
       return
false;
       exit();
       } else {
        
ftp_chdir($connection, $path); // go to destination dir
      
if(ftp_mkdir($connection,$newDir)) { // create directory
          
return $newDir;
       } else {
           return
false;       
       }
  
ftp_close($conn_id); // close connection
  
}

}
?>
i found a mistake at the last line before } :
 ftp_close($conn_id); // close connection
is not $conn_id is $connection
Protik Mukherjee
04-Mar-2005 01:29
mkdir, file rw, permission related notes for Fedora 3////
If you are using Fedora 3 and are facing permission problems, better check if SElinux is enabled on ur system. It add an additional layer of security and as a result PHP cant write to the folder eventhough it has 777 permissions. It took me almost a week to deal with this!

If you are not sure google for SElinux or 'disabling SELinux' and it may be the cure! Best of luck!
Aleks Peshkov
26-Feb-2005 09:18
function makeDirs($strPath, $mode = 0777) //creates directory tree recursively
{
   return is_dir($strPath) or ( makeDirs(dirname($strPath), $mode) and mkdir($strPath, $mode) );
}

The simpler is the better.
par dot sandgren at gmail dot com
11-Feb-2005 04:29
You might want to upload files into random named dir's, just to make it harder to guess the link. But still have some ID to know whats in there.

<?php

$dirLength
= rand(30, 40);
      
$projectID = $_POST['pid']; // ID from database perhaps?
      
      
$rndName = "";
       for(
$i=0; $i<$dirLength; $i++)
       {
          
$rnd = rand(1, 3);
           if(
$rnd == 1)
              
$rndName = $rndName . chr(rand(97, 122));
           else if(
$rnd == 2)
              
$rndName = $rndName . chr(rand(65, 90));
           else
              
$rndName = $rndName . chr(rand(48, 57));
       }
      
      
$dirName = $projectID . "-" . $rndName;
      
mkdir($dirname);
?>
aidan at php dot net
03-Oct-2004 10:17
This function creates a directory structure recursively.

http://aidan.dotgeek.org/lib/?file=function.mkdirr.php
Han Van den Hoof
10-Nov-2003 02:28
If you're on a shared *nix server, a directory created through mkdir() will not be assigned to you, but to the user that your host's server or php process is running under, usually 'nobody', 'apache' or 'httpd'.

In practice, this means that you can create directories, even add files to them, but you can't delete the directory or its contents nor change permissions.

It is therefore advised to create directories through PHP's FTP API. Here's a function I wrote:

<?php
// create directory through FTP connection
function FtpMkdir($path, $newDir) {
  
      
$server='ftp.yourserver.com'; // ftp server
      
$connection = ftp_connect($server); // connection
  
 
       // login to ftp server
      
$user = "me";
      
$pass = "password";
      
$result = ftp_login($connection, $user, $pass);

  
// check if connection was made
    
if ((!$connection) || (!$result)) {
       return
false;
       exit();
       } else {
        
ftp_chdir($connection, $path); // go to destination dir
      
if(ftp_mkdir($connection,$newDir)) { // create directory
          
return $newDir;
       } else {
           return
false;       
       }
  
ftp_close($conn_id); // close connection
  
}

}
?>

Hope this comes in handy for someone.
28-Jun-2003 07:00
You might notice that when you create a new directory using this code:

mkdir($dir, 0777);

The created folder actually has permissions of 0755, instead of the specified
0777. Why is this you ask? Because of umask(): http://www.php.net/umask

The default value of umask, at least on my setup, is 18. Which is 22 octal, or
0022. This means that when you use mkdir() to CHMOD the created folder to 0777,
PHP takes 0777 and substracts the current value of umask, in our case 0022, so
the result is 0755 - which is not what you wanted, probably.

The "fix" for this is simple, include this line:

$old_umask = umask(0);

Right before creating a folder with mkdir() to have the actual value you put be
used as the CHMOD. If you would like to return umask to its original value when
you're done, use this:

umask($old_umask);
aulbach at unter dot franken dot de
23-Jul-1999 05:37
This is an annotation from Stig Bakken:

The mode on your directory is affected by your current umask.  It will end
up having (<mkdir-mode> and (not <umask>)).  If you want to create one
that is publicly readable, do something like this:

<?php
$oldumask
= umask(0);
mkdir('mydir', 0777); // or even 01777 so you get the sticky bit set
umask($oldumask);
?>