略微加速

PHP官方手册 - 互联网笔记

PHP - Manual: mkdir

2024-12-20

mkdir

(PHP 4, PHP 5, PHP 7, PHP 8)

mkdir新建目录

说明

mkdir(
    string $pathname,
    int $mode = 0777,
    bool $recursive = false,
    resource $context = ?
): bool

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

参数

pathname

目录的路径。

mode

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

注意:

mode 在 Windows 下被忽略。

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

recursive

允许递归创建由 pathname 所指定的多级嵌套目录。

context

上下文流(context stream) resource

返回值

成功时返回 true, 或者在失败时返回 false

范例

示例 #1 mkdir() 例子

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

示例 #2 通过 recursive 参数使用 mkdir()

<?php
// Desired folder structure
$structure './depth1/depth2/depth3/';

// To create the nested structure, the $recursive parameter 
// to mkdir() must be specified.

if (!mkdir($structure0777true)) {
    die(
'Failed to create folders...');
}

// ...
?>

错误/异常

目录已存在时,产生 E_WARNING错误。

如果因为权限问题无法创建目录,导致 E_WARNING错误。

参见

  • is_dir() - 判断给定文件名是否是一个目录
  • rmdir() - 删除目录
add a noteadd a note

User Contributed Notes 40 notes

up
26
jack dot sleight at gmail dot com
12 years ago
When using the recursive parameter bear in mind that if you're using chmod() after mkdir() to set the mode without it being modified by the value of uchar() you need to call chmod() on all created directories. ie:

<?php
mkdir
('/test1/test2', 0777, true);
chmod('/test1/test2', 0777);
?>

May result in "/test1/test2" having a mode of 0777 but "/test1" still having a mode of 0755 from the mkdir() call. You'd need to do:

<?php
mkdir
('/test1/test2', 0777, true);
chmod('/test1', 0777);
chmod('/test1/test2', 0777);
?>
up
15
satis at clankiller dot com
11 years ago
Please note that in a shared environment I failed to take into account an existing umask when I did a mkdir(dirname, 0755).  This ended up creating the directory (function returned true), but I didn't have rights to do anything inside the folder, nor could I even view that it existed via ftp.

However, file_exists(dirname) returned true.  Eventually I figured out what happened and was able to rmdir(dirname), then created the directory correctly.

So, when writing scripts you expect to be portable, either use umask to set your umask accordingly, or do a straight mkdir(dirname) followed by chmod(dirname, 0755) (or whatever it is you're looking for).  If you make the same mistake I did, you should be able to rmdir() or chmod() the folder so it's accessible.
up
9
fantasysportswire at yahoo dot com
15 years ago
One small correction on a note from Frank in June 2006 on recursive directories under Windows.

First - this should be in the documentation as its the only function that I know of that php does not fix the slashes automatically.

Franks note stated:

<?php
   $mypath
="testdir\subdir\test";
  
mkdir($mypath,0777,TRUE);
?>

This doesn't work in windows:

<?php
   $mypath
="testdir/subdir/test";
  
mkdir($mypath,0777,TRUE);
?>

----

This will work a bit better :)

<?php
   $mypath
="testdir\\subdir\\test";
  
mkdir($mypath,0777,TRUE);
?>
up
9
ethaizone at hotmail dot com
12 years ago
When I created folder on windows with mkdir, I found some problem from folder nam so I write this function.

<?php
function filename_safe($name) {
   
$except = array('\\', '/', ':', '*', '?', '"', '<', '>', '|');
    return
str_replace($except, '', $name);
}
?>

It can use with another functions about file system as file_put_contents to clean up file name.
up
3
info at cc-folio dot ru
2 years ago
One use case:
<?php
function addDir($path){
        return (!
mkdir($path, 0755) && !is_dir($path));
    }
?>
up
12
aulbach at unter dot franken dot de
22 years ago
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);
?>
up
5
Protik Mukherjee
17 years ago
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!
up
7
toppi at kacke dot de
11 years ago
If you have problems with the SAFE MODE Restriction in effect i.e. if you try to create and access to subdirectorys recursive you can use ftp-lib like this.

<?php

DEFINE
('FTP_USER','yourUser');
DEFINE ('FTP_PASS','yourPassword');

/**
* Returns the created directory or false.
*
* @param Directory to create (String)
* @return Created directory or false;
*/

