腾讯 PHP 笔试题,写一个 is_writable 函数的替代函数

今年三月份去腾讯面试过。笔试题有一题是,PHP 中的 is_writable 函数不可信,请写一个函数来替代这个函数。

拿到这个题目,我便想起之前读 CI 框架实现的时候看到 CI 里面写了个 is_really_writable 函数,当时没有注意,只看这个函数的功能,至于 CI 为什么要自己实现一个 is_writable 函数的功能没有去深究。当时,我的解题思路是这样的,既然 is_writable 不可信,那么我就实实在在的尝试去那个文件夹里进行写入,如果可以写则返回 true,否则返回 false,思路是对的,但代码并不是完全无误,有瑕疵。

回到家后我便开始搜索,同时重新仔细查看 CI 的那个函数实现以及说明,原来是因为在 Windows 服务器上如果一个文件夹有只读属性,is_writable 这个函数还是会返回 true,而实际上 php 是不能进行写入的,另外一种情况是,在 unix 服务器上,如果 safe_mode 选项打开,那么 is_writable 函数也是不可信的。

这个事情提醒我,当遇到一个问题时,一定要追查到底,搞明白它的原理以及那样做的理由。

附上 CI 里面 is_really_writable 函数的实现:

function is_really_writable($file)
{
    // If we're on a Unix server with safe_mode off we call is_writable
    if (DIRECTORY_SEPARATOR == '/' AND @ini_get("safe_mode") == false) {
        return is_writable($file);
    }

    // For windows servers and safe_mode "on" installations we'll actually
    // write a file then read it.  Bah...
    if (is_dir($file)) {
        $file = rtrim($file, '/') . '/' . md5(mt_rand(1, 100) . mt_rand(1, 100));

        if (($fp = @fopen($file, FOPEN_WRITE_CREATE)) === false) {
            return false;
        }

        fclose($fp);
        @chmod($file, DIR_WRITE_MODE);
        @unlink($file);
        return true;
    } elseif (!is_file($file) OR ($fp = @fopen($file, FOPEN_WRITE_CREATE)) === false) {
        return false;
    }

    fclose($fp);
    return true;
}

 

4个评论

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注