很早之前,苏南大叔就分析过phpfile_get_contents函数。在本文中,苏南大叔要分析一下它的兄弟函数file_put_contents。大家可能会发笑,这么简单的php函数,有啥好分析的呢?那么,您看完本文,再说话。好么?您可能会对这个最简单的函数,有着新的感悟。

苏南大叔:进阶深入分析,php的file_put_contents函数 - php-file-put-contents
进阶深入分析,php的file_put_contents函数(图6-1)

本文测试环境:win10php@5.6ntsphp@7.3.4nts。当然,由于能力有限,苏南大叔并没有分析完这个file_get_contents函数的所有情况,这里留待后文评说。

函数原型

官方的file_put_contents函数见下面的这个页面:

file_put_contents ( string $filename , mixed $data [, int $flags = 0 [, resource $context ]] ) : int

函数说明挺乱乎的。其实最常见的应用场景就是把一些字符串写到某个文件里面。或者是单纯写入文件,或者是追加写入。同时,有个flag叫做独占lock。更多的其它不常见的使用场景,就有待苏南大叔后续解锁了。

苏南大叔:进阶深入分析,php的file_put_contents函数 - php-file-get-contents-info
进阶深入分析,php的file_put_contents函数(图6-2)

$filename

文件名一般来说,大家都不会写中文。但是如果写中文的话(碰巧又是php5系列的话),可能就会碰到乱码的情况了,文件名是个大家不认识的乱码。所以,这里,在php@5系列下的话,如果您要使用中文做文件名的话,请使用iconv转换一下。

注意:iconv是个扩展,需要在php.ini中开启。php@5系列,中文名可能乱码。php@7系列,中文名并不会乱码,并不需要iconv转换!

苏南大叔:进阶深入分析,php的file_put_contents函数 - phpini-iconv
进阶深入分析,php的file_put_contents函数(图6-3)

下面的是php@5下,中文转换范例代码:

$file_name = iconv("utf-8","gb2312","中文.txt"); 

苏南大叔:进阶深入分析,php的file_put_contents函数 - php-name-iconv
进阶深入分析,php的file_put_contents函数(图6-4)

所以,面对文件名中文乱码的问题,解决方案有两个:第一是iconv转换一下。第二个是把php@5换成php@7系列。明白了木有?

$data

一般都是个字符串,但是也可以是别的,因为类型是mixed嘛。官方说明是:可以是字符串、数组或数据流。苏南大叔这里就实验一个数组吧。结果写入数据的结果,令人窒息。

$file = "中文.txt";
$data = ["a","b","c"];
file_put_contents($file, $data, LOCK_EX);

这个数组["a","b","c"]的写入结果是:字符串abc。有些不太容易理解啊~ 苏南大叔觉得:还是老老实实的写入字符串吧,比较好些。

苏南大叔:进阶深入分析,php的file_put_contents函数 - php-file-put-contents-array
进阶深入分析,php的file_put_contents函数(图6-5)

$flag

这个默认就是重复写入的$flag,但是你可以配置成追加模式,而独占模式最好都写上。

名称解释
FILE_USE_INCLUDE_PATH在 include 目录里搜索 filename。 更多信息可参见 include_path
FILE_APPEND如果文件 filename 已经存在,追加数据而不是覆盖
LOCK_EX在写入时获得一个独占锁

这个$flag似乎不是太好理解,苏南大叔是这么理解的:

  • LOCK_EX能带上就带上,带上总是有好处的。
  • FILE_APPEND,这个是叠加项目,看情况使用了。
  • FILE_USE_INCLUDE_PATH,这个选项就是个非常奇怪的设置了。放在这里,似乎是有些不妥当。
file_put_contents($file, $str);
file_put_contents($file, $str, LOCK_EX);
file_put_contents($file, $str, FILE_APPEND | LOCK_EX);

$flagFILE_USE_INCLUDE_PATH模式

这里单独说一下这个FILE_USE_INCLUDE_PATH模式,非常邪门的一个参数值。

file_put_contents($file, $str, FILE_USE_INCLUDE_PATH);

下面有个例子:

define("DS",DIRECTORY_SEPARATOR);
set_include_path( realpath ( dirname ( __FILE__ ) ).DS."test".DS);
//print_r(get_include_path());
file_put_contents('test.txt',"test", FILE_USE_INCLUDE_PATH);

目前在苏南大叔看来,这个FILE_USE_INCLUDE_PATH就是可以用于改变$filename的路径,那么问题来了,既然是改变路径。那为什么不在第一个$filename参数里面,直接写好路径呢?非要费事拐弯抹角的去设置第三个参数$flag呢?大家有好的不同见解的话,欢迎留言给苏南大叔。谢谢。

苏南大叔:进阶深入分析,php的file_put_contents函数 - php-file-put-contents-path
进阶深入分析,php的file_put_contents函数(图6-6)

在这个例子中,苏南大叔设置test.txt的写入,那么它到底是会生成在include_path里面呢?还是会生出在默认的根目录下面呢?测试结果,非常神奇。include_path设置的是根目录下面的test目录。

  • include_path下没有目标文件的时候,测试结果是把目标文件生成在了站点根目录下面。
  • 手工在include_path下新建一个同名文件后,目标文件就默认生成到了include_path下面。即使删除同名文件后,也依然生成到include_path下。就是说,想要生成文件到include_path下面,还需要个人为的引导动作....

这个测试结果,是非常神奇的。苏南大叔非常不建议您使用FILE_USE_INCLUDE_PATH参数,这个不确定性太多...

相关链接

总结

一些php函数就是有些很奇怪的说,无法用常规思路去理解。更多php函数解析,请参考苏南大叔的文章:

如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。
本站采用创作共用版权协议, 要求署名、非商业用途和相同方式共享。
转载本站内容必须也遵循“署名-非商业用途-相同方式共享”的创作共用协议。
未经许可,规模化镜像抄袭本站内容的行为,将会根据有关法律法规进行维权。
程序如此灵动~》下所有原创文章,如被用于商业用途,请您按规定支付稿费。

 【加群】加入QQ群【175454274】和大家一起讨论这个问题

 【源码】本文代码片段及相关软件,请点此获取

 【绝密】秘籍文章入口,仅传授于有缘之人   php

本站的忠实读者小伙伴,正在阅读下面这些文章: