我正在尝试重命名2个或更多目录中包含的文件。也许以前有人问过这个问题,但我仍然坚持这个问题。任何帮助将不胜感激
主目录:
文件所在的子文件夹:
资源/国家/英格兰/(在此处下载文件)
$dir = scandir($_SERVER['DOCUMENT_ROOT']."/resources/country");
if(!empty($dir) && is_array($dir)){
foreach($dir as $d){
$sub_dir = scandir($_SERVER['DOCUMENT_ROOT']."/resources/country/".$d);
if(!empty($sub_dir)){
foreach($sub_dir as $s_dir){
if($s_dir != '..' && $s_dir != '.'){
$mynew_dir = $_SERVER['DOCUMENT_ROOT']."/resources/country/".utf8_decode($d)."/";
if ($handle = opendir($mynew_dir)) {
while (false !== ($fileName = readdir($handle))) {
//$newName = str_replace("SKU#","",$fileName);
if(is_file($fileName)){
$newName = urlencode($fileName);
if(rename($fileName, $newName)){
print"<div>Rename Successful: Filename:".$fileName." Newname: ".$newName."</div>";
}else{
print"<div>Rename UnSuccessful: Filename:".$fileName." Newname: ".$newName."</div>";
}
}
}
closedir($handle);
}else{
print print"<div>Rename UnSuccessful: Failed to open: " .$d."</div>";
}
}
}
}else{
print"<div>Rename UnSuccessful: Empty</div>";
}
}
}
答案 0 :(得分:0)
is_file()将对待'。'和“ ..”作为文件,并允许它们进入路径。 重命名()需要绝对路径
<?php
$dir = scandir($_SERVER['DOCUMENT_ROOT']."/resources/country");
if(!empty($dir) && is_array($dir))
{
foreach($dir as $d)
{
if(strcasecmp($d, '..')!=0 && strcasecmp($d, '.')!=0) //You need to check the first two files in the base directory as well. Else you will always go one directory back if the path contains '. or '..'
{
$sub_dir = scandir($_SERVER['DOCUMENT_ROOT']."/resources/country/".$d);
if(!empty($sub_dir))
{
foreach($sub_dir as $s_dir)
{
if(strcasecmp($s_dir, '..')!=0 && strcasecmp($s_dir, '.')!=0)
{
$mynew_dir = $_SERVER['DOCUMENT_ROOT']."/resources/country/".$d; // No need to use another '/'
if ($handle = opendir($mynew_dir))
{
while (false !== ($fileName = readdir($handle)))
{
//$newName = str_replace("SKU#","",$fileName);
if(strcasecmp($fileName, '..')!=0 && strcasecmp($fileName, '.')!=0) //is_file treats '.' and '..' as files which you want to avoid
{
$newName = urlencode($fileName);
if(rename($mynew_dir."/".$fileName, $mynew_dir."/".$newName)) //rename() needs an absoulute path
{
print"<div>Rename Successful: Filename:".$fileName." Newname: ".$newName."</div>";
}else{
print"<div>Rename UnSuccessful: Filename:".$fileName." Newname: ".$newName."</div>";
}
}
}
closedir($handle);
}else{
print print"<div>Rename UnSuccessful: Failed to open: " .$d."</div>";
}
}
}
}else{
print"<div>Rename UnSuccessful: Empty</div>";
}
}
}
}
?>
我假设resource /文件夹和此php脚本位于根目录中。 如果要将它们放置在另一个文件夹中,请在$ _SERVER ['DOCUMENT_ROOT']中的所有位置添加文件夹名称。“ / resources / country /”
答案 1 :(得分:0)
原始代码有一个主要问题-目录遍历。基本目录$_SERVER['DOCUMENT_ROOT']."/resources/country"
已被读取多次。
重命名本身发生时,没有检查$fileName
是否确实是文件-也可以重命名目录。
此外,我还删除了一些绝对不必要的错误消息。
第一个答案部分正确,rename()
确实需要绝对路径。
但是,is_file
在提供绝对路径时效果很好。
假设文件夹结构/resourses/country/...
放在服务器文档的根文件夹中(可以是任何东西,不一定是php根文件夹。在很大程度上取决于设置),示例代码如下:
<?php
$dir = scandir($_SERVER['DOCUMENT_ROOT']."/resources/country");
if(!empty($dir) && is_array($dir)) {
foreach($dir as $d) {
/* $dir will always include '.' and '..' as the first two elemets of the array.
* The check below ensures, that you exclude these elements from further traversial.
* If you don't make this check, you will also read the parent of your directory and the directory itself
*/
if($d != '.' && $d != '..') {
/*
* Here, we ensure ourselves that we actually selected a directory and not a file.
*/
if(is_dir($_SERVER['DOCUMENT_ROOT']."/resources/country/".utf8_decode($d)))
{
$sub_dir = $_SERVER['DOCUMENT_ROOT']."/resources/country/".utf8_decode($d)."/";
/*
* Here, no extra checks are needed, we already ensured ourselves that we selected the correct directory.
* We just need to open it and read it's contents.
*/
if ($handle = opendir($sub_dir)) {
while (false !== ($fileName = readdir($handle))) {
/*
* Here is_file() actually take care of all the necessary checks.
* When absolute path is supplied, it will only return true for actual files.
* '.' and '..' will be treated as non-files. Any subfolders will be also ignored.
*/
if(is_file($sub_dir."/".$fileName))
{
/* Here we make file name modifications. It can be any modifications.
* As an axample I added appending 'new_' to file name.
* Also for the sake of not forgetiing we encode the new file name strate away;
*/
$new_fileName = "new_" . $fileName;
$encoded_name = urlencode($new_fileName);
/*
* Here we do the renaming itself.
* As it was said earlier 'rename()' needs an absolute path to work correctly
*/
if(rename($sub_dir."/".$fileName, $sub_dir."/".$new_fileName)) {
print"<div>Rename Successful: Filename: ".$fileName." Newname: ".$new_fileName."</div>";
} else {
print"<div>Rename UnSuccessful: Filename: ".$fileName." Newname: ".$new_fileName."</div>";
}
}
}
closedir($handle);
}
}
}
}
}
我将注释留在了代码内部,以更好地解释代码的作用以及为什么这样做。
上面的示例已经在Windows上进行了测试,并且可以在其中运行。就我所知,Linux必须为此文件夹设置属性x
(可执行)才能使此代码正常工作。