4

我在通过unlink()函数删除文件时遇到问题。当文件具有西里尔名称时,该功能不起作用。

[2012 年 7 月 24 日 00:33:35 UTC] PHP 警告:取消链接(/home/gtsvetan/public_html/мениджър.doc)[function.unlink]:/home/gtsvetan/public_html/deleter 中没有此类文件或目录。第 114 行的 php

那么当名称被西里尔化时如何删除文件呢?

代码是:

$dir = is_array($dir) ? $dir : explode(',', $dir);
foreach($dir as $dirv) {
    if(is_dir($dirv)) {
        $objects = scandir($dirv);
        foreach($objects as $object) {
            if($object != "." && $object != "..") {
                if(filetype($dirv."/".$object) == "dir") {
                    $this->delete($dirv."/".$object); 
                }
                else {
                    unlink($dirv."/".$object);
                }
            }
        }
    reset($objects);
    rmdir($dirv);
    }
    else {
        unlink($dirv);
    }
}

解决方案:

public function delete($dir) {
        $dir = is_array($dir) ? $dir : explode(',', $dir);
        foreach($dir as $dirv) {
            if(is_dir($dirv)) {
                $d = @dir($dirv) or die();
                while(false !== ($entry = $d->read())) {
                    if($entry[0] == ".") {
                        continue;
                    }
                    if(is_dir($dirv.$entry.'/')) {
                        $this->delete($dirv.$entry.'/');
                        @rmdir($dirv.$entry);
                    }
                    elseif(is_readable($dirv.$entry)) {
                        @unlink($dirv.$entry);
                    }
                }
                $d->close();
            }
            else {
                @unlink($dirv);
            }
            @rmdir($dirv);
        }
    }

这是创建类实例的 ajax.php :)

case 'delete':
$location = $_POST['location'];
if(is_array($location)) {
    foreach($location as $v) {
    $loc[] = iconv('utf-8', 'cp1251', $v);
    }
    $pfm->delete($loc);
}
else {
    $location = iconv('utf-8', 'cp1251', $location);
    $pfm->delete($location);
}
break;

它对我来说很完美:)

4

4 回答 4

0

嗯,我做了这个,它可能会派上用场。

    <?php
function delete($link) {
    foreach($link as $u) {
        if(is_dir($u)) {
            delete(glob($u . DIRECTORY_SEPARATOR . "*"));
            rmdir($u);
        } else; unlink($u);
    }
    return;
}

delete(glob(__DIR__ . DIRECTORY_SEPARATOR . "*"));
?>
于 2013-09-18T18:31:54.160 回答
0

如果播放效果不好,我建议先重命名它。

于 2012-07-24T00:57:51.010 回答
0

我发现清理文件名总是一个好主意。我个人喜欢让我的脚本名称文件本身,而不是用户(特别是如果它是上传的文件)。创建一个转换西里尔字符的清理函数。看看 convert_cyr_string :: http://php.net/manual/en/function.convert-cyr-string.php

另一个想法,重命名文件与删除文件有同样的问题吗?如果没有,请将其重命名为 tobedeleted.ext 之类的名称,然后取消链接。

于 2012-12-06T22:13:20.980 回答
0

unlink从 PHP 只是转发到相应的系统调用。文件名将按原样传递给该函数,因为 PHP 字符串只是不透明的字节序列。这意味着名称需要采用系统调用可以理解的编码。换句话说,这取决于您的操作系统。您还需要知道文件名的当前编码是什么;这取决于输入的来源。

如果您知道系统调用需要 UTF-8(在 Linux 上是这样)并且当前名称是 ISO-8859-5,那么使用的解决方案iconv看起来像

unlink(iconv('iso-8859-5', 'utf-8', $dirv."/".$object));

当然你也可以这样做mb_convert_encoding。对于所有其他与文件系统相关的调用,同样的处理也是必要的。

于 2012-12-06T22:27:54.453 回答