文件“资源ID#11”不存在

时间:2019-02-09 05:43:29

标签: php laravel

我正在尝试创建一个将数组转换为纯文本和文件的类。 Plaintext可以正常工作,但是当我尝试将其另存为tmpfile并共享时,出现了错误。

我的控制器如下:

public method index() {
    $props = ['foo'=>'bar']; //array of props;
    return response()->download(MyClass::create($props);
    // I've also tried using return response()->file(MyClass::create($props);
}

我的班级如下:

class MyClass
{
    // transform array to plain text and save
    public static function create($props)
    {

        // I've tried various read/write permissions here with no change.
        $file = fopen(tempnam(sys_get_temp_dir(), 'prefix'), 'w');
        fwrite($file,  implode(PHP_EOL, $props));

            return $file;
    }

    // I've also tried File::put('filename', implode(PHP_EOL, $props)) with the same results.
}

我得到一个找不到文件的异常:

  

The file "Resource id #11" does not exist.

我尝试过tmpfile,tempname和其他文件,并得到相同的异常。我尝试通过MyClass :: create($ props)['uri'],然后得到

  

The file "" does not exist

这是由于我的env(代客)引起的错误还是我做错了?

1 个答案:

答案 0 :(得分:2)

您的代码混合了文件名文件句柄的使用:

  • tempnam()返回一个字符串:新创建的临时文件的路径
  • fopen()访问给定路径的文件,并返回“资源”-PHP中的一种特殊类型,用于引用系统资源。在这种情况下,资源更具体地是“文件句柄”
  • 如果您使用期望使用字符串的资源,PHP只会为您提供一个描述资源的标签,例如“ Resource id#11”;据我所知,没有办法找回打开文件句柄的文件名

在您的create定义中,$filefopen()的结果,“资源”值(打开的文件句柄)也是。由于您return $fileMyClass::create($props)的结果也是文件句柄。

Laravel response()->download(...) method需要一个字符串,即要访问的文件名;给定资源后,它将无提示地将其转换为字符串,从而导致看到错误。

要获取文件名,您需要对create函数进行两项更改:

  • tempnam(sys_get_temp_dir(), 'prefix')的结果放入变量中,例如$filename,然后再致电$file = fopen($filename, 'w');
  • 返回$filename而不是$file

您还应该在返回之前向fclose($file)添加一个调用,以在将数据写入文件后干净地关闭文件。