简体   繁体   中英

how to rename files in different directories?

I am trying to rename the files contained in 2 or more directories. Maybe this question was asked before but I'm stuck on this problem. Any help is greatly appreciated

main directory:

  • resources/country

sub folder where files located:

  • resources/country/USA/ (fileshere)
  • resources/country/Thailand/ (fileshere)
  • resources/country/England/ (fileshere)

     $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>"; } } }

is_file() will treat '.' and '..' as files and will allow them in the path. rename() needs absolute path

<?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>";                   
                }
            }
        }
    }

?>

I assume that the resource/ folder and this php script are in root directory. If you want to place them inside another folder, add the folder name everywhere in $_SERVER['DOCUMENT_ROOT']."/resources/country/"

Original code had a main problem - directory traversial. The base directory $_SERVER['DOCUMENT_ROOT']."/resources/country" was read multiple times.

When the renaming itself occured, there were no checks if the $fileName is aclually a file - it was possible to rename directories as well.

Also there were several absolutely un-necessary error messages, which i removed.

The first answer was partly correct, rename() does need an absolute path. However is_file works perfectly fine when you supply it an absolute path.

Assuming folder structure /resourses/country/... is placed in the servers document root folder(can be anything, not necessarly php root folder. Depends greatly on setups) the code for working exapmle will look like:

<?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);
                }
            }
        }
    }
}

I left the comments inside the code, to explain a little better what the code does and why it does it.

The above example was tested on Windows, and works there. Linux can have problems with this, as far as I know folder must have attribute x (executable) set, for this code to work.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM