file-exists与mkdir联合使用遇到的目录检测失败的问题
有如下一段代码:
if (!file_exists($uploadPath)) {
// 0777可读可写可执行 true最高权限
mkdir($uploadPath, 0777, true);
// 改变他的权限
chmod($uploadPath, 0777);
}
先检测上传路径文件夹是否存在,如果不存在,那么就创建这个文件夹,$uploadPath=D:\xampp\htdocs\xin-card\statics\templates-packages\2023\03\249b7052c117013e8d4754d1706df1ea 是一个文件夹
当我使用上传接口,上传多个文件的时候,比如上传1.jpg,2.html,3.png等等的时候,发现有偶然性的出现如下报错:
mkdir(): File exists in -- mkdir():文件存在于
意思就是文件已经存在了。
究其原因,是因为一起同时发送多个文件的时候,形成了并发请求,出现了竞争条件情况。
这时候解决方法有2个:
1、在发送上传请求之前,先请求一次创建目录的操作,先在服务器创建目录,成功返回目录,然后在之后的多文件上传的时候(上传多文件,实际就是每次发送一个单个文件,比如有4个单文件,那么就发送4次上传请求)携带要保存的目录作为参数即可。
2、参考下面这段代码,使用is_dir替代file_exists
$filepath = '/media/static/css/common.css';
// is_dir is more appropriate than file_exists here is_dir比这里的file_exists更合适
if (!is_dir(dirname($filepath))) {
if (true !== @mkdir(dirname($filepath), 0777, TRUE)) {
if (is_dir(dirname($filepath))) {
// The directory was created by a concurrent process, so do nothing, keep calm and carry on
// 目录是由一个并发过程创建的,所以什么都不做,保持冷静,继续
} else {
// There is another problem, we manage it (you could manage it with exceptions as well)
$error = error_get_last();
trigger_error($error['message'], E_USER_WARNING);
}
}
}
以下是搜索到关于这个问题的摘抄:
我偶然发现了 PHP 中 mkdir 函数的每一个奇怪行为。下面是我的简单代码示例。
$filepath = '/media/static/css/common.css';
if (!file_exists(dirname($filepath)))
{
mkdir(dirname($filepath), 0777, TRUE);
}
“媒体”文件夹始终存在。必须创建“媒体”文件夹中的所有文件夹。在处理 common.css 文件之前,我想创建一个文件夹“/static/css”。
mkdir 偶尔抛出异常“文件存在”。如果它不存在,我试图创建一个文件夹。我假设“文件存在”是一个常见错误,因此该文件夹存在。
我知道我给你的信息很少,这确实是一个奇怪的错误。也许您可以给我任何建议,我必须做什么以及如何测试该错误并找到瓶颈。
服务器:CentOS 6.4 版
最佳答案
这是竞争条件情况。你应该这样做:
$filepath = '/media/static/css/common.css';
// is_dir is more appropriate than file_exists here
if (!is_dir(dirname($filepath))) {
if (true !== @mkdir(dirname($filepath), 0777, TRUE)) {
if (is_dir(dirname($filepath))) {
// The directory was created by a concurrent process, so do nothing, keep calm and carry on
} else {
// There is another problem, we manage it (you could manage it with exceptions as well)
$error = error_get_last();
trigger_error($error['message'], E_USER_WARNING);
}
}
}
引用:
- https://www.drupal.org/files/1642532-drush-mkdir-race-condition.patch
- https://github.com/KnpLabs/Gaufrette/blob/master/src/Gaufrette/Adapter/Local.php#L260
- https://github.com/symfony/symfony/commit/04834521f1298c8fee2704b1c4b1df43b655eb60
关于php - mkdir 函数抛出异常 'File exists' 即使在检查该目录不存在之后,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19964287/