【问题标题】:check if file exist in folder检查文件夹中是否存在文件
【发布时间】:2012-02-05 06:32:23
【问题描述】:

我的脚本:

$secret = check_input($_GET['secret']);
if(isset($_POST['register'])) {
    if (isset($secret) || !empty($secret)) {
        if (file_exists(ROOT . '/intl/codes/' . $secret)) {
            unlink(ROOT . '/intl/codes/' . $secret);
            $trusted = 'yes';
        } else {
            $trusted = 'no';
        }
    }
//$_POST['register'] register details...
}
  1. 还有其他方法(更简单等)吗?
  2. 如果$secret 不存在于/codes/ 文件夹中,它会产生Warning: unlink Is a directory 如何摆脱它?
  3. 为什么$trusted 总是给yes,即使文件不存在?

【问题讨论】:

    标签: php file-exists


    【解决方案1】:

    要删除目录,您应该使用rmdir() 而不是unlink()

    $secret = check_input($_GET['secret']);
    if(isset($_POST['register'])) {
        if (!empty($secret)) {
            if(file_exists(ROOT . '/intl/codes/' . $secret)) {
                rmdir(ROOT . '/intl/codes/' . $secret);
                $trusted = 'yes';
            } else {
                $trusted = 'no';
            }
        }
        //$_POST['register'] register details...
    }
    

    虽然,这里存在严重的安全风险!如果您的check_input() 没有正确清理$secret,您可以rmdir('/intl/codes/../') 这与删除/intl/ 相同。 试试这样的:

    $allowed = ROOT. '/intl/codes/';
    $path = realpath($allowed . check_input($_GET['secret']));
    
    if(strpos($path, $allowed) === 0) {  //Check that $path is within allowed directory
        if(is_dir($path)) {
            rmdir($path);
        } else if(file_exists($path)) {
            unlink($path);
        } else {
            echo "File/folder not found";
        }
    } else {
        echo "Untrusted user tried to delete outside of allowed directory";
    }
    

    【讨论】:

      【解决方案2】:
      1. 您可以只使用 if (!empty($secret)) - empty() 返回 TRUE 以获得 NULL 值。

      2. 使用if (file_exists(ROOT . '/intl/codes/' . $secret) && !is_dir(ROOT . '/intl/codes/' . $secret)) 检查您的文件是否不是目录并消除该警告。如果您仍想删除目录,请使用rmdir() 函数。

      3. file_exists() 也为目录返回TRUE。因此,您还应该检查参数是否为 is_dir() 的目录,如我之前所说。

      【讨论】:

        【解决方案3】:
            if (file_exists(ROOT . '/intl/codes/' . $secret)) {
                unlink(ROOT . '/intl/codes/' . $secret);
                $trusted = 'yes';
            } else {
                $trusted = 'no';
            }
        

        还有其他方法吗(更简单等)?

        不,唯一的方法是使用file_exists

        如果 /codes/ 文件夹中不存在 $secret,则会产生警告:unlink Is a directory 如何摆脱它?

        似乎$secret 指向一个目录。执行路径到达unlink,因为if 部分返回true。所以它存在。要删除目录,请使用rmdir()

        即使文件不存在,为什么 $trusted 总是给出是?

        因为unlink 将其删除并将$trusted 设置为yes。当您在删除后搜索时,您会看到它不存在,但 $trusted 包含 yes

        【讨论】:

          【解决方案4】:

          显然您的$secret 是一个空字符串,但它通过了您的isset() 测试。 所以目录ROOT . '/intl/codes/'确实存在(因此通过file_exists()检查),但你不能unlink()目录(这也不是你的意图)。

          确保$_GET['secret'] 中有非空内容并验证check_input() 函数。

          附:您可能应该删除 isset($secret) 部分条件。 !empty($secret) 在这里就足够了,它会修复你的脚本。

          【讨论】:

            【解决方案5】:

            如关于file_exists()的php文档所述:

            Checks whether a file or directory exists
            

            我对您的问题 #3 的唯一猜测是:您检查文件是否存在并且确实存在。只是,不是文件,是目录。

            至于 #2,也如错误消息所述,您可以执行以下操作:

            $file_to_check = 根。 '/intl/codes/' 。 $秘密;

            if (file_exists($file_to_check)) {
                if( !is_dir( $file_to_check ) )
                    unlink($file_to_check);
                else
                    rmdir( $file_to_check );
                $trusted = 'yes';
            }
            

            对于你的第一个问题,你可能会做这样的事情:

            $secret = input_get($_GET['secret']);
            if(isset($_POST['register']) && !empty($secret)) {
            
                $file_to_check = ROOT . '/intl/codes/' . $secret;
                if (file_exists($file_to_check)) {
                    if( !is_dir( $file_to_check ) )
                        unlink($file_to_check);
                    else
                        rmdir( $file_to_check );
                    $trusted = 'yes';
                } else {
                    $trusted = 'no';
                }
            }
            
            function input_get($key, $default = ""){
            
                if(!isset($_GET[$key])){
                    return $default;
                } else {
                    //do input cleanup first, if you want
                    return $_GET[$key];
                }
            }
            

            一点解释:

            1. 我不知道check_input() 是做什么的,所以我为$_GET[] 创建了包装函数input_get()。它无需执行isset() 并填写默认值。
            2. 我将ROOT . '/intl/codes/' . $secret; 放入变量$file_to_check,这样您就不必一次又一次地键入它。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2016-05-20
              • 2011-11-15
              • 2015-11-06
              • 2012-07-18
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多