创建文件夹(如果尚不存在)


642

我在使用Bluehost进行WordPress安装时遇到了一些情况,由于没有上传文件夹,我的WordPress主题遇到了错误wp-content/uploads

显然,尽管HostGator可以,Bluehost cPanel WordPress安装程序不会创建此文件夹。

因此,我需要向主题添加代码,以检查文件夹并以其他方式创建该文件夹。


7
if (!file_exists('path/to/directory')) { mkdir('path/to/directory', 0777, true); }
我是最愚蠢的人

Answers:


1226

使用mkdir尝试一下:

if (!file_exists('path/to/directory')) {
    mkdir('path/to/directory', 0777, true);
}

请注意,这0777已经是目录的默认模式,并且仍可以被当前的umask修改。


11
您错过了“递归”标志-请参阅Satish的答案。
弗朗索瓦·布尔乔亚

118
is_dir()是位速度更快,比file_exists()
pliashkou

43
@YuryPliashkou是的,但是如果已经有一个具有该名称的文件,则无法使用。
Gumbo

4
问题在这里:因此,如果在path / to中有一个名为“ directory”的文件,is_dir将返回true,但是file_exists将返回false?
Igor L.

8
file_exists-检查某个文件或目录是否存在 is_file-判断文件名是否是一个普通文件 is_dir-给定文件名是否是一个目录
TarranJones


66

自Google出现以来,它的通用性有所提高。尽管细节更为具体,但此问题的标题更为通用。

/** 
 * recursively create a long directory path
 */
function createPath($path) {
    if (is_dir($path)) return true;
    $prev_path = substr($path, 0, strrpos($path, '/', -2) + 1 );
    $return = createPath($prev_path);
    return ($return && is_writable($prev_path)) ? mkdir($path) : false;
}

这将采用一条路径,可能带有一长串未创建的目录,并继续向上移动一个目录,直到到达现有目录为止。然后它将尝试在该目录中创建下一个目录,并继续直到创建了所有目录。如果成功,则返回true。

通过提供停止级别,可以改善它,如果它超出了用户文件夹或其他内容,并且包含了权限,则只会失败。


@phazei我由于行$ return = createPath($ prev_path);而得到了对未定义函数的调用。
Battousai

感谢@phazei :)
亚历克斯(Alex)

58

像这样的辅助函数呢?

function makeDir($path)
{
     $ret = mkdir($path); // use @mkdir if you want to suppress warnings/errors
     return $ret === true || is_dir($path);
}

true如果目录已成功创建或已经存在,并且false无法创建目录,它将返回。

一个更好的替代方案是这样的(不应该给任何警告):

function makeDir($path)
{
     return is_dir($path) || mkdir($path);
}

4
如果删除@并通过适当的is_dir检查将其替换,则我的投票是您的:)奖励点,用于检查是否is_writable()为防水助手功能的父目录。
Pekka

使用@抑制错误会影响性能。最好检查一下它是否像Gumbo一样不存在
Simon

1
不管错误抑制如何,对于第一个示例,我倾向于-1。第二个要好得多,第一个就没有意义。
贾斯汀·约翰逊

仅将其放在一行上就很难阅读代码。可接受的答案更加清晰。
MikeKulls

26

创建文件夹的更快方法:

if (!is_dir('path/to/directory')) {
    mkdir('path/to/directory', 0777, true);
}

如果在该路径下有一个名为“目录”的文件,则会产生错误。
Guney Ozsan

23

递归创建目录路径:

function makedirs($dirpath, $mode=0777) {
    return is_dir($dirpath) || mkdir($dirpath, $mode, true);
}

受Python启发 os.makedirs()


11

在WordPress中,还有非常方便的功能wp_mkdir_p,它将以递归方式创建目录结构。

资料来源:-

function wp_mkdir_p( $target ) {
    $wrapper = null;

    // strip the protocol
    if( wp_is_stream( $target ) ) {
        list( $wrapper, $target ) = explode( '://', $target, 2 );
    }

    // from php.net/mkdir user contributed notes
    $target = str_replace( '//', '/', $target );

    // put the wrapper back on the target
    if( $wrapper !== null ) {
        $target = $wrapper . '://' . $target;
    }

    // safe mode fails with a trailing slash under certain PHP versions.
    $target = rtrim($target, '/'); // Use rtrim() instead of untrailingslashit to avoid formatting.php dependency.
    if ( empty($target) )
        $target = '/';

    if ( file_exists( $target ) )
        return @is_dir( $target );

    // We need to find the permissions of the parent folder that exists and inherit that.
    $target_parent = dirname( $target );
    while ( '.' != $target_parent && ! is_dir( $target_parent ) ) {
        $target_parent = dirname( $target_parent );
    }

    // Get the permission bits.
    if ( $stat = @stat( $target_parent ) ) {
        $dir_perms = $stat['mode'] & 0007777;
    } else {
        $dir_perms = 0777;
    }

    if ( @mkdir( $target, $dir_perms, true ) ) {

        // If a umask is set that modifies $dir_perms, we'll have to re-set the $dir_perms correctly with chmod()
        if ( $dir_perms != ( $dir_perms & ~umask() ) ) {
            $folder_parts = explode( '/', substr( $target, strlen( $target_parent ) + 1 ) );
            for ( $i = 1; $i <= count( $folder_parts ); $i++ ) {
                @chmod( $target_parent . '/' . implode( '/', array_slice( $folder_parts, 0, $i ) ), $dir_perms );
            }
        }

        return true;
    }

    return false;
}

6

对于登录站点,我需要相同的内容。我需要创建一个包含两个变量的目录。$ directory是我要使用用户许可证号创建另一个子文件夹的主文件夹。

include_once("../include/session.php");
$lnum = $session->lnum; //Users license number from sessions
$directory = uploaded_labels; // Name of directory that folder is being created in

if (!file_exists($directory."/".$lnum)) {
mkdir($directory."/".$lnum, 0777, true);
}

5

这是没有错误抑制的最新解决方案:

if (!is_dir('path/to/directory')) {
    mkdir('path/to/directory');
}

3

如果您想避免file_existsVS is_dir问题,建议您在这里查看

我尝试了此操作,并且仅在目录不存在时才创建目录。它不在乎是否存在具有该名称的文件。

/* Creates the directory if it does not exist */
$path_to_directory = 'path/to/directory';
if (!file_exists($path_to_directory) && !is_dir($path_to_directory)) {
    mkdir($path_to_directory, 0777, true);
}

2
if (!is_dir('path_directory')) {
    @mkdir('path_directory');
}

3
错误抑制?为什么?
canadiancreed

4
借助错误抑制,无需检查目录是否存在
neoascetic

4
处理错误胜于抑制错误。如果失败了,您将永远不知道为什么会因此而不得不对其进行研究
Tim Ogilvy

在高度并发/多线程的环境中,建议抑制该错误。可能发生竞争情况,其中两个或更多线程将is_dir()评估为false并尝试创建目录。第一个线程将能够毫无问题地创建它,但是其他线程将无法创建它,因为目录已经存在。为了避免丢失实际失败的目录创建,您应该在再次调用@mkdir()之后检查目录的存在。
tobain

2

您也可以尝试:

$dirpath = "path/to/dir";
$mode = "0777";
is_dir($dirpath) || mkdir($dirpath, $mode, true);

2

创建文件夹(如果尚不存在)

考虑问题的环境。

  • WordPress。
  • 虚拟主机服务器。
  • 假设它的Linux不是运行PHP的Windows。

并引用自:http : //php.net/manual/en/function.mkdir.php

bool mkdir(字符串$ pathname [,int $ mode = 0777 [,bool $ recursive = FALSE [,资源$ context]]])

手册说,唯一需要的参数是$pathname

因此,我们可以简单地编写以下代码:

<?php
error_reporting(0); 
if(!mkdir('wp-content/uploads')){
   // todo
}
?>

说明:

除非需要,否则不必传递任何参数,也不必检查文件夹是否存在,甚至不必传递模式参数。出于以下原因:

  • 该命令将使用0755权限(共享主机文件夹的默认权限)或0777命令的默认权限创建文件夹。
  • mode运行PHP的Windows主机上被忽略。
  • mkdir如果文件夹存在,该命令已经内置了检查器;所以我们只需要检查返回值True | False;并且它不是错误,仅是警告,默认情况下,在托管服务器中禁用了警告。
  • 根据速度,如果禁用警告,则速度更快。

这只是研究问题而不主张更好或最理想的解决方案的另一种方式。

在PHP7,生产服务器,Linux上测试


2
$upload = wp_upload_dir();
$upload_dir = $upload['basedir'];
$upload_dir = $upload_dir . '/newfolder';
if (! is_dir($upload_dir)) {
   mkdir( $upload_dir, 0700 );
}

2

我们应该始终对代码进行模块化,并在下面编写了相同的代码进行检查...首先检查目录,如果目录不存在,则创建目录。

$boolDirPresents = $this->CheckDir($DirectoryName);

if (!$boolDirPresents) {
        $boolCreateDirectory = $this->CreateDirectory($DirectoryName);
        if ($boolCreateDirectory) {
        echo "Created successfully";
      }
  }

function CheckDir($DirName) {
    if (file_exists($DirName)) {
        echo "Dir Exists<br>";
        return true;
    } else {
        echo "Dir Not Absent<br>";
        return false;
    }
}

function CreateDirectory($DirName) {
    if (mkdir($DirName, 0777)) {
        return true;
    } else {
        return false;
    }
}

1

您首先需要检查目录是否存在 file_exists('path_to_directory')

然后使用mkdir(path_to_directory)创建目录

mkdir( string $pathname [, int $mode = 0777 [, bool $recursive = FALSE [, resource $context ]]] ) : bool

更多关于mkdir()在这里

完整代码在这里:

$structure = './depth1/depth2/depth3/';
if (!file_exists($structure)) {
    mkdir($structure);
}

0

干得好。

if (!is_dir('path/to/directory')) {
    if (!mkdir('path/to/directory', 0777, true) && !is_dir('path/to/directory')) {
        throw new \RuntimeException(sprintf('Directory "%s" was not created', 'path/to/directory'));
    }
}

PHPStorm(带有PHP Inspections)给出了这个建议;-) btw。您可以将外部if合并到内部:if(!is_dir(...)&&!mkdir(...)&&!is_dir(...))...
aProgger

-1

可接受的答案有效,但由于权限原因,它不是正确的解决方案。0777权限允许所有人访问/读取/写入目录。这不是我们想要的Web服务器上载目录。这是建议的正确和完整的解决方案。

$path_to_directory = 'path/to/directory';
if (!file_exists($path_to_directory) && !is_dir($path_to_directory)) {
    mkdir($path_to_directory, 0644, true);
}

0644是上载目录的正确权限,因为我们通常不希望在服务器上执行上载。

true是将递归属性设置为true或false的第三个参数。它允许创建在路径名中指定的嵌套目录。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.