function mkDirFix ($path) {
   
   
       
$path = explode("/",$path);
       
$conn_id = @ftp_connect("localhost");
        if(!
$conn_id) {
            return
false;
        }
        if (@
ftp_login($conn_id, FTP_USER, FTP_PASS)) {
           
            foreach (
$path as $dir) {
                if(!
$dir) {
                    continue;
                }
               
$currPath.="/".trim($dir);
                if(!@
ftp_chdir($conn_id,$currPath)) {
                    if(!@
ftp_mkdir($conn_id,$currPath)) {
                        @
ftp_close($conn_id);
                        return
false;
                    }
                    @
ftp_chmod($conn_id,0777,$currPath);
                }
            }
        }
        @
ftp_close($conn_id);
        return
$currPath;
   
}
?>

Maybe it helps.
Toppi
up
5
Anonymous
8 years ago
Don't forget to use the recursive option on Windows if creating a folder below a folder that already exists. Otherwise you may get a very confusing error message, "Warning: mkdir(): No such file or directory in d:\path\to\file" where you think the folder should exist but you forgot to create the parent(s).

For example, if d:\path exists but there is nothing in it:

<?php
$path
= 'd:\path\to\my\file';
mkdir($path, null, true);
?>
up
1
Chance Green
2 years ago
Attempting to create a directory with a trailing space on Windows will result in a permission denied error.
up
2
julius - grantzau - c-o-m
11 years ago
Remember to use clearstatcache()

... when working with filesystem functions.

Otherwise, as an example, you can get an error creating a folder (using mkdir) just after deleting it (using rmdir).
up
1
etter dot ayoub at gmail dot com
4 years ago
Function to create recursive and writable folder, if we have permission, without generate a warnings :
/**
* Create correctly writable folder.
* Check if folder exist and writable.
* If not exist try to create it one writable.
*
* @return bool
*     true folder has been created or exist and writable.
*     False folder not exist and cannot be created.
*/
function createWritableFolder($folder)
{
    if($folder != '.' && $folder != '/' ) {
        createWritableFolder(dirname($folder));
    }
    if (file_exists($folder)) {
        return is_writable($folder);
    }

    return is_writable($folder) && mkdir($folder, 0777, true);
}
up
3
kungla at gmail dot com
15 years ago
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 ;)
up
2
yordanny90 at gmail dot com
9 months ago
To create a folder tree recursively so that all new folders have the same permissions:
<?php
function mkdir_recursive($directory, $permissions=0777) {
    if(!
file_exists(dirname($directory))){
       
mkdir_recursive(dirname($directory), $permissions);
    }
    if(
mkdir($directory, $permissions)){
       
chmod($directory, $permissions);
        return
true;
    }
    return
false;
}
?>
up
1
d dot kok at kadova dot nl
13 years ago
Please note that when specifying the recursive option the function returns false anyway if the directory already exists.

For some reason however I expected it to behave like `mkdir -p` on the command line which succeeds if the directory already exists.
up
1
php at mike2k dot com
13 years ago
It should be noted that all of the recursive mkdir functions coded below are no longer required - as of 5.0.0 it says the "recursive" flag is available. I just tested it, it properly works (and I would assume it works for streams and Windows as well, if not, then it would be a bug)
up
0
mamedul.github.io
1 year ago
To create nested folder In windows OS use suppressor @.

This suppressor will handle user type errors also.

$path = 'testpath\nested1\nested2\nested3\';
@mkdir( $path, '0777', TRUE);

Besides you can create a function-

function createMyDir( $path ){

    return @mkdir( $path, '0777', TRUE);

}
up
0
sean at pedlr dot com
15 years ago
It should be noted that although the documentation says that  the default permissions for mkdir are 0777, this is not always the case.

I'm running LAMP and without explicitly setting the permissions, the directories created had permissions of 0755.
up
-1
pz
10 years ago
mkdir works with stream wrappers, so it's ok to write mkdir('ftp://user:pass@server/mydir');

which really made my day
up
-3
bloggernitscomp54engg[at]gmail[dot]com
7 years ago
[Editor's note: that behavior is related to the current umask, which is documented above.]

mkdir("video/".$userId,0777);

Every time I run this code but permission wont change. It always show 755.I have spent lot of time in why my folder is not getting permission 777 (I think, mkdir has some problem in setting permission ).

then I used this code.

mkdir("video/".$userId,0777);
chmod("video/".$userId,0777);

my folder permission get changed 777.
up
-5
Anonymous
16 years ago
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;
}
up
-4
haclong
8 years ago
If you are using the SPL FileInfo object and then try to create the path with mkdir, don't forget that mkdir expects a string as the first argument and NOT an object...

