开发者

How to make is_dir($FoLdEr) case insensitive in php?

I need is_dir() to don't care about if the folder or the argument is upper or lower case, or a mix of upper and lower.

So if the foldername is "My Folder" and I run is_dir("mY FoLdEr")开发者_如何学JAVA the result should be true.


That's not up to PHP. That's up to operating system and filesystem that PHP is running on. Windows is case insensitive but every version of Unix/Linux is case sensitive.

Let me put it another way: is_dir() is basically a wrapper to a system call or it will use the results of system calls on file info. Those system calls will either return something or not if, by the rules of that operating system and filesystem, a file is found with the matching name. PHP can't change this so no you can't just make is_dir() be case insensitive on Linux.

The best you can do is get a list of files in the directory and loop through them to test to see if any match a case insensitive comparison to what you're looking for.

Note: you might get multiple hits eg "HOME" and "Home" will both match "home". What would such a function (that you want) do in this case?

Alternatively you can change all your filenames to lowercase and then you can use the lowercase version of your input to find the specified file.


You can use regular expressions. I am not quite sure on the syntax in php:

is_dir("[mM][yY] [fF][oO][lL][dD][eE][rR]")

They may be a better regexp for it.


I had an issue where I needed to validate a directory path. I didn't want to have a mixture of similarly name directories in different cases. i.e. my\dir and My\Dir. I tried the grep approach mentioned by Filip glob('{mM}{yY} {fF}{oO}{lL}{dD}{eE}{rR}', GLOB_BRACE) but I found that if the directory name was longer than about 8 characters it would grind to a halt. So this is my solution for a case insensitive is_dir();

$path  = '/';
$parts = explode(DIRECTORY_SEPARATOR, '/My/DirecTorY/pATh');

foreach($parts as $key => $dir) {
    $isUnique = true;

    if (is_dir($path . DIRECTORY_SEPARATOR . $dir)) {
        $path .= DIRECTORY_SEPARATOR . $dir;
        $isUnique = false;
    } else {
        $iterator = new DirectoryIterator($path);
        $name = strtolower($dir);

        foreach($iterator as $file) {
            $filename = $file->getFilename();
            if($file->isDir() && strtolower($filename) == $name) {
                $path .= DIRECTORY_SEPARATOR . $filename;
                $isUnique = false;
                break;
            }
        }
    }

    if($isUnique) {
        $path .= DIRECTORY_SEPARATOR 
              . implode(DIRECTORY_SEPARATOR, array_slice($parts, $key));
        break;
    } 
}

var_dump($isUnique, $path);


Dirty way could be getting list of all directories in actual dir and compare theirs strtolower()-ed names with desired name


here is my solution:

function is_dir_ci($path){
    $glob_path='';
    for ($i=0; $i<strlen($path); $i++) {
        if(preg_match('/^\p{Latin}+$/',$path[$i])){
            $glob_path.='['.strtolower($path[$i]).strtoupper($path[$i]).']';
        }else 
            $glob_path.=$path[$i];
    }
    return !empty(glob($glob_path,GLOB_BRACE));
}

is_dir_ci('/path/With/Cap-Case or not/');

it basicaly does transform the path from

'/path/With/Cap-Case or not/'

to

'/[pP][aA][tT][hH]/[wW][iI][tT][hH]/[cC][aA][pP]-[cC][aA][sS][eE] [oO][rR] [nN][oO][tT]/'

But as only knowing there is dir with some cap-letters changed, I think a better function should be:

function get_correct_dir($path){
    $glob_path='';
    for ($i=0; $i<strlen($path); $i++) {
        if(preg_match('/^\p{Latin}+$/',$path[$i])){
            $glob_path.='['.strtolower($path[$i]).strtoupper($path[$i]).']';
        }else 
            $glob_path.=$path[$i];
    }
    return glob($glob_path,GLOB_BRACE);
}

var_export( get_correct_dir('/path/With/Cap-Case or not/') )
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