php 您访问的页面不存在!

hxzsmxv2  于 2023-05-16  发布在  PHP
关注(0)|答案(1)|浏览(68)

我正在尝试创建一个类,它可以将数组转换为明文和文件。纯文本工作正常,但是当我试图将其保存为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(代客)造成的错误,还是我做错了?

pcww981p

pcww981p1#

您的代码混淆了 filenamesfile handles 的用法:

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

在您的create定义中,$filefopen()的结果,因此是一个“资源”值,即打开的文件句柄。因为你是return $file,所以MyClass::create($props)的结果也是文件句柄。
Laravel response()->download(...)方法需要一个字符串,即要访问的文件名;当给定一个资源时,它会默默地将其转换为字符串,导致出现错误。
要获取文件名,需要对create函数进行两处修改:

  • tempnam(sys_get_temp_dir(), 'prefix')的结果放入变量中,例如$filename,在调用$file = fopen($filename, 'w');之前
  • 返回$filename而不是$file

您还应该在返回之前添加对fclose($file)的调用,以便在将数据写入文件后干净地关闭该文件。
作为fopen/fwrite/fclose序列的替代方案,您可以使用file_get_contents(),它接受一个文件名(作为字符串)和一些数据(作为字符串),并在一次调用中创建或覆盖整个文件。

相关问题