I have forgotten that very important rules and get only a permission deny to mkdir to create new directories but in fact, the issue was the fact that i wasn't passing a string to mkdir

$my_file = new SplFileInfo('path/to/file.txt') ;

// get path from file
$parent = $my_file->getPathInfo() ;

// check if path is directory or not
if($parent->isDir())
{
// create / open file.txt file
} else {
// if path/to does not exists, create the directory recursively
mkdir($parent, 0755, true) ; // THIS WON'T WORK because $parent is a SplFileInfo object.

// instead, get the path as a string
$path = $parent->getPathname() ;
mkdir($path, 0755, true) ; // THIS WILL WORK
}
up
-6
Michal Nazarewicz, mina86 at mina86 dot com
14 years ago
On the other hand, splitting path on something else then a DIRECTORY_SEPARATOR may give unexpected results when someone accualy wants a file name with backslash in it! Moreover, neither Alan's nor pluto's code check for errors or return any value. Also, I don't like the isset($folder[$i]) technique -- there is a count() function you know.

<?php
function recursive_mkdir($path, $mode = 0777) {
   
$dirs = explode(DIRECTORY_SEPARATOR , $path);
   
$count = count($dirs);
   
$path = '.';
    for (
$i = 0; $i < $count; ++$i) {
       
$path .= DIRECTORY_SEPARATOR . $dirs[$i];
        if (!
is_dir($path) && !mkdir($path, $mode)) {
            return
false;
        }
    }
    return
true;
}
?>

It will only fail if someone specifies a mode which does not allow owner to create new entries in directory.
up
-5
t-k-r at o2 dot pl
13 years ago
Very simple script, may be useful to someone.
Creating a directory structure liki this:

0 ------ 0
1          1
2          2 -------- 0
3          3             1
4          ...           2
5                        3
6                        ...
7
[....]
e
f

Used by my as structure to store uploaded files:
someone upload file -> its name + microtime is md5 -> first 3 letters of md5 string are first 3 subfolders in this folder structure, and at least file is stroed with md5 name.
Naturally SQL- or other type - Database is needed to store infos about files position in this structure.

<?php

for ($a=0;$a<=15;$a++) {
   
   
mkdir(dechex($a),0755);

    for (
$b=0;$b<=15;$b++) {

       
mkdir(dechex($a).'/'.dechex($b),0755);

        for (
$c=0;$c<=15;$c++) {

           
mkdir(dechex($a).'/'.dechex($b).'/'.dechex($c),0755);

        }

    }

}

?>
up
-5
matt at imaketheweb dot com
10 years ago
If you're getting a Permission Denied error, but are certain the permissions and ownership where you are trying to create the directory are correct, check again:

The location where you are trying to create the directory in must have the Execute permission for the owner trying to create it, regardless of if the folder is Readable, or Writable.

This may be obvious to some, but was not to me at first. Hopefully this will save you the trouble I went through.
up
-8
michael at neo dot co dot il
12 years ago
sometimes the directory created with another mode than specified ( 0755 instead 0777  etc).
to solve that use :

<?php
$old
= umask(0);
mkdir($dir,0777);
umask($old);
?>
up
-6
hinom - iMasters
13 years ago
mkdir simple test with "exception handler"

<?php

function handleError() {
   
trigger_error('MY ERROR');

   
/** usage sample
        @handleError();
        echo $php_errormsg;
    */
}

// detect slash/backslash nomenclature dirname
$path = dirname( __FILE__ );
$slash = '/'; strpos( $path, $slash ) ? '' : $slash = '\\';
define( 'BASE_DIR', $path . $slash );

$folder  = time();               // folder name
$dirPath = BASE_DIR . $folder;   // folder path

// print results
echo $slash;
echo
'<hr>';

$rs = @mkdir( $dirPath, '0777' );
@
handleError();
if(
$rs )
{

   
// print success information
   
echo 'was done!';
    echo
'<br>folder: <a href="' . $folder . '">' . $folder . '</a>';
    echo
'<br>dirPath: ' . $dirPath;

}else{
   
   
// print error information
   
echo 'an error was occurred. Attempting create folder';
    echo
'<br>dirPath: ' . $dirPath;
    echo
'<br>php_errormsg: ' . $php_errormsg;

}

?>
up
-5
webmaster2007 at home dot nl
17 years ago
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
?>
up
-6
david dot NOSPAM at ajnewmedia dot NOSPAM dot co dot uk
14 years ago
p-garcia : since PHP 5, setting the recursive flag (which currently has no notes in the manual entry) will allow you to create nested directories in the same way as Windows / Linux mkdir -p, so long as the webserver has permissions to write in the root directory of the path specified
eg:

<?php
  mkdir
("./newdir1/newdir2/newdir3/", 0755, true);

 
// Returns TRUE if you have permission to write to the current directory
  //   and creates nested directories with permissionsrwxr-xr-x
?>
up
-10
jamespilcher1hotmail
16 years ago
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)
up
-8
nickcarenza at gmail dot com
11 years ago
If you are having trouble with the pathname, use:

echo dirname( __FILE__ );

That will show you the pathname of the current script and you will be able to use that to see where you have to start your pathname.

I tried forever to do mkdir('dirname') and was getting permission denied. I can see now its because it was trying to create that folder up at home when i wanted it down in public_html.

I hope this saves someone some time.
up
-8
[Rakesh Verma] rakeshnsony at gmail dot com
11 years ago
if you are unable to create recursive folder(s) using 0755 mode in your php script.

Then try it by changing your current user to apache and test it again.

Hopefully you will get positive results
up
-7
GelaMu at GMail dot com
14 years ago
<?php

/**
* Makes directory and returns BOOL(TRUE) if exists OR made.
*
* @param  $path Path name
* @return bool
*/
function rmkdir($path, $mode = 0755) {
   
$path = rtrim(preg_replace(array("/\\\\/", "/\/{2,}/"), "/", $path), "/");
   
$e = explode("/", ltrim($path, "/"));
    if(
substr($path, 0, 1) == "/") {
       
$e[0] = "/".$e[0];
    }
   
$c = count($e);
   
$cp = $e[0];
    for(
$i = 1; $i < $c; $i++) {
        if(!
is_dir($cp) && !@mkdir($cp, $mode)) {
            return
false;
        }
       
$cp .= "/".$e[$i];
    }
    return @
mkdir($path, $mode);
}

?>
up
-6
Kevin Cook
16 years ago
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
up
-8
Benjamin Rack
11 years ago
It should be mentioned that - at least on Windows - when using UNC paths with mkdir the 2nd parameter $mode should not be specified. Otherwise mkdir fails to create the directory on the given UNC path.
up
-8
vlad at todosv dot com
13 years ago
Note that you should NOT enter the $mode value with "" or '' sorrounding it.

So, this should be valid:
<?php mkdir("dir1/dir2",0777,true); ?>

But this is not:
<?php mkdir("dir1/dir2","0777",true); ?>

Nor this:
<?php mkdir("dir1/dir2",'0777',true); ?>
up
-9
till at etill dot net
6 years ago
Note that mkdir() also will return false if the directory exists. So, always use file_exists() to catch an existing-directory error.
up
-11
roth at egotec dot com
17 years ago
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);
up
-15
code at ashleyhunt dot co dot uk
14 years ago
Here's a script to create a recursive directory path on NAS or another server using Common Internet File System (CIFS)

e.g. you already have a directory on a server
\\server/share/dir1/dir2

you want to create some more directories
\\server/share/dir1/dir2/dir3/dir4

<?php
function remote_mkpath($server, $path)  {
       
$dirs = array();
       
$path = preg_replace('/(\/){2,}|(\\\){1,}/','/',$path); //only forward-slash
       
$dirs = explode("/", $path);
       
$path = "\\\\" . $server . "/";
       
$i = 0;
        foreach (
$dirs AS $element) {
           
$path .= $element . "/";
            if(!
is_dir($path) && $i != 0) {
                if(!
mkdir($path)){
                    echo
"something was wrong at : " . $path;
                    return
0;
                }
            }  
           
$i++;
        }
        return
true;
        echo
$path;
}

// example usage
remote_mkpath("SERVER", "share/dir1/dir2/dir3/dir4");
?>

Good luck!

Ashley
up
-25
Ali Baba
16 years ago
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);

?>

官方地址:https://www.php.net/manual/en/function.mkdir.php

北京半月雨文化科技有限公司.版权所有 京ICP备12026184号-3