ConFoo 2025

fwrite

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

fwriteЗаписывает данные в файл в бинарно-безопасном режиме

Описание

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

Функция fwrite() записывает содержимое data в файловый поток stream.

Список параметров

stream

Ресурс (resource) указателя файловой системы, который обычно создают функцией fopen().

data

Строка, которую нужно записать.

length

Функция остановит запись через length байтов, если значение length — целое число (int), или когда достигнет конца строки data, в зависимости от того, что произойдёт раньше.

Возвращаемые значения

Функция fwrite() возвращает количество записанных байтов или false, если возникла ошибка.

Ошибки

Функция fwrite() выдаёт ошибку уровня E_WARNING в случае ошибки.

Список изменений

Версия Описание
8.0.0 Параметр length теперь принимает значение null.

Примеры

Пример #1 Простой пример использования функции fwrite()

<?php

$filename
= 'test.txt';
$somecontent = "Добавить это к файлу\n";

// Вначале убедимся, что файл существует и доступен для записи.
if (is_writable($filename)) {

// В примере мы открываем $filename в режиме «записи в конец».
// Поэтому смещение установлено в конец файла и
// значение переменной $somecontent допишется в конец файла при вызове функции fwrite().
if (!$fp = fopen($filename, 'a')) {
echo
"Не могу открыть файл ($filename)";
exit;
}

// Записываем значение переменной $somecontent в открытый файл.
if (fwrite($fp, $somecontent) === FALSE) {
echo
"Не могу произвести запись в файл ($filename)";
exit;
}

echo
"Ура! Записали ($somecontent) в файл ($filename)";

fclose($fp);
} else {
echo
"Файл $filename недоступен для записи";
}

?>

Примечания

Замечание:

Запись в сетевой поток может прекратиться до завершения записи строки. Значение, которое возвращает функция fwrite(), можно проверить:

<?php

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;
}

?>

Замечание:

В системах, которые различают двоичные и текстовые файлы (например, операционные системы Windows), файл должен быть открыт с флагом «b» в конце аргумента mode функции fopen().

Замечание:

Если функция fopen() открыла дескриптор stream в режиме «добавление в конец», вызовы функции fwrite() будут атомарными (если размер data не превышает размер блока файловой системы, на некоторых платформах, и пока файл хранится в локальной файловой системе). То есть не нужно блокировать ресурс функцией flock() перед вызовом функции fwrite(); данные будут записаны без прерываний.

Замечание:

При повторной записи в файловый указатель, данные будут добавлены в конец файла:

<?php

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

// Теперь файл 'data.txt' содержит 123, а не 23!

?>

Смотрите также

  • fread() - Читает файл в бинарно-безопасном режиме: как последовательность байтов
  • fopen() - Открывает файл или URL-адрес
  • fsockopen() - Открывает соединение с сокетом интернет- или Unix-домена
  • popen() - Открывает файловый указатель процесса
  • file_get_contents() - Считывает содержимое файла в строку
  • pack() - Упаковывает данные в двоичную строку

Добавить

Примечания пользователей 10 notes

up
109
nate at frickenate dot com
14 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
3
divinity76 at gmail dot com
3 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
3
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
8 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
5
dharris dot nospam at removethispart dot drh dot net
16 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
8 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
4
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.
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));
To Top