欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

fwrite

PHP 文件创建/写入

在本节中,我们将为您讲解如何在服务器上创建并写入文件。

PHP 创建文件 - fopen()

fopen() 函数也用于创建文件。也许有点混乱,但是在 PHP 中,创建文件所用的函数与打开文件的相同。

如果您用 fopen() 打开并不存在的文件,此函数会创建文件,假定文件被打开为写入(w)或增加(a)。

下面的例子创建名为 "testfile.txt" 的新文件。此文件将被创建于 PHP 代码所在的相同目录中:

实例

$myfile = fopen("testfile.txt", "w")

PHP 文件权限

如果您试图运行这段代码时发生错误,请检查您是否有向硬盘写入信息的 PHP 文件访问权限。

PHP 写入文件 - fwrite()

fwrite() 函数用于写入文件。

fwrite() 的第一个参数包含要写入的文件的文件名,第二个参数是被写的字符串。

下面的例子把姓名写入名为 "newfile.txt" 的新文件中:

实例

<?php
$myfile = fopen("newfile.txt", "w") or die("Unable to open file!");
$txt = "Bill Gates\n";
fwrite($myfile, $txt);
$txt = "Steve Jobs\n";
fwrite($myfile, $txt);
fclose($myfile);
?>

请注意,我们向文件 "newfile.txt" 写了两次。在每次我们向文件写入时,在我们发送的字符串 $txt 中,第一次包含 "Bill Gates",第二次包含 "Steve Jobs"。在写入完成后,我们使用 fclose() 函数来关闭文件。

如果我们打开 "newfile.txt" 文件,它应该是这样的:

Bill Gates
Steve Jobs

PHP 覆盖(Overwriting)

如果现在 "newfile.txt" 包含了一些数据,我们可以展示在写入已有文件时发生的的事情。所有已存在的数据会被擦除并以一个新文件开始。

在下面的例子中,我们打开一个已存在的文件 "newfile.txt",并向其中写入了一些新数据:

实例

<?php
$myfile = fopen("newfile.txt", "w") or die("Unable to open file!");
$txt = "Mickey Mouse\n";
fwrite($myfile, $txt);
$txt = "Minnie Mouse\n";
fwrite($myfile, $txt);
fclose($myfile);
?>

如果现在我们打开这个 "newfile.txt" 文件,Bill 和 Steve 都已消失,只剩下我们刚写入的数据:

Mickey Mouse
Minnie Mouse

PHP Filesystem 参考手册

如需完整的 PHP 文件系统参考手册,请访问 W3School 提供的 PHP Filesystem 参考手册


来自  http://www.w3school.com.cn/php/php_file_create.asp

(PHP 4, PHP 5, PHP 7)

fwrite — 写入文件(可安全用于二进制文件)

说明

int fwrite ( resource $handle , string $string [, int $length ] )

fwrite() 把 string 的内容写入 文件指针 handle 处。

参数

 

handle

文件系统指针,是典型地由 fopen() 创建的 resource(资源)。

string

The string that is to be written.

length

如果指定了 length,当写入了 length 个字节或者写完了 string 以后,写入就会停止,视乎先碰到哪种情况。

注意如果给出了 length 参数,则 magic_quotes_runtime 配置选项将被忽略,而 string 中的斜线将不会被抽去。

返回值

fwrite() 返回写入的字符数,出现错误时则返回 FALSE 。

注释

Note:

Writing to a network stream may end before the whole string is written. Return value of fwrite() may be checked:

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

?>

Note:

在区分二进制文件和文本文件的系统上(如 Windows) 打开文件时,fopen() 函数的 mode 参数要加上 'b'。

Note:

