本文翻译自:How do I check if a directory exists? “is_dir”, “file_exists” or both?
I want to create a directory if it does'nt exist already. 如果目录尚不存在,我想创建一个目录。
Is using is_dir enough for that purpose? 使用is_dir是否足以达到目的?
if ( !is_dir( $dir ) ) { mkdir( $dir ); }Or should I combine is_dir with file_exists ? 还是应该将is_dir与file_exists结合使用?
if ( !file_exists( $dir ) && !is_dir( $dir ) ) { mkdir( $dir ); }参考:https://stackoom.com/question/MlWN/如何检查目录是否存在-is-dir-file-exists-还是两者
I think realpath() may be the best way to validate if a path exist http://www.php.net/realpath 我认为realpath()可能是验证路径是否存在的最佳方法http://www.php.net/realpath
Here is an example function: 这是一个示例函数:
<?php /** * Checks if a folder exist and return canonicalized absolute pathname (long version) * @param string $folder the path being checked. * @return mixed returns the canonicalized absolute pathname on success otherwise FALSE is returned */ function folder_exist($folder) { // Get canonicalized absolute pathname $path = realpath($folder); // If it exist, check if it's a directory if($path !== false AND is_dir($path)) { // Return canonicalized absolute pathname return $path; } // Path/folder does not exist return false; }Short version of the same function 相同功能的简短版本
<?php /** * Checks if a folder exist and return canonicalized absolute pathname (sort version) * @param string $folder the path being checked. * @return mixed returns the canonicalized absolute pathname on success otherwise FALSE is returned */ function folder_exist($folder) { // Get canonicalized absolute pathname $path = realpath($folder); // If it exist, check if it's a directory return ($path !== false AND is_dir($path)) ? $path : false; }Output examples 输出示例
<?php /** CASE 1 **/ $input = '/some/path/which/does/not/exist'; var_dump($input); // string(31) "/some/path/which/does/not/exist" $output = folder_exist($input); var_dump($output); // bool(false) /** CASE 2 **/ $input = '/home'; var_dump($input); $output = folder_exist($input); // string(5) "/home" var_dump($output); // string(5) "/home" /** CASE 3 **/ $input = '/home/..'; var_dump($input); // string(8) "/home/.." $output = folder_exist($input); var_dump($output); // string(1) "/"Usage 用法
<?php $folder = '/foo/bar'; if(FALSE !== ($path = folder_exist($folder))) { die('Folder ' . $path . ' already exist'); } mkdir($folder); // Continue do stuffWell instead of checking both, you could do if(stream_resolve_include_path($folder)!==false) . 好吧,而不是同时检查两者,您可以执行if(stream_resolve_include_path($folder)!==false) 。 It is slower but kills two birds in one shot. 它的速度较慢,但一枪杀死了两只鸟。
Another option is to simply ignore the E_WARNING , not by using @mkdir(...); 另一种选择是简单地忽略E_WARNING , 而不使用@mkdir(...); (because that would simply waive all possible warnings, not just the directory already exists one), but by registering a specific error handler before doing it: (因为这将简单地放弃所有可能的警告,不仅仅是目录已经存在),而是通过在执行操作之前注册一个特定的错误处理程序来进行:
namespace com\stackoverflow; set_error_handler(function($errno, $errm) { if (strpos($errm,"exists") === false) throw new \Exception($errm); //or better: create your own FolderCreationException class }); mkdir($folder); /* possibly more mkdir instructions, which is when this becomes useful */ restore_error_handler();Second variant in question post is not ok, because, if you already have file with the same name, but it is not a directory, !file_exists($dir) will return false , folder will not be created, so error "failed to open stream: No such file or directory" will be occured. 有问题的帖子的第二个变种不好,因为,如果您已经有相同名称的文件,但它不是目录,则!file_exists($dir)将返回false ,将不会创建文件夹,因此错误"failed to open stream: No such file or directory" 。 In Windows there is a difference between 'file' and 'folder' types, so need to use file_exists() and is_dir() at the same time, for ex.: 在Windows中,“文件”和“文件夹”类型之间存在差异,因此需要同时使用file_exists()和is_dir() ,例如:
if (file_exists('file')) { if (!is_dir('file')) { //if file is already present, but it's not a dir //do something with file - delete, rename, etc. unlink('file'); //for example mkdir('file', NEEDED_ACCESS_LEVEL); } } else { //no file exists with this name mkdir('file', NEEDED_ACCESS_LEVEL); }