fopen

Opens a file or URL and returns a stream resource for reading or writing.

Signature
fopen(string $filename, string $mode, bool $use_include_path = false, ?resource $context = null): resource|false
  • Added in PHP 4.0.0

Parameters

ParameterTypeDescription
$filenamestringPath to the file, or a URL using a registered stream wrapper such as php://memory.
$modestringAccess mode: r, r+, w, w+, a, a+, x, x+, c or c+, optionally with b or t appended.
$use_include_pathoptionalbool= falseAlso search the include_path for the file.
$contextoptional?resource= nullA stream context from stream_context_create(), or null for none.

Return value

resource|falseA file pointer resource on success, or false on failure.

Errors

Emits an E_WARNING and returns false if the file cannot be opened or if the mode is not a valid one; throws a ValueError if filename contains a null byte.

Changelog

  • PHP 7.0.16, 7.1.2The 'e' mode option (close-on-exec) was added.

fopen gives you a stream handle instead of a string. Everything else in the f* family — fgets, fread, fwrite, fseek, flock, fputcsv — works on the resource it returns.

Choosing a mode

ModeReadWriteTruncatesCreatesStarts at
ryesnononostart
r+yesyesnonostart
wnoyesyesyesstart
w+yesyesyesyesstart
anoyesnoyesend
xnoyesnofails if existsstart
cnoyesnoyesstart

When to reach for it

Use fopen when the file is too big to hold in memory, when you need to read and write the same handle, or when you need a lock. For a small file you just want as a string, file_get_contents is shorter and faster.

What trips people up

Mode 'w' truncates immediately — before any lock, before any check. If you are locking, use 'c' or 'c+'. Mode 'a' always appends at the end regardless of fseek. And always fclose, or at least let the handle fall out of scope; leaked handles exhaust the process limit in long-running workers.

Example

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

When to use it

  • Stream a multi-gigabyte log file line by line with fgets instead of loading it all.
  • Open a file with mode 'x' so the call fails if another process already created it.
  • Get an in-memory stream with php://memory to build CSV output without touching disk.

Frequently asked questions

What is the difference between fopen modes w and a?

`w` truncates the file to zero bytes on open and writes from the start; `a` keeps the existing content and always writes at the end. Both create the file if it does not exist.

Do I have to call fclose after fopen?

PHP closes the handle when the script ends or the resource goes out of scope, but you should call `fclose` explicitly — it flushes buffers immediately and prevents handle exhaustion in long-running or looping scripts.

Why does fopen return false?

The file does not exist for a read mode, the directory is not writable, permissions deny access, or with mode `x` the file already exists. PHP emits an E_WARNING naming the reason.

More examples

Streaming a large file without loading it

The count comes out as 142 — every seventh request from 7 to 994. Only one line is ever in memory at a time, which is the whole reason to use `fopen` over `file()` on a large log.

Example · php
<?php
$fh = fopen('big.log', 'w');
for ($i = 1; $i <= 1000; $i++) {
    fwrite($fh, "request $i status=" . ($i % 7 === 0 ? 500 : 200) . "\n");
}
fclose($fh);

$errors = 0;
$fh = fopen('big.log', 'r');
while (($line = fgets($fh)) !== false) {
    if (str_contains($line, 'status=500')) $errors++;
}
fclose($fh);

echo "errors: $errors of 1000\n";
unlink('big.log');

Mode x refuses to clobber an existing file

The first open succeeds and the second dumps `bool(false)`. Mode `x` performs the exists-check and the create as one atomic operation, which makes it a safer lock-file primitive than `file_exists()` followed by a write.

Example · php
<?php
$first = fopen('once.lock', 'x');
var_dump($first !== false);
fwrite($first, 'owned');
fclose($first);

$second = @fopen('once.lock', 'x');   // already exists
var_dump($second);

unlink('once.lock');

An in-memory stream needs no disk at all

The stream behaves exactly like a file handle — write, rewind, read back — but nothing is created on disk. This is the usual way to build CSV or fixture data for functions that insist on a resource.

Example · php
<?php
$fh = fopen('php://memory', 'r+');

fwrite($fh, "id,name\n");
fwrite($fh, "1,Ada\n");
fwrite($fh, "2,Grace\n");

rewind($fh);
echo stream_get_contents($fh);
echo 'bytes: ', ftell($fh), "\n";

fclose($fh);

Discussion

  • Be the first to comment on this lesson.