file_put_contents

Writes a string, array or stream to a file in one call, creating the file if needed.

Signature
file_put_contents(string $filename, mixed $data, int $flags = 0, ?resource $context = null): int|false
  • Added in PHP 5.0.0

Parameters

ParameterTypeDescription
$filenamestringPath to the file to write. It is created if it does not exist.
$datamixedThe data to write: a string, a one-dimensional array (joined with no glue), or a stream resource whose remaining contents are copied.
$flagsoptionalint= 0Bitmask of FILE_USE_INCLUDE_PATH, FILE_APPEND and LOCK_EX.
$contextoptional?resource= nullA stream context from stream_context_create(), or null for none.

Return value

int|falseThe number of bytes written, or false on failure.

Errors

Emits an E_WARNING and returns false if the file cannot be opened or written; throws a ValueError if filename contains a null byte or if data is an unsupported type.

file_put_contents is the write-side twin of file_get_contents: it opens, writes, and closes in one statement. By default it truncates the file, so the contents are replaced, not added to. Pass FILE_APPEND when you want to add to the end instead.

When to reach for it

  • Dumping a rendered string, a serialized array or JSON to disk.
  • Appending a single line to a log file.
  • Copying a stream to a file — $data accepts a resource, and PHP will drain it for you.

What trips people up

Two processes appending at once will interleave garbage unless you add LOCK_EX. Combine flags with |: FILE_APPEND | LOCK_EX. Note that even with LOCK_EX, a reader using plain file_get_contents takes no lock and can still read a half-written file — for real atomicity, write to a temporary file and rename() it into place.

The return value is a byte count, and writing an empty string returns 0, which is falsy. As with the read side, compare with === false. Only one-dimensional arrays are supported: the call is equivalent to implode('', $array), so a nested array does not throw — each inner array is converted to the literal string Array and PHP emits an “Array to string conversion” warning.

Example

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

When to use it

  • Cache a rendered HTML fragment to disk so the next request can serve it directly.
  • Append a timestamped audit line to a log file with FILE_APPEND | LOCK_EX.
  • Write json_encode output to a data file that another job picks up.

Frequently asked questions

How do I append to a file instead of overwriting it with file_put_contents?

Pass `FILE_APPEND` as the third argument: `file_put_contents($f, $data, FILE_APPEND)`. Without it the file is truncated to zero bytes before writing.

Does file_put_contents create the file if it does not exist?

Yes, it creates the file, but not the directories above it. If the parent directory is missing you get an E_WARNING and `false` — call `mkdir($dir, 0777, true)` first.

Is file_put_contents with LOCK_EX safe for concurrent writes?

It stops two writers from interleaving, but it does not stop a concurrent reader from seeing a partial file. For a guaranteed all-or-nothing update, write to a temp file and `rename()` it over the target.

More examples

Truncate versus append

The second write prints `beta` only — `alpha` is gone, because the default behaviour truncates. The FILE_APPEND write prints `beta|gamma|`, showing the flag is what keeps existing content.

Example · php
<?php
file_put_contents('notes.txt', "alpha\n");
file_put_contents('notes.txt', "beta\n");              // replaces
echo "after second write: ", trim(file_get_contents('notes.txt')), "\n";

file_put_contents('notes.txt', "gamma\n", FILE_APPEND); // adds
echo "after append: ", str_replace("\n", '|', file_get_contents('notes.txt')), "\n";

unlink('notes.txt');

Writing an array of lines properly

The naive write produces `redgreenblue` on one line. Joining with `PHP_EOL` first gives `red/green/blue/` after the separators are made visible — the array form concatenates without any glue.

Example · php
<?php
$lines = ['red', 'green', 'blue'];

file_put_contents('bad.txt', $lines);
echo "naive: ", file_get_contents('bad.txt'), "\n";

file_put_contents('good.txt', implode(PHP_EOL, $lines) . PHP_EOL);
echo "joined: ", str_replace(PHP_EOL, '/', file_get_contents('good.txt')), "\n";

unlink('bad.txt');
unlink('good.txt');

Atomic write via a temp file and rename

Readers only ever see the complete file, because `rename()` swaps it into place in a single filesystem operation. The final line prints `false`, confirming the temp file is gone.

Example · php
<?php
$target = 'settings.json';
$tmp    = $target . '.tmp';

file_put_contents($tmp, json_encode(['theme' => 'dark'], JSON_PRETTY_PRINT));
rename($tmp, $target);   // atomic on the same filesystem

echo file_get_contents($target), "\n";
echo "temp file left behind: ", var_export(file_exists($tmp), true), "\n";

unlink($target);

Discussion

  • Be the first to comment on this lesson.