php - is_file 总是返回 false

标签 php symfony laravel

问题

我在使用 PHP 函数 is_file() 时遇到问题。

一些准备工作:我正在使用 PHP 5.5.10 和 Apache 2.4.9 在 32 位 Ubuntu 12.04 上进行开发。

我目前正在重写一些工作代码以将其转换为 Laravel 中的一个库(完成了一个 Facade 和一个 ServiceProvider)。我这样做主要是为了清理自己年少无知(大约6个月前)写的一些代码,以及实现单元测试。我正在编写的库提供了获取契约(Contract)(其中有两种不同类型,还有更多类型)和查找 PDF 文档(扫描的纸质契约(Contract))路径的方法。我找到路径的方法工作正常,测试全部通过。

在我的旧代码中,我曾经这样做:

/**
 * Get a scanned contract and return it to the client
 *
 * @param string $type
 * The contract type. Must be either static::CONTRACT1 or static::CONTRACT2.
 * 
 * @param string $contract_id
 * The contract ID
 *
 * @return Response
 */
public static function get($type, $contract_id)
{
    // get the file name
    //
    $results = static::getFileName($type, $contract_id);

    // did we find a file? if not, throw a ScannedContractNotFoundException
    //
    if(!$results)
        throw new \MyApplication\Exceptions\ScannedContractNotFoundException("No file found for $type contract $contract_id");

    // get the path and file name
    //
    $path = $results['path'];
    $name = $results['name'];

    // get the full path
    //
    $file = $path.$name;

    // get the file size
    //
    $contents = file_get_contents($file);
    $fsize = strlen($contents);

    // push the file to the client
    //
    header("Content-type: application/pdf");
    header("Content-Disposition: inline; filename=\"".$name."\"");
    header("Content-length: $fsize");
    header("Cache-control: private");

    echo $contents;

    exit;
}

而且效果很好。

现在我正在尝试重写它以摆脱 echo 并将实际执行将文件发送到 Controller 的工作的代码移动。该代码将如下所示:

$x = \MyApplication\Models\Contract1::find($id);

$file = \ScannedContracts::getFileName($x);

$path = $file["path"].$file["name"];

return \Response::download($path, $file["name"]);

但是,这段代码抛出一个 FileNotFoundException。抛出异常的代码如下所示:

public function __construct($path, $checkPath = true)
{
    if ($checkPath && !is_file($path)) {
        throw new FileNotFoundException($path);
    }

...

很明显,问题出在 if 语句上,尤其是对 is_file() 的调用。

我已经编写了一个小脚本来使用已知良好的路径对此进行测试,并且 is_file() 返回 false。

当我将文件复制到我的“公共(public)”文件夹时,它工作正常。

the documentation for the is_file() function有注释说父文件夹的权限必须是+x。我已经检查了权限,该文件夹是世界可执行的,父级、祖父级、曾祖父级等也是如此。

有两个可能的混杂因素:首先,我正在使用的文件位于 CIFS/Samba 共享上。我应该提到,所讨论的路径是已安装共享的绝对路径。

我在 SO 上发现的与此最接近的问题是 PHP is_file returns false (incorrectly) for Windows share on Ubuntu ,但这没有解决方案。我还搜索了 PHP 错误报告,但没有任何内容。

其次,一些路径包含空格。我尝试过我能想到的所有方法来逃避它们,但没有用。

在没有解决方案的情况下,我将不得不采用老式的方法,但我真的很想使用 Laravel 提供的功能来实现。

问题

  1. 我是否需要转义传递给 is_file() 的路径中的空格?

  2. 有没有人知道不 a) 需要更改第 3 方库中的代码,或 b) 需要对 CIFS/Samba 服务器上的权限或其他配置进行全面更改的修复或解决方法?

提前致谢!

最佳答案

我认为上传到目录时需要清理文件名

function sanitize_file_name( $str ) {
    return preg_replace("/[^a-z0-9\.]/", "", strtolower($str));
}

关于php - is_file 总是返回 false,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23019699/

相关文章:

php - MySQL 行数总是返回 false

php - 如何根据数据库查询加载特定文件/url

php - 可以安全地将 $HTTP_XXXX_VARS 替换为 $_XXXX

php - Symfony2 之上的多站点 SaaS CMS

php - Paypal 自适应支付服务 550001 错误

php - Laravel 5.1 Auth::attempt() 在 Composer 更新后不起作用

php - Mysql统计表中的行并返回一个整数

php - 使用结果缓存和不使用结果缓存来计时我的 php 函数

php - Symfony2 形式 : set default options depending on form value

php - 拉拉维尔。加入后保持 Eloquent 关系