我遇到了PHP函数is_file()
的问题。
一些预备知识:我正在使用PHP 5.5.10和Apache 2.4.9在32位Ubuntu 12.04上进行开发。
我目前正在重写一些工作代码,将其转换为Laravel中的库(使用Facade和ServiceProvider完成)。我这样做主要是为了清理我在年轻和愚蠢时(大约6个月前)编写的一些代码并实施单元测试。我正在编写的图书馆提供了签订合同的方法(其中有两种不同的类型,还有更多),并找到PDF文档的路径(扫描的纸质合同)。我找到路径的方法工作正常,测试都在通过。
在我的旧代码中,我曾经这样做过:
/**
* 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
并移动实际执行将文件发送到控制器的工作的代码。该代码将如下所示:
$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提供的功能。
我是否需要在传递给is_file()
的路径中转义空格?
是否有人知道修复或解决方法不是a)要求更改第三方库中的代码,或b)是否需要批量更改CIFS / Samba服务器上的权限或其他配置?
提前致谢!
答案 0 :(得分:1)
我认为您需要在上传到目录
时清理文件名function sanitize_file_name( $str ) {
return preg_replace("/[^a-z0-9\.]/", "", strtolower($str));
}