If handle was fopen()ed in append mode, fwrite()s are atomic (unless the size of string exceeds the filesystem's block size, on some platforms, and as long as the file is on a local filesystem). That is, there is no need to flock() a resource before calling fwrite(); all of the data will be written without interruption.

Note:

If writing twice to the file pointer, then the data will be appended to the end of the file content:

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

// the content of 'data.txt' is now 123 and not 23!
?>

范例

 

Example #1 一个简单的 fwrite() 例子

<?php
$filename 
'test.txt';
$somecontent "添加这些文字到文件\n";

// 首先我们要确定文件存在并且可写。
if (is_writable($filename)) {

    
// 在这个例子里,我们将使用添加模式打开$filename,
    // 因此,文件指针将会在文件的末尾,
    // 那就是当我们使用fwrite()的时候,$somecontent将要写入的地方。
    
if (!$handle fopen($filename'a')) {
         echo 
"不能打开文件 $filename";
         exit;
    }

    
// 将$somecontent写入到我们打开的文件中。
    
if (fwrite($handle$somecontent) === FALSE) {
        echo 
"不能写入到文件 $filename";
        exit;
    }

    echo 
"成功地将 $somecontent 写入到文件$filename";

    
fclose($handle);

} else {
    echo 
"文件 $filename 不可写";
}

?>

参见

 

  • fread() - 读取文件(可安全用于二进制文件)
  • fopen() - 打开文件或者 URL
  • fsockopen() - 打开一个网络连接或者一个Unix套接字连接
  • popen() - 打开进程文件指针
  • file_get_contents() - 将整个文件读入一个字符串
add a note add a note

User Contributed Notes 30 notes

nate at frickenate dot com ¶
6 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($fpsubstr($string$written)); 
        if (
$fwrite === false) { 
            return 
$written
        } 
    } 
    return 
$written

?>
synnus at gmail dot com ¶
2 months 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($fp65536))) { 
    
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;
    }

?>
dharris dot nospam at removethispart dot drh dot net ¶
8 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");
chedong at hotmail dot com ¶
13 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));
Anonymous ¶
7 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.
Anonymous ¶
2 months 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($fp65536))) { 
    
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;
    }

?>
php at biggerthanthebeatles dot com ¶
12 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.
Jake Roberts ¶
13 years ago
Use caution when using:

$content = fread($fh, filesize($fh)) or die "Error Reading";

This will cause an error if the file you are reading is zero length.

Intead use:

if ( false === fread($fh, filesize($fh)) ) die "Error Reading";

Thus it will be successful on reading zero bytes but detect and error returned as FALSE.
Jon Haynes ¶
5 years ago
Be careful of using reserved Windows filenames in fwrite operations. 

<?php 
$fh 
fopen('prn.txt''w'); 
fwrite($fh'wtf?'); 
echo 
'done' PHP_EOL
?> 

The above script will hang (tested on Windows 7) before it can echo 'done'. 

This is due to another 'feature' of our favourite operating system where filenames like prn.xxx, con.xxx, com1.xxx and aux.xxx (with xxx being any filename extension) are Windows reserved device names. Attempts to create/read/write to these files hangs the interpreter.
Anonymous ¶
1 year ago
Bad example!

The result of fwrite could be either FALSE or 0.

So it should be correctly:

