Recursively creating directory structures
Posted on April 5th, 2004 in Code Repository | 17 Comments »
Every now and then you want to create a deep directory structure on the fly. This function allows you to create whole directory trees independent of what folders exist in the path.
/**
* Create a directory structure recursively
*
* @author Aidan Lister <aidan@php.net>
* @version 1.0.1
* @link http://aidanlister.com/repos/v/function.mkdirr.php
* @param string $pathname The directory structure to create
* @return bool Returns TRUE on success, FALSE on failure
*/
function mkdirr($pathname, $mode = null)
{
// Check if directory already exists
if (is_dir($pathname) || empty($pathname)) {
return true;
}
// Ensure a file does not already exist with the same name
$pathname = str_replace(array('/', ''), DIRECTORY_SEPARATOR, $pathname);
if (is_file($pathname)) {
trigger_error('mkdirr() File exists', E_USER_WARNING);
return false;
}
// Crawl up the directory tree
$next_pathname = substr($pathname, 0, strrpos($pathname, DIRECTORY_SEPARATOR));
if (mkdirr($next_pathname, $mode)) {
if (!file_exists($pathname)) {
return mkdir($pathname, $mode);
}
}
return false;
}
17 Responses
This is one nice little function
thx
Nice function, thx a lot
thanks for the help
Nice script
Aidan,
Thank you so very much for this wonderful function. I’ve spent an inordinate amount of time looking for a quick solution to mkdir’s recursive deficiency (at least prior to 5.0), and you’ve supplied the answer.
Thank you!
To use with windows change the slash to \. Thank you
[Editor's Note: I updated the code to make this work on both systems]
Hello,
it seems that DIRECTORY_SEPARATOR doesn’t work on some systems. This is the case for my ISP (PHP 4.0.5, Apache 1.3.19, I don’t know the exact OS type).
[Editor's Note: That constant is not defined until PHP 4.3.0. You can either set it manually in the code, or use the PEAR package PHP_Compat (http://pear.php.net/package/PHP_Compat) ...]
how to call this funtion
Nice function! I found you link on php.net! Very helpfull, it saved my day!
good stuff
As per the ‘return once’ convention, I have modified the function to return once:
<?php
function mkdirr($pathname, $mode = null)
{
$return = false;
// Check if directory already exists
if (is_dir($pathname) || empty($pathname)) {
$return = true;
}
// Ensure a file does not already exist with the same name
if (is_file($pathname)) {
trigger_error(’mkdirr() File exists’, E_USER_WARNING);
$return = false;
}
// Crawl up the directory tree
$next_pathname = substr($pathname, 0, strrpos($pathname, DIRECTORY_SEPARATOR));
if (mkdirr($next_pathname, $mode)) {
if (!file_exists($pathname)) {
$return = mkdir($pathname, $mode);
}
}
return $return;
}
?>
Another slight variation. True single function return, and function name is now mkdirTree.
<?php
/**
* Create a directory structure recursively
*
* @author Aidan Lister <aidan@php.net>
* @version 1.0.0
* @param string $pathname The directory structure to create
* @return bool Returns TRUE on success, FALSE on failure
*/
function mkdirTree($pathname, $mode = null) {
$dirSeperator = “/”;
$return = false;
// Check if directory already exists
if (is_dir($pathname) || empty($pathname)) {
$return = true;
}
else {
// Ensure a file does not already exist with the same name
if (is_file($pathname)) {
trigger_error(’mkdirTree() Directory $pathname already exists’, E_USER_WARNING);
$return = false;
}
else {
// Crawl up the directory tree
$nextPathname = substr($pathname, 0, strrpos($pathname, $dirSeperator));
if ($this->mkdirTree($nextPathname, $mode)) {
if (!file_exists($pathname) and strpos($pathname, “.htm”) == 0) {
echo “Making directory $pathname…<br>”;
$return = mkdir($pathname, $mode);
}
}
}
}
return $return;
}
?>
Thank you for your help
I use php under windows (CLI) however, I use forward slashes exclusively as this will still remain compatible with *nix systems.
The php manual states that:
“On Windows, both slash (/) and backslash (\) are used as path separator character. In other environments, it is the forward slash (/).”
A small change to this function will make this function work on both windows and *nix.
put this line at the top of the function:
$pathname = str_replace( “\\”, “/”, $pathname );
then where $next_pathname is set, use a “/” in place of the constant or variable
I made this change on my system and it works fine.
Thanks for a nice, very useful function.
-Tim Gallagher
[Editor's Note: By using the DIRECTORY_SEPARATOR separator constant, we avoid the need to hardcode any specific slash.]
Great function !!! But I found another one which is simpler :
<?php
function mkdirr($path)
// create a directory structure recursively
{
if(is_dir($path)) return true;
return mkdirr(dirname($path)) && @mkdir($path);
}
?>
Nice 1 Mate Came in real handy, couldnt find the thing anywhere.
if using win DIRECTORY_SEPARATOR will be \
but people coding will commonly still use \
if you pass a ‘foo/bar/baz to your function, it will fail on win because it is trying to locate DIRECTORY_SEPARATOR with strrpos, which fails.
consider:
$pathname = str_replace(array(’/', ‘\\’), DIRECTORY_SEPARATOR, $pathname);
[Editor's Note: Good pick up. Fixed, thanks!]