file_put_contents

(PHP 5, PHP 7, PHP 8)

file_put_contents将数据写入文件

描述

file_put_contents(
    字符串 $filename,
    混合 $data,
    整数 $flags = 0,
    ?资源 $context = null
): 整数|false

此函数等同于依次调用 fopen()fwrite()fclose() 来将数据写入文件。

如果 filename 不存在,则创建该文件。否则,将覆盖现有文件,除非设置了 FILE_APPEND 标志。

参数

filename

要写入数据的文件的路径。

data

要写入的数据。可以是 字符串数组 资源。

如果 data 资源,则该流的剩余缓冲区将被复制到指定文件。这类似于使用 stream_copy_to_stream()

您还可以将 data 参数指定为一个一维数组。这等同于 file_put_contents($filename, implode('', $array))

flags

flags 的值可以是以下标志的任意组合,使用二进制 OR (|) 运算符连接。

可用标志
标志 描述
FILE_USE_INCLUDE_PATH 在包含目录中搜索 filename。有关详细信息,请参阅 include_path
FILE_APPEND 如果文件 filename 已经存在,则将数据追加到文件而不是覆盖它。
LOCK_EX 在继续写入之前,获取文件的独占锁。换句话说,在 fopen() 调用和 fwrite() 调用之间会发生一个 flock() 调用。这与使用模式 "x" 的 fopen() 调用并不相同。

context

使用 stream_context_create() 创建的有效上下文资源。

返回值

此函数返回写入文件的字节数,如果失败则返回 false

警告

此函数可能返回布尔值 false,但也可能返回一个非布尔值,该值计算结果为 false。有关详细信息,请参阅有关 布尔值 的部分。使用 === 运算符 测试此函数的返回值。

示例

示例 #1 简单用法示例

<?php
$file
= 'people.txt';
// 打开文件以获取现有内容
$current = file_get_contents($file);
// 将新的人添加到文件中
$current .= "John Smith\n";
// 将内容写回文件
file_put_contents($file, $current);
?>

示例 #2 使用标志

<?php
$file
= 'people.txt';
// 要添加到文件中的新人
$person = "John Smith\n";
// 将内容写入文件,
// 使用 FILE_APPEND 标志将内容追加到文件末尾,
// 以及 LOCK_EX 标志以防止其他人在同一时间写入文件
file_put_contents($file, $person, FILE_APPEND | LOCK_EX);
?>

注释

注意: 此函数是二进制安全的。

提示

如果启用了 fopen 包装器,则可以使用 URL 作为此函数的文件名。有关如何指定文件名,请参阅 fopen()。有关各种包装器具有的功能、使用说明以及它们可能提供的任何预定义变量的信息,请参阅 支持的协议和包装器

参见

添加注释

用户贡献的注释 19 个注释

134
TrentTompkins at gmail dot com
16 年前
如果您尝试将文件放在不存在的目录中,则 file put contents 会失败。这将创建目录。

<?php
function file_force_contents($dir, $contents){
$parts = explode('/', $dir);
$file = array_pop($parts);
$dir = '';
foreach(
$parts as $part)
if(!
is_dir($dir .= "/$part")) mkdir($dir);
file_put_contents("$dir/$file", $contents);
}
?>
56
justin dot carlson at gmail dot com
12 年前
很明显,这应该只在您进行一次写入时使用,如果您多次写入同一个文件,则应该使用 fopen 和 fwrite、fwrite 完成写入后使用 fclose 来自己处理。

下面的基准

file_put_contents() 执行 1,000,000 次写入 - 3 次基准测试的平均值

real 0m3.932s
user 0m2.487s
sys 0m1.437s

fopen() fwrite() 执行 1,000,000 次写入,fclose() - 3 次基准测试的平均值

real 0m2.265s
user 0m1.819s
sys 0m0.445s
20
maksam07 at gmail dot com
5 年前
该方法的稍微简化版本:https://php.net/manual/ru/function.file-put-contents.php#84180

<?php
function file_force_contents( $fullPath, $contents, $flags = 0 ){
$parts = explode( '/', $fullPath );
array_pop( $parts );
$dir = implode( '/', $parts );

if( !
is_dir( $dir ) )
mkdir( $dir, 0777, true );

file_put_contents( $fullPath, $contents, $flags );
}

file_force_contents( ROOT.'/newpath/file.txt', 'message', LOCK_EX );
?>
20
chris at ocportal dot com
11 年前
重要的是要理解,除非你使用 PHP 的 'flock' 函数显式地获取一个读锁(共享锁),否则 LOCK_EX 不会阻止读取文件。