if (false === fwrite($handle, $somecontent)) { ....
kzevian at cybercable dot net dot mx ¶
11 years ago
I needed to append, but I needed to write on the file's beginning, and after some hours of effort this worked for me:

$file = "file.txt";
if (!file_exists("file.txt")) touch("file.txt");
$fh = fopen("file.txt", "r");
$fcontent = fread($fh, filesize("file.txt"));

$towrite = "$newcontent $fcontent";

$fh22 = fopen('file.txt', 'w+');
fwrite($fh2, $towrite);
fclose($fh);
fclose($fh2);
oktavianus dot programmer at gmail dot com ¶
7 years ago
this the another sample to use fwrite with create a folder and create the txt file.

<?php
$mypath
="testdir\\subdir\\test";
mkdir($mypath,0777,TRUE);
$filename $mypath.'\test.txt';
$handle fopen($filename,"x+");
$somecontent "Add this to the file Oktavianus";
fwrite($handle,$somecontent);
echo 
"Success";
fclose($handle);
?> 

please try...
Oktavianus
james at facepwn dot com ¶
7 years ago
if (is_writable($filename)) {

Could also be

if (is_writable($filename) or die ("Can not write to ".$filename)) {
ceo at l-i-e dot com ¶
7 years ago
If you are trying to write binary/structured data (e.g., a 4-byte sequence for an (int)) to a file, you will need to use: 
http://php.net/pack
Will at EnigmaChannel dot com ¶
11 years ago
Using fwrite to write to a file in your include folder...

PHP does not recognise the permissions setting for the file until you restart the server... this script works fine. (still have to create the blank text file first though...it is not created automatically) On OS X Server..
Using the 1 in fopen tells php to look for the file in your include folder. Change your include folder by altering include_path in php.ini
On OS X Server, php.ini is in private/etc/php.ini.default
copy the file and call it php.ini

the default include path is usr/lib/php
(All these folders are hidden - use TinkerTool to reveal them)

<?php
$file 
fopen('textfile.txt''a'1);
$text="\n Your text to write \n ".date('d')."-".date('m')."-".date('Y')."\n\n";
fwrite($file$text); 
fclose($file);
?>
Chris Blown ¶
13 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.
james at nicolson dot biz ¶
10 years ago
I could'nt quite get MKP Dev hit counter to work.... this is how I modified it
<?
function hitcount()
{
$file = "counter.txt";
if ( !file_exists($file)){
        touch ($file);
        $handle = fopen ($file, 'r+'); // Let's open for read and write
        $count = 0;

}
else{
        $handle = fopen ($file, 'r+'); // Let's open for read and write
        $count = fread ($handle, filesize ($file));
        settype ($count,"integer");
}
rewind ($handle); // Go back to the beginning
/*
* Note that we don't have problems with 9 being fewer characters than
  * 10 because we are always incrementing, so we will always write at
   * least as many characters as we read
    **/
fwrite ($handle, ++$count); // Don't forget to increment the counter
fclose ($handle); // Done 

return $count;
}      
?>
dominic at varspool dot com ¶
2 years ago
Note that the optional $length argument is expected to be an int, and cannot be skipped by passing null. 

That is, `fwrite($handle, $string, null)` is treated as `fwrite($handle, $string, 0)`, and will write zero bytes, not the whole string.
chill at cuna dot org ¶
11 years ago
In PHP 4.3.7 fwrite returns 0 rather than false on failure.
The following example will output "SUCCESS: 0 bytes written" for existing file test.txt:

$fp = fopen("test.txt", "rw");
if (($bytes_written = fwrite($fp, "This is a test")) === false) {
  echo "Unable to write to test.txt\n\n";
} else {
  echo "SUCCESS: $bytes_written bytes written\n\n";
}
cutmaster at fearlesss dot com ¶
9 years ago
For those who, like me, lost a lot of minutes (hours) to understand why fwrite doesn't create a real utf-8 file, here's the explanation I've found : 

I tried to do something like this : 
<?php 
$myString 
utf8_encode("Test with accents éèàç"); 
$fh=fopen('test.xml',"w"); 
fwrite($fh,$myString); 
fclose($fh); 
?> 

For a mysterious reason, the resulted file shows the accent without the utf-8 conversion. 

I tried the binary, mode, etc. etc. And finally I've found it : 
It seems that fwrite NEEDS to have the utf8_encode function INSIDE its parameters like this, to understand it must create a non-text only file : 
<?php 
$myString 
"Test with accents éèàç"
$fh=fopen('test.xml',"w"); 
fwrite($fh,utf8_encode($myString)); 
fclose($fh); 
?> 
Hope this will help
Andi ¶
12 years ago
[Ed. Note: 
The runtime configuration setting auto_detect_line_endings should solve this problem when set to On.] 

I figured out problems when writing to a file using \r as linebreak, after that file() wasn't able to read the data from that file. 
Using \n solved the problem.
chad 0x40 herballure 0x2e com ¶
8 years ago
Remember to check the return value of fwrite(). In particular, writing into a socket can return fewer bytes than requested, and you'll have to try again with the remainder of your data.
sheyh ¶
11 years ago
if you want to create quickly and without fopen use system, exec

system('echo "blahblah" > /path/file');
zaccraven at junk.com ¶
9 years ago
Use this to get a UTF-8 Unicode CSV file that opens properly in Excel:

$tmp = chr(255).chr(254).mb_convert_encoding( $tmp, 'UTF-16LE', 'UTF-8'); 
$write = fwrite( $filepath, $tmp );

Use a tab character, not comma, to seperate the fields in  the $tmp.

Credit for this goes to someone called Eugene Murai, I found this solution by him after searching for several hours.
bluevd at gmail dot com ¶
11 years ago
Watch out for mistakes in writting a simple code for a hit counter:
<?php
$cont
=fopen('cont.txt','r');
$incr=fgets($cont);
//echo $incr;
$incr++;
fclose($cont);
$cont=fopen('cont.txt','a');
fwrite($cont,$incr);
fclose($cont);
?>

Why? notice the second fopen -> $cont=fopen('cont.txt','a');
it opens the file in writting mode (a). And when it ads the incremented
value ( $incr ) it ads it ALONG the old value... so opening the counter
page about 5 times will make your hits number look like this
012131214121312151.21312141213E+ .... you get the piont.
nasty, isn't it? REMEMBER to open the file with the 'w' mode (truncate
the file to 0). Doing this will clear the file content and it will make sure that
your counter works nice. This is the final code

<?php
$cont
=fopen('cont.txt','r');
$incr=fgets($cont);
//echo $incr;
$incr++;
fclose($cont);
$cont=fopen('cont.txt','w');
fwrite($cont,$incr);
fclose($cont);
?>

Notice that this work fine =)
XU (alias Iscu Andrei)
qrworld.net ¶
1 year ago
Here you have a function found on the websitehttp://softontherocks.blogspot.com/2014/11/funcion-para-escribir-en-un-fichero-log.html with an example of how to make a log file.

The function is this:

function writeLog($data) {
list($usec, $sec) = explode(' ', microtime());
$datetime = strftime("%Y%m%d %H:%M:%S",time());
$msg = "$datetime'". sprintf("%06s",intval($usec*1000000)).": $data";
$save_path = 'foo.txt';
$fp = @fopen($save_path, 'a'); // open or create the file for writing and append info
fputs($fp, "$msg\n"); // write the data in the opened file
fclose($fp); // close the file
}
bahatest at ifrance doc com ¶
10 years ago
[Editor's Note: No, you only need to use this if you want a BOM (Byte order mark) added to the document - most people do not.] 

if you have to write a file in UTF-8 format, you have to add an header to the file like this : 

<?php 
$f
=fopen("test.txt""wb"); 
$text=utf8_encode("�a�!"); 
// adding header 
$text="\xEF\xBB\xBF".$text
fputs($f$text); 
fclose($f); 
?>
MKP Dev ¶
11 years ago
bluevd at gmail dot com mentioned a hit counter. In his/her implementation, the file is first opened, read, closed, then opened +truncated, then written, and closed again. An alternative to this is:
<?php
$file 
'counter.txt or whatever';
$handle fopen ($file'r+'); // Let's open for read and write
$count int (fread ($handlefilesize ($file)));
// We don't want to think it's a string and try appending
echo "Number of hits $count";
rewind ($handle); // Go back to the beginning
/*
* Note that we don't have problems with 9 being fewer characters than
* 10 because we are always incrementing, so we will always write at
* least as many characters as we read
**/

fwrite ($handle, ++$count); // Don't forget to increment the counter
fclose ($handle); // Done
?>
elinor_hust at REMOVETHIS dot hotmail dot com ¶
8 years ago
Remember to use double-quotes when outputting special characters such as \n or they come out literally.

...
michael at newbcity dot com ¶
8 years ago
For my fellow newbies, if you test the sample script and want to have the .txt file created for you, you need to comment out the is_writable stuff, like this:  

<?php
$filename 
'test.txt';
$somecontent "Add this to the file\n";

// Let's make sure the file exists and is writable first.
//if (is_writable($filename)) {

// In our example we're opening $filename in append mode.
// The file pointer is at the bottom of the file hence
// that's where $somecontent will go when we fwrite() it.

if (!$handle fopen($filename'a')) {
echo 
"Cannot open file ($filename)";
exit;
}


// Write $somecontent to our opened file.
if (fwrite($handle$somecontent) === FALSE) {
echo 
"Cannot write to file ($filename)";
exit;
}

echo 
"Success, wrote ($somecontent) to file ($filename)";

fclose($handle);

//} else {
//echo "The file $filename is not writable";
//}

?>
来自 http://php.net/manual/zh/function.fwrite.php
普通分类: