(PHP 4, PHP 5, PHP 7, PHP 8)
fwrite — Escribe en un fichero en modo binario
fwrite() escribe el contenido de la cadena
data en el fichero apuntado por
stream.
fwrite() devuelve el número de bytes escritos o false si ocurre un error.
La función fwrite() emite una E_WARNING si ocurre un error.
| Versión | Descripción |
|---|---|
| 8.0.0 |
length ahora es nullable.
|
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.";
}
?>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
streamestá abierto en modo añadir (append), fwrite() será atómico (excepto si el tamaño dedataexcede 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 ! ?>
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;
}
?>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));
}
}
}$handles can also be used to output in console like below example
fwrite(STDOUT, "Console Output");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.// 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;
}
?>// 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;
}
?>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));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");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.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.