例如,在并发的情况下,如果你不将它包装起来,file_get_contents 可能会返回空

<?php
$myfile
=fopen('test.txt','rt');
flock($myfile,LOCK_SH);
$read=file_get_contents('test.txt');
fclose($myfile);
?>

如果你有代码对文件执行 file_get_contents,更改字符串,然后使用 file_put_contents 重新保存,你最好确保正确执行此操作,否则你的文件将随机自毁。
26
deqode at felosity dot nl
14 年前
请注意,当使用 FTP 主机保存时,必须通过一个额外的流上下文,告诉 PHP 覆盖文件。

<?php
/* 设置 FTP 主机名 */
$user = "test";
$pass = "myFTP";
$host = "example.com";
$file = "test.txt";
$hostname = $user . ":" . $pass . "@" . $host . "/" . $file;

/* 文件内容 */
$content = "this is just a test.";

/* 创建一个流上下文,告诉 PHP 覆盖文件 */
$options = array('ftp' => array('overwrite' => true));
$stream = stream_context_create($options);

/* 最后,放入内容 */
file_put_contents($hostname, $content, 0, $stream);
?>
4
Anonymous
2 年前
创建子目录的方法的更简化的版本

function path_put_contents($filePath, $contents, $flags = 0) {

if (! is_dir($dir = implode('/', explode('/', $filePath, -1))))
mkdir($dir, 0777, true);
file_put_contents($filePath, $contents, $flags);
}
9
Anonymous
7 年前
确保在失败的情况下不破坏任何东西。

<?php

function file_put_contents_atomically($filename, $data, $flags = 0, $context = null) {
if (
file_put_contents($filename."~", $data, $flags, $context) === strlen($contents)) {
return
rename($filename."~",$filename,$context);
}

@
unlink($filename."~", $context);
return
FALSE;
}

?>
7
egingell at sisna dot com
18 年前
回复之前的说明

如果你想在 PHP4 中模拟此函数,你需要返回写入的字节数,以及对数组、标志的支持。

我只能找出 FILE_APPEND 标志和数组支持。如果我能找出“资源上下文”和其他标志,我也会包含它们。

<?

define('FILE_APPEND', 1);
function file_put_contents($n, $d, $flag = false) {
$mode = ($flag == FILE_APPEND || strtoupper($flag) == 'FILE_APPEND') ? 'a' : 'w';
$f = @fopen($n, $mode);
if ($f === false) {
return 0;
} else {
if (is_array($d)) $d = implode($d);
$bytes_written = fwrite($f, $d);
fclose($f);
return $bytes_written;
}
}

?>
7
aidan at php dot net
20 年前
此功能现在在 PEAR 包 PHP_Compat 中实现。

有关在不升级 PHP 版本的情况下使用此函数的更多信息,请访问以下链接

http://pear.php.net/package/PHP_Compat
1
vaneatona at gmail dot com
7 年前
我正在更新一个发布的函数,因为它在没有目录的情况下会失败。它还会返回最终值,以便你可以确定实际文件是否已写入。

public static function file_force_contents($dir, $contents){
$parts = explode('/', $dir);
$file = array_pop($parts);
$dir = '';

foreach($parts as $part) {
if (! is_dir($dir .= "{$part}/")) mkdir($dir);
}

return file_put_contents("{$dir}{$file}", $contents);
}
2
ravianshmsr08 at gmail dot com
13 年前
从本地主机上传文件到任何 FTP 服务器。
请注意,'ftp_chdir' 已被使用,而不是直接放入远程文件路径...在 ftp_put 中...远程文件应该只是文件名

<?php
$host
= '*****';
$usr = '*****';
$pwd = '**********';
$local_file = './orderXML/order200.xml';
$ftp_path = 'order200.xml';
$conn_id = ftp_connect($host, 21) or die ("Cannot connect to host");
ftp_pasv($resource, true);
ftp_login($conn_id, $usr, $pwd) or die("Cannot login");
// 执行文件上传
ftp_chdir($conn_id, '/public_html/abc/');
$upload = ftp_put($conn_id, $ftp_path, $local_file, FTP_ASCII);
if(
$upload) { $ftpsucc=1; } else { $ftpsucc=0; }
// 检查上传状态:
print (!$upload) ? 'Cannot upload' : 'Upload complete';
print
"\n";
// 关闭 FTP 流
ftp_close($conn_id);
?>
3
Brandon Lockaby
13 年前
在析构函数中调用 file_put_contents 将导致文件写入 SERVER_ROOT...
2
wjsams at gmail dot com
15 年前
file_put_contents() 删除最后一个行结束符

如果你真的想在使用 file_put_contents() 写入文件时在文件末尾添加一个额外的行结束符,你必须在行末追加一个额外的 PHP_EOL,如下所示。

<?php
$a_str
= array("these","are","new","lines");
$contents = implode(PHP_EOL, $a_str);
$contents .= PHP_EOL . PHP_EOL;
file_put_contents("newfile.txt", $contents);
print(
"|$contents|");
?>

你可以看到,当你打印 $contents 时,你会得到两个额外的换行符,但是如果你查看文件 newfile.txt,你只会得到一个。
-2
curda222 at gmail dot com
6 个月前
来自 TrentTompkins at gmail dot com 的改进和改进代码

注意:添加了错误响应
注意:添加了目录检测
注意:添加了根目录检测
注意:创建文件夹时添加了权限

function file_force_contents($dir, $contents, $flags = 0){
if (strpos($dir, "../") === 0){
$dir = str_replace("..", substr(__DIR__, 0, strrpos(__DIR__, "/")), $dir);
}
$parts = explode('/', $dir);
if(is_array($parts)){
$file = array_pop($parts);
$dir = '';
foreach($parts as $part)
if(!is_dir($dir .= "/$part")){
mkdir($dir, 0777, true);
}
if(file_put_contents("$dir/$file", $contents, $flags) === false ){
return false;
}
}else{
if(file_put_contents("$dir", $contents, $flags) === false ){
return false;
}
}
}

-Oliver Leuyim Angel
1
John Galt
15 年前
我使用 file_put_contents() 作为一种非常简单的点击计数器的方法。以下是在一行代码中展示的两个极其简单的点击计数器的示例。

请记住,它们效率并不高。你必须有一个名为 counter.txt 的文件,其中包含初始值 0。

对于文本点击计数器
<?php
$counter
= file_get_contents("counter.txt"); $counter++; file_put_contents("counter.txt", $counter); echo $counter;
?>

或者图形点击计数器
<?php
$counter
= file_get_contents("counter.txt"); $counter++; file_put_contents("counter.txt", $counter); for($i = 0; $i < strlen($counter); $i++) echo "<img src=\"counter/".substr($counter, $i, 1).".gif\" alt=\"".substr($counter, $i, 1)."\" />";
?>
0
aabaev arroba gmail coma com
8 年前
我建议扩展 TrentTompkins at gmail dot com 的 file_force_contents() 函数,通过添加验证来判断补丁是否像这样: "../foo/bar/file"

if (strpos($dir, "../") === 0)
$dir = str_replace("..", substr(__DIR__, 0, strrpos(__DIR__, "/")), $dir);
0
gurjindersingh at SPAM dot hotmail dot com
9 年前
如果你试图将文件放到不存在的目录中,File put contents 会失败。此函数创建目录。

我更新了 “TrentTompkins at gmail dot com” 的代码。感谢。
<?php
/**
* @param string $filename <p>文件名称,包括文件夹。
* 例如 :: /path/to/file/filename.ext 或 filename.ext</p>
* @param string $data <p> 要写入的数据。
* </p>
* @param int $flags 与 file_put_contents 相同的标志。
* 更多信息:https://php.net/manual/en/function.file-put-contents.php
* @return bool <b>TRUE</b> 文件创建成功 <br> <b>FALSE</b> 无法创建文件。
*/
function file_force_contents($filename, $data, $flags = 0){
if(!
is_dir(dirname($filename)))
mkdir(dirname($filename).'/', 0777, TRUE);
return
file_put_contents($filename, $data,$flags);
}
// 用法

file_force_contents('test1.txt','test1 content'); // 创建 test1.txt

file_force_contents('test2/test2.txt','test2 content');
// 创建 test2/test2.txt 和 "test2" 文件夹。

file_force_contents('~/test3/test3.txt','test3 content');
// 创建 /path/to/user/directory/test3/test3.txt 和用户目录中的 "test3" 文件夹(在 Linux 上检查 "ll ~/ | grep test3")。
?>
0
error at example dot com
13 年前
值得注意的是,使用此函数时,你必须确保使用正确的路径。我用它来帮助错误处理程序进行日志记录,有时它会工作 - 而有时它不会。最终,这是因为有时它从不同的路径调用,导致无法写入日志文件。

__DIR__ 是你的朋友。
-1
vahkos at mail dot ru
12 年前
如果文件名不正确(例如,在末尾有 /n,/t 等符号),file_put_contents 不会发出错误消息。
因此,请对文件名使用 trim()。
$name=trim($name);
file_put_contents($name,$content);
To Top