tmpfile

Creates a temporary file open for reading and writing that is deleted when closed.

Signature
tmpfile(): resource|false
  • Added in PHP 4.0

Return value

resource|falseReturns a file handle like the one fopen() gives, or false on failure.

Errors

Emits an E_WARNING and returns false if the temporary file cannot be created, for example when the temp directory is not writable or full.

tmpfile() opens a uniquely named file in the system temporary directory in w+b mode and returns the handle. You never see the name, and you never have to clean up: the file is removed when the handle is closed with fclose(), when the last reference to it goes out of scope, or when the script ends normally.

When to reach for it

  • Buffering data too big to hold comfortably in memory, such as a multi-hundred-megabyte export.
  • Spooling a stream you will rewind and re-read, where you do not care about the path.
  • Any scratch work where forgetting to delete the file would be a leak.

What trips people up

You get a handle, not a path. stream_get_meta_data($fh)['uri'] often exposes one, but on some platforms the file is already unlinked from the directory tree, so that path may not open. If another process or library needs a real filename, use tempnam().

The mode is w+b, so the pointer sits at the end after writing — rewind() before you read, or you will get an empty string. And the automatic delete only happens on a clean shutdown: a fatal signal, a kill -9 or a segfault can leave the file behind.

For small buffers, php://temp is usually a better fit — it keeps data in memory until it exceeds a threshold and only then spills to disk.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Spool a large database export to disk before streaming it to the client, without leaving files behind on error.
  • Buffer an incoming stream so it can be rewound and validated before being committed.
  • Hold intermediate rows during a multi-pass report that will not fit in memory.

Frequently asked questions

How do I get the filename of a tmpfile handle?

stream_get_meta_data($fh)['uri'] usually reports it, but on some platforms the file is already unlinked and that path cannot be reopened. If you truly need a usable filename, use tempnam() instead.

When is the tmpfile deleted?

On fclose(), when the last reference to the handle is released, or at normal script end. An abnormal termination such as a hard kill can leave the file behind.

What is the difference between tmpfile and php://temp?

tmpfile() always creates a file on disk; php://temp keeps data in memory up to a threshold (2 MB by default) and only then writes to disk. Prefer php://temp for buffers that are usually small.

More examples

Spool rows, then re-read them

Rows are written to disk and then read back through the same handle after rewinding. Closing the handle deletes the spool file, so nothing is left to clean up.

Example · php
<?php
$tmp = tmpfile();
foreach ([['ada', 36], ['alan', 41]] as $row) {
    fputcsv($tmp, $row, ',', '"', '\\');
}

rewind($tmp);
while (($r = fgetcsv($tmp, 0, ',', '"', '\\')) !== false) {
    echo $r[0], ' is ', $r[1], "\n";
}
fclose($tmp);

Cleanup happens even without fclose

When the last reference to the handle disappears, PHP closes it and removes the file. The existence check prints false without any explicit fclose().

Example · php
<?php
function spool(): string {
    $tmp = tmpfile();
    fwrite($tmp, 'transient');
    return stream_get_meta_data($tmp)['uri'];
}

$path = spool();   // handle goes out of scope here
clearstatcache();
var_dump(file_exists($path));
echo "handle released, file gone\n";

php://temp when the data is usually small

php://temp behaves like tmpfile() but keeps the first kilobyte in RAM and only spills to a real file beyond that, avoiding disk I/O for small buffers.

Example · php
<?php
$buf = fopen('php://temp/maxmemory:1024', 'w+b');
fwrite($buf, str_repeat('x', 100));   // stays in memory
rewind($buf);
echo 'bytes: ', strlen(stream_get_contents($buf)), "\n";
echo 'uri: ', stream_get_meta_data($buf)['uri'], "\n";
fclose($buf);

Discussion

  • Be the first to comment on this lesson.