简体   繁体   中英

The file “Resource id #11” does not exist

I'm trying to create a class that converts an array into plaintext and file. Plaintext works fine however when I try to save it as a tmpfile and share it I'm getting errors.

My controller looks like:

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);
}

And my class looks like:

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.
}

And I'm getting a file not found exception:

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

I've tried tmpfile, tempname and others and get the same exception. I've tried passing MyClass::create($props)['uri'] and I got

The file "" does not exist

Is this an error due to my env (valet) or am I doing this wrong?

Your code is mixing up usage of filenames and file handles :

  • tempnam() returns a string: the path to a newly created temporary file
  • fopen() accesses a file at a given path, and returns a "resource" - a special type in PHP used to refer to system resources; in this case, the resource is more specifically a "file handle"
  • if you use a resource where a string was expected, PHP will just give you a label describing the resource, such as "Resource id #11"; as far as I know, there is no way to get back the filename of an open file handle

In your create definition, $file is the result of fopen() , so is a "resource" value, the open file handle. Since you return $file , the result of MyClass::create($props) is also the file handle.

The Laravel response()->download(...) method is expecting a string, the filename to access; when given a resource, it silently converts it to string, resulting in the error seen.

To get the filename, you need to make two changes to your create function:

  • Put the result of tempnam(sys_get_temp_dir(), 'prefix') in a variable, eg $filename , before calling $file = fopen($filename, 'w');
  • Return $filename instead of $file

You should also add a call to fclose($file) before returning, to cleanly close the file after writing your data to it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM