PHP Conference Kansai 2025

fwrite

(PHP 4, PHP 5, PHP 7, PHP 8)

fwriteEscribe en un fichero en modo binario

Descripción

fwrite(resource $stream, string $data, ?int $length = null): int|false

fwrite() escribe el contenido de la cadena data en el fichero apuntado por stream.

Parámetros

stream

Resource que apunta a un fichero del sitema que normalmente es creado usando fopen().

data

La cadena a escribir.

length

Si se proporciona la longitud length, la escritura se detendrá después de length bytes, o al final de la cadena (lo que ocurra primero).

Valores devueltos

fwrite() devuelve el número de bytes escritos o false en caso de error.

Errores/Excepciones

La función fwrite() emite una E_WARNING si ocurre un error.

Historial de cambios

Versión Descripción
8.0.0 length ahora es nullable.

Ejemplos

Ejemplo #1 Ejemplo con fwrite()

<?php
$filename
= 'test.txt';
$somecontent = "Añadiendo cadena al fichero\n";

// Asegurémonos de que el fichero es accesible en escritura
if (is_writable($filename)) {

// En nuestro ejemplo, abrimos el fichero $filename en modo de añadir
// El puntero del fichero se coloca al final del fichero
// es ahí donde $somecontent será colocado
if (!$fp = fopen($filename, 'a')) {
echo
"No se puede abrir el fichero ($filename)";
exit;
}

// Escribamos algo en nuestro fichero.
if (fwrite($fp, $somecontent) === FALSE) {
echo
"No se puede escribir en el fichero ($filename)";
exit;
}

echo
"La escritura de ($somecontent) en el fichero ($filename) ha tenido éxito";

fclose($fp);

} else {
echo
"El fichero $filename no es accesible en escritura.";
}
?>

Notas

Nota:

La escritura en un flujo puede terminar antes de que la cadena completa sea escrita. El valor devuelto por la función fwrite() puede ser verificado de la siguiente manera:

<?php
function fwrite_stream($fp, $string) {
for (
$written = 0; $written < strlen($string); $written += $fwrite) {
$fwrite = fwrite($fp, substr($string, $written));
if (
$fwrite === false) {
return
$fwrite;
}
}
return
$written;
}
?>

Nota:

En los sistemas que hacen la distinción entre ficheros binarios y ficheros de texto (por ejemplo, Windows), el fichero debe ser abierto con la opción 'b' incluida en el parámetro de modo de fopen().

Nota:

Si stream está abierto en modo añadir (append), fwrite() será atómico (excepto si el tamaño de data excede el tamaño del bloque del sistema de ficheros, en algunas plataformas, y siempre que el fichero se encuentre en el sistema de ficheros local). Por lo tanto, no es necesario utilizar la función flock() en un recurso antes de llamar a la función fwrite(); todos los datos serán escritos sin interrupción.

Nota:

Si se escribe dos veces en el fichero, los datos serán añadidos al final del fichero; esto significa que el siguiente ejemplo no dará el resultado esperado:

<?php
$fp
= fopen('data.txt', 'w');
fwrite($fp, '1');
fwrite($fp, '23');
fclose($fp);

// el contenido de 'data.txt' es ahora 123 y no 23 !
?>

Ver también

  • fread() - Lectura de un fichero en modo binario seguro
  • fopen() - Abre un fichero o un URL
  • fsockopen() - Abre un socket de conexión Internet o Unix
  • popen() - Abre un proceso de un puntero a un fichero
  • file_get_contents() - Transmite un fichero completo a una cadena
  • pack() - Empaqueta información a una cadena binaria

add a note

User Contributed Notes 10 notes

up
108
nate at frickenate dot com
15 years ago
After having problems with fwrite() returning 0 in cases where one would fully expect a return value of false, I took a look at the source code for php's fwrite() itself. The function will only return false if you pass in invalid arguments. Any other error, just as a broken pipe or closed connection, will result in a return value of less than strlen($string), in most cases 0.

Therefore, looping with repeated calls to fwrite() until the sum of number of bytes written equals the strlen() of the full value or expecting false on error will result in an infinite loop if the connection is lost.

This means the example fwrite_stream() code from the docs, as well as all the "helper" functions posted by others in the comments are all broken. You *must* check for a return value of 0 and either abort immediately or track a maximum number of retries.

Below is the example from the docs. This code is BAD, as a broken pipe will result in fwrite() infinitely looping with a return value of 0. Since the loop only breaks if fwrite() returns false or successfully writes all bytes, an infinite loop will occur on failure.

<?php
// BROKEN function - infinite loop when fwrite() returns 0s
function fwrite_stream($fp, $string) {
for (
$written = 0; $written < strlen($string); $written += $fwrite) {
$fwrite = fwrite($fp, substr($string, $written));
if (
$fwrite === false) {
return
$written;
}
}
return
$written;
}
?>
up
4
divinity76 at gmail dot com
4 years ago
if you need a function that writes all data, maybe try

<?php

/**
* writes all data or throws
*
* @param mixed $handle
* @param string $data
* @throws \RuntimeException when fwrite returned <1 but still more data to write
* @return void
*/
/*private static*/
function fwrite_all($handle, string $data): void
{
$original_len = strlen($data);
if (
$original_len > 0) {
$len = $original_len;
$written_total = 0;
for (;;) {
$written_now = fwrite($handle, $data);
if (
$written_now === $len) {
return;
}
if (
$written_now < 1) {
throw new
\RuntimeException("could only write {$written_total}/{$original_len} bytes!");
}
$written_total += $written_now;
$data = substr($data, $written_now);
$len -= $written_now;
// assert($len > 0);
// assert($len === strlen($data));
}
}
}
up
4
niklesh at example dot com
4 years ago
$handles can also be used to output in console like below example

fwrite(STDOUT, "Console Output");
up
5
Chris Blown
21 years ago
Don't forget to check fwrite returns for errors! Just because you successfully opened a file for write, doesn't always mean you can write to it.

On some systems this can occur if the filesystem is full, you can still open the file and create the filesystem inode, but the fwrite will fail, resulting in a zero byte file.
up
4
Anonymous
9 years ago
// you want copy dummy file or send dummy file
// it is possible to send a file larger than 4GB and write without FSEEK used is limited by PHP_INT_MAX. it works on a system 32-bit or 64-bit
// fwrite and fread non pas de limite de position du pointeur

<?php

$gfz
= filesize_dir("d:\\starwars.mkv"); // 11,5GB
echo 'Z:',$gfz,PHP_EOL;

$fz = fopen('d:\\test2.mkv', 'wb');
$fp = fopen('d:\\starwars.mkv', 'rb');
echo
PHP_EOL;
$a = (float) 0;
while((
$l=fread($fp, 65536))) {
fwrite($fz, $l);
if((
$a+=65536)%5) echo "\r", '>', $a, ' : ' , $gfz;
}

fclose($fp);
fclose($fz);

// test2.mkv' is 11,5GB

function filesize_dir($file) {
exec('dir ' . $file, $inf);
$size_raw = $inf[6];
$size_exp = explode(" ",$size_raw);
$size_ext = $size_exp[19];
$size_int = (float) str_replace(chr(255), '', $size_ext);
return
$size_int;
}
?>
up
6
dharris dot nospam at removethispart dot drh dot net
17 years ago
Some people say that when writing to a socket not all of the bytes requested to be written may be written. You may have to call fwrite again to write bytes that were not written the first time. (At least this is how the write() system call in UNIX works.)

This is helpful code (warning: not tested with multi-byte character sets)

function fwrite_with_retry($sock, &$data)
{
$bytes_to_write = strlen($data);
$bytes_written = 0;

while ( $bytes_written < $bytes_to_write )
{
if ( $bytes_written == 0 ) {
$rv = fwrite($sock, $data);
} else {
$rv = fwrite($sock, substr($data, $bytes_written));
}

if ( $rv === false || $rv == 0 )
return( $bytes_written == 0 ? false : $bytes_written );

$bytes_written += $rv;
}

return $bytes_written;
}

Call this like so:

$rv = fwrite_with_retry($sock, $request_string);

if ( ! $rv )
die("unable to write request_string to socket");
if ( $rv != strlen($request_string) )
die("sort write to socket on writing request_string");
up
2
synnus at gmail dot com
9 years ago
// you want copy dummy file or send dummy file
// it is possible to send a file larger than 4GB and write without FSEEK used is limited by PHP_INT_MAX. it works on a system 32-bit or 64-bit
// fwrite and fread non pas de limite de position du pointeur

<?php

$gfz
= filesize_dir("d:\\starwars.mkv"); // 11,5GB
echo 'Z:',$gfz,PHP_EOL;

$fz = fopen('d:\\test2.mkv', 'wb');
$fp = fopen('d:\\starwars.mkv', 'rb');
echo
PHP_EOL;
$a = (float) 0;
while((
$l=fread($fp, 65536))) {
fwrite($fz, $l);
if((
$a+=65536)%5) echo "\r", '>', $a, ' : ' , $gfz;
}

fclose($fp);
fclose($fz);

// test2.mkv' is 11,5GB

function filesize_dir($file) {
exec('dir ' . $file, $inf);
$size_raw = $inf[6];
$size_exp = explode(" ",$size_raw);
$size_ext = $size_exp[19];
$size_int = (float) str_replace(chr(255), '', $size_ext);
return
$size_int;
}
?>
up
3
Anonymous
15 years ago
If you write with the pointer in the middle of a file, it overwrites what's there rather than shifting the rest of the file along.
up
2
chedong at hotmail dot com
21 years ago
the fwrite output striped the slashes if without length argument given, example:

<?php
$str
= "c:\\01.txt";
$out = fopen("out.txt", "w");
fwrite($out, $str);
fclose($out);
?>

the out.txt will be:
c:^@1.txt
the '\\0' without escape will be '\0' ==> 0x00.

the correct one is change fwrite to:
fwrite($out, $str, strlen($str));
up
3
php at biggerthanthebeatles dot com
21 years ago
Hope this helps other newbies.

If you are writing data to a txt file on a windows system and need a line break. use \r\n . This will write hex OD OA.

i.e.
$batch_data= "some data... \r\n";
fwrite($fbatch,$batch_data);

The is the equivalent of opening a txt file in notepad pressing enter and the end of the line and saving it.
To Top