PHP 文件写入和读取操作实例详解【必看篇】


Posted in PHP onNovember 04, 2019

本文实例讲述了PHP 文件写入和读取操作。分享给大家供大家参考,具体如下:

文章提纲:

一.实现文件读取和写入的基本思路

二.使用fopen方法打开文件

三.文件读取和文件写入操作

四.使用fclose方法关闭文件

五.文件指针的移动

六.Windows和UNIX下的回车和换行

一.实现文件读取和写入的基本思路:

1.通过fopen方法打开文件:$fp =fopen(/*参数,参数*/),fp为Resource类型
2.进行文件读取或者文件写入操作(这里使用的函数以1中返回的$fp作为参数)
3. 调用fclose($fp)关闭关闭文件

二:使用fopen方法打开文件

fopen(文件路径[string],打开模式[string])

<1>fopen的第一个参数为文件路径
写文件路径的方式:1绝对路径,2相对路径

1绝对路径:

在windows下工作的小伙伴们应该很熟悉,windows下的路径分隔符是“\”而不是“/”,但我们在写入路径时不能以钦定的“\”为分隔符

PHP 文件写入和读取操作实例详解【必看篇】

那如果我们以“\”分隔符写入路径会怎样呢?

<?php
  $fp = fopen("C:\wamp64\www\text.txt",'w');
?>

运行后报错,提示路径参数无效

PHP 文件写入和读取操作实例详解【必看篇】

所以我们要把分隔符“\”换成“/”:

<?php
 $fp = fopen("C:/wamp64/www/text.txt",'w');
?>

运行时无报错,说明参数是有效的。

【注意】fopen函数不能理解“\”分隔符,如果你想要使用“\”,那么要使用转义,如写成:"C:\\wamp64\\www\\text.txt"这种写法也是可以的,函数也能理解,不会报错。但即使这样,也不推荐使用“\”,因为在OS(mac)下只能识别“/”不能识别“\”

本小节的结论:推荐坚持使用“/”作为分隔符

2.相对路径:

上一小节介绍的是绝对路径的写法,但这样却带来了另外一个问题:服务器的目录结构可能会有较大的改变,这时原来写的绝对路径就要全部重写了,比如在我的电脑上的目标文件路径是C:/wamp64/www/text.txt,如果我把www文件夹改名为penghuwan呢?原来写入的路径参数就失效了。所以我们引入了相对路径的写法:

<?php
 $DOCUMENT_ROOT = $_SERVER['DOCUMENT_ROOT'];
 $fp = fopen("$DOCUMENT_ROOT/text.txt",'w');
?>

• $_SERVER是PHP的超级全局变量(在代码任何地方都可访问,类型是数组),通过$_SERVER['DOCUMENT_ROOT']可取到服务器的默认根目录

服务器的默认根目录可通过php.ini修改(这个可自行百度)

• $_SERVER['DOCUMENT_ROOT']在这里等同于C:/wamp64/www

本小节的结论:推荐使用相对路径

<2>fopen的第二个参数为打开模式

设置打开模式后,我们就相当于为接下来的读写操作设置了权限:

最基本的几个模式:

“r”:只能读取文件,不能写入文件(写入操作被忽略)
“w”:只能写入文件,不能读取文件(读取操作被忽略)
“a”:只追加文件,与“w”类似,区别是“w”删除原有的内容,“a”不删除原有内容,只追加内容

<?php
 $DOCUMENT_ROOT = $_SERVER['DOCUMENT_ROOT'];
 $fp = fopen("$DOCUMENT_ROOT/text.txt",'w');
 fwrite($fp,'在写模式下写入');
 fclose($fp);
?>

在设置了写操作的权限后,就能正常地写入文件了

运行后打开C:/wamp64/www/text.txt:

PHP 文件写入和读取操作实例详解【必看篇】

这次我们把权限设置为只读,并尝试写入文本:'在只读模式下写入' ?

<?php
 $DOCUMENT_ROOT = $_SERVER['DOCUMENT_ROOT'];
 $fp = fopen("$DOCUMENT_ROOT/text.txt",'r');
 fwrite($fp,'在读模式下写入');
 fclose($fp);
?>

运行后打开C:/wamp64/www/text.txt,发现文件内容并没有改变,说明由于没有设置相应的权限,操作被忽略了 PHP 文件写入和读取操作实例详解【必看篇】

关于打开模式的网络资料,我想大家最可能找到的是这张表:(图来自W3C) PHP 文件写入和读取操作实例详解【必看篇】

很全面,但我觉得这张表对新手有些不太友好,让人看后不知多云。 r是只读,w是只写(原来有的内容全删除),a是追加(不删除原有内容),这都好理解。

但r+,w+,和a+的区别和联系讲的实在太模糊了呀。 这里我就想详细地讲一下r+,w+,和a+三者的区别和联系:

首先r+,w+,和a+都是可读可写的,读取时的方式是一样的,关键在于写入方式的不同:

r+: 从文件[头部][覆盖]原有内容 ([不删除]原有内容);

a+:从文件[尾部][追加]内容 ([不删除]原有内容);

w+:[完全删除]原有内容,然后[再添加]新的内容

下面我依次演示上述的结论,首先我们没有写入的时候文本是”I am initialized value”(意为我是初始值)

PHP 文件写入和读取操作实例详解【必看篇】

• 采用r+模式写入文本“r+ mode”

<?php
 $DOCUMENT_ROOT = $_SERVER['DOCUMENT_ROOT'];
 $fp = fopen("$DOCUMENT_ROOT/text.txt",'r+');
 fwrite($fp,'r+ mode');
 fclose($fp);
?>

运行后再打开文本,发现“I am in”被“r+ mode”覆盖了:

PHP 文件写入和读取操作实例详解【必看篇】

• 采用a+模式写入文本“a+ mode”

基于”I am initialized value”的初始文本我们运行以下代码:  

<?php
 $DOCUMENT_ROOT = $_SERVER['DOCUMENT_ROOT'];
 $fp = fopen("$DOCUMENT_ROOT/text.txt",'a+');
 fwrite($fp,'a+ mode');
 fclose($fp);
?>

PHP 文件写入和读取操作实例详解【必看篇】

I am initialized value没有被删除和覆盖,而是在后面追加了a+ mode的这一段新文本运行多次后:

PHP 文件写入和读取操作实例详解【必看篇】

•采用w+模式写入文本“w+ mode”

基于”I am initialized value”的初始文本我们运行以下代码:

<?php
 $DOCUMENT_ROOT = $_SERVER['DOCUMENT_ROOT'];
 $fp = fopen("$DOCUMENT_ROOT/text.txt",'w+');
 fwrite($fp,'w+ mode');
 fclose($fp);
?>

运行后,我们发现”I am initialized value”已经被删除了,然后才加上了“w+ mode”这段新文本 PHP 文件写入和读取操作实例详解【必看篇】

【注意】r+,a+,w+还有一个区别是a+,w+在文件不存在时则创建文件,r+文件不存在时报错

【吐槽】:关于r+和w+,a+的区别,我找了网络上,包括W3C和各种博客文章以及那本“PHP圣经”上的各种资料,发现都是一笔带过去的,这也是我写这篇文章的原因

三.文件读取和文件写入操作

先说说几个比较重要的函数:

 file_exists():判断文件是否存在,返回布尔值

 filesize():判断一个文件大小,返回文件的字节数,为整型数字

 unlink():删除一个文件

写入文件

fwrite(资源文件对象[string],写入方式[string]),资源文件对象即为fopen方法返回的参数,为Resource类型,写入方式可以是w(或者w+,a+,r+) 已经有上面的例子,这里就不放demo了

读取文件

这是我们要读取的文件内容:

PHP 文件写入和读取操作实例详解【必看篇】

读取文件的方式有以下几种:

1.一次读取一个字节的数据 fgetc()

2.一次读取指定的字节数的数据 fread()

3.一次读取一行数据 fgets()/fgetcsv()

4.一次读完全部数据 fpassthru()/ file()

1. 一次读取一个字节 —— 通过fgetc()获取单个字节

<?php
  $DOCUMENT_ROOT = $_SERVER['DOCUMENT_ROOT'];
  $fp = fopen("$DOCUMENT_ROOT/text.txt",'r');//打开文件
  if(file_exists("$DOCUMENT_ROOT/text.txt")){//当文件存在时,才读取内容
   while(!feof($fp)){//判断文件指针是否到达末尾
    $c = fgetc($fp);//每执行一次fgetc(),文件指针就向后移动一位
    echo $c;//输出获取到的字节
   }
  }
  fclose($fp);//关闭文件
?>

运行:

PHP 文件写入和读取操作实例详解【必看篇】 

【注意】:无论是按文本格式输入输出

还是按二进制格式输出,fgetc()每次获取的是一个字节而不是一个字符!上面的例子中我们是逐个输出,现在让我们只做一次输出,看看结果怎样:

<?php
 $DOCUMENT_ROOT = $_SERVER['DOCUMENT_ROOT'];
 $fp = fopen("$DOCUMENT_ROOT/text.txt",'r');
 echo fgetc($fp);//只做一次输出
 close($fp);
?>

运行结果如下,我们得到的不是汉字“我”,而是一个乱码,其实这个乱码就是一个字节

PHP 文件写入和读取操作实例详解【必看篇】

<?php
  $DOCUMENT_ROOT = $_SERVER['DOCUMENT_ROOT'];
  $fp = fopen("$DOCUMENT_ROOT/text.txt",'r');
  echo fgetc($fp);//连续做三次输出
  echo fgetc($fp);
  echo fgetc($fp);
  fclose($fp);
?>

2.一次读取多个字节 ——通过fread()方法:

<?php
 $DOCUMENT_ROOT = $_SERVER['DOCUMENT_ROOT'];
 $fp = fopen("$DOCUMENT_ROOT/text.txt",'r');
 echo fread($fp, 3);//一次输出三个字节即一个汉字字符(UTF-8)
 fclose($fp);
?>

运行结果:

PHP 文件写入和读取操作实例详解【必看篇】

改成:

echo fread($fp, 6);

运行结果如下,输出了6个字节也即两个汉字字符(UTF-8)

PHP 文件写入和读取操作实例详解【必看篇】

3.一次读取一行——通过fgets()获取一行内容

<?php
  $DOCUMENT_ROOT = $_SERVER['DOCUMENT_ROOT']
  $fp = fopen("$DOCUMENT_ROOT/text.txt",'r');//打开文件
  if(file_exists("$DOCUMENT_ROOT/text.txt")){//当文件存在时,才读取内容
   while(!feof($fp)){//判断文件指针是否到达末尾
    $line = fgets($fp);//返回一行文本,并将文件指针移动到下一行头部
    echo $line."<br/>";//输出获取到的一行文本
   }
  }
  fclose($fp);//关闭文件
?>

PHP 文件写入和读取操作实例详解【必看篇】

fgets()其实还有第二个参数,这个参数规定了每一行能读取的最大字节数(注意是字节数不是字符数):

【注意】在UTF-8编码下汉字3字节,字母1字节下面我修改上面的一行,代码,使获取的每一行最大字符数为3(也即字节数为9)

$line = fgets($fp,10);

Demo:

PHP 文件写入和读取操作实例详解【必看篇】

【注意】:这里我fgets()里第二个参数为10,为什么是10呢?因为

1.这里的长度是按字节数算的

2.一个汉字占3个字节。fgets($fp,10)代表一次最多读取10 - 1 = 9字节

4.一次读完全部文件 ——fpassthru() or file()? fpassthru()将读取文件并直接输出(无处理过程)

<?php
  $DOCUMENT_ROOT = $_SERVER['DOCUMENT_ROOT'];
  $fp = fopen("$DOCUMENT_ROOT/text.txt",'r');
  fpassthru($fp);
  fclose($fp);
?>

运行结果:

PHP 文件写入和读取操作实例详解【必看篇】

【注意】这里需要注意一点的是,我们并没有从fpassthru($fp)获取到返回值然后echo到页面上去,也就是说这个方法是会强制输出获取的内容的,而并不是像之前例子的方法那样返回文本,允许我们保存到变量中才将其输出

将读取到的全部内容保存到一个数组中,每个数组元素为一行的内容——fille()

<?php
 $DOCUMENT_ROOT = $_SERVER['DOCUMENT_ROOT'];
 $file_array = file("$DOCUMENT_ROOT/text.txt");//取到文件数组
 foreach ($file_array as $value) {//输出数组元素
  echo $value."<br/>";
 }
?>

PHP 文件写入和读取操作实例详解【必看篇】

【注意】:这里我们并不需要写fopen和fclose哦!也就是说file()方法已经帮我们做了这一步了

四.使用fclose方法关闭文件

fclose()将返回一个布尔值,成功关闭为true,关闭失败为false(失败的情况很少出现,可不考虑) 是否打开文件后一定要关闭?

1即使不手写fclose,在PHP脚本执行结束后,也会自动关闭文件的

2但在一个长时间执行的脚本中,如果不写关闭文件的fclose(),在文件加锁的情况下会造成操作的阻塞,所以,写fclose是个好习惯

五.文件指针的移动

我们上面调用的读取文件的函数,其实都是基于文件指针去打印的,每读取一段字节内容,文件指针就向后移动一段字节长度,直到被读取的文件最大字节长度为止

<?php
   $DOCUMENT_ROOT = $_SERVER['DOCUMENT_ROOT'];
   function print_file_pointer($fp){//定义一个打印文件指针位置的函数
    echo " <br/>//此时文件指针的位置:";
    echo ftell($fp)."<br/>";
   }
   $fp = fopen("$DOCUMENT_ROOT/text.txt",'r');
   echo fgetc($fp);//通过fgetc连续输出三个字节
   echo fgetc($fp);
   echo fgetc($fp);
   print_file_pointer($fp);//打印此刻文件指针的位置
   
   echo fread($fp,6);//通过fread一次输出6字节
   print_file_pointer($fp);//打印此刻文件指针的位置
   
   echo fgets($fp); //通过fgets输出一整行
   print_file_pointer($fp);//打印此刻文件指针的位置
   
   fpassthru($fp); //一次性输出全部内容
   print_file_pointer($fp);//打印此刻文件指针的位置
   
   fseek($fp, 33);//使文件指针移动到33字节位置
   print_file_pointer($fp);//打印此刻文件指针的位置
   
   rewind($fp);//使文件指针移动到0字节位置(初始位置)
   print_file_pointer($fp);//打印此刻文件指针的位置
$fclose($fp);
?>

Demo:

PHP 文件写入和读取操作实例详解【必看篇】

所以我们需要正确理解fgets(),fpassthru()这些函数的作用:

fgets():从当前文件指针的位置到本行结束的数据,而不是一定输出一整行

fpassthru():从当前文件指针的位置到全部内容结束的数据,而不是一定输出所有的数据

但在这里你可能会有疑问:为什么输出“湖湾”后的指针位置会是17而不是15呢?按理说输出“我叫彭湖湾”这5个汉字一共占3*5 = 15个字节,多出来的17 - 15 =2字节是什么呢?

多出来的两个字节是windows下的回车换行符\n\r

\n是换行,占一字节,\r是回车,占一字节,在六中我将会介绍

六.Windows和UNIX下的回车和换行

<?php
  $DOCUMENT_ROOT = $_SERVER['DOCUMENT_ROOT'];
  $fp = fopen("$DOCUMENT_ROOT/text.txt",'r');
  while(!feof($fp)){
  echo fgets($fp);
  echo ftell($fp);
  }
  fclose($fp);
?>

我们在windows下敲下回车键的时候,相当于键入了\n\r,所以“我叫彭湖湾”的15字节+“\n\r”的2字节 = 17字节

PHP 文件写入和读取操作实例详解【必看篇】

在mac下不一样的是:敲下回车键的时候,相当于只键入了\n,所以“我叫彭湖湾”的15字节+“\n”的1字节 = 16字节

PHP 文件写入和读取操作实例详解【必看篇】

希望本文所述对大家PHP程序设计有所帮助。

PHP 相关文章推荐
PHP文章按日期(月日)SQL归档语句
Nov 29 PHP
深入phpMyAdmin的安装与配置的详细步骤
May 07 PHP
基于session_unset与session_destroy的区别详解
Jun 03 PHP
php通过数组实现多条件查询实现方法(字符串分割)
May 06 PHP
php快速查找数据库中恶意代码的方法
Apr 01 PHP
PHP SPL标准库之接口(Interface)详解
May 11 PHP
thinkPHP5.0框架简单配置作用域的方法
Mar 17 PHP
PHP新特性之字节码缓存和内置服务器
Aug 11 PHP
PHP实现的策略模式简单示例
Aug 25 PHP
php新建文件的方法实例
Sep 26 PHP
gearman中任务的优先级和返回状态实例分析
Feb 27 PHP
PHP中的输出echo、print、printf、sprintf、print_r和var_dump的示例代码
Dec 01 PHP
PHP连接MySQL数据库的三种方式实例分析【mysql、mysqli、pdo】
Nov 04 #PHP
php ZipArchive实现多文件打包下载实例
Oct 31 #PHP
Laravel框架实现抢红包功能示例
Oct 31 #PHP
laravel框架实现后台登录、退出功能示例
Oct 31 #PHP
TP5框架简单登录功能实现方法示例
Oct 31 #PHP
Laravel框架实现即点即改功能的方法分析
Oct 31 #PHP
laravel 框架实现无限级分类的方法示例
Oct 31 #PHP
You might like
php ftp文件上传函数(基础版)
2010/06/03 PHP
PHP通过iconv将字符串从GBK转换为UTF8字符集
2011/07/18 PHP
php使用MySQL保存session会话的方法
2015/06/18 PHP
php简单随机字符串生成方法示例
2017/04/19 PHP
PHP面向对象五大原则之里氏替换原则(LSP)详解
2018/04/08 PHP
分享精心挑选的12款优秀jQuery Ajax分页插件和教程
2012/08/09 Javascript
推荐JavaScript实现继承的最佳方式
2014/11/11 Javascript
浅谈javascript中的三种弹窗
2016/10/21 Javascript
微信小程序 数据交互与渲染实例详解
2017/01/21 Javascript
HTML中使背景图片自适应浏览器大小实例详解
2017/04/06 Javascript
JS 组件系列之 bootstrap treegrid 组件封装过程
2017/04/28 Javascript
浅谈vue的几种绑定变量的值 防止其改变的方法
2018/03/01 Javascript
详解从NodeJS搭建中间层再谈前后端分离
2018/11/13 NodeJs
JavaScript中var的重要性实例分析
2019/07/09 Javascript
Python 解析XML文件
2009/04/15 Python
python设置检查点简单实现代码
2014/07/01 Python
Python找出最小的K个数实例代码
2018/01/04 Python
python进行文件对比的方法
2018/12/24 Python
django-rest-framework 自定义swagger过程详解
2019/07/18 Python
python使用paramiko模块通过ssh2协议对交换机进行配置的方法
2019/07/25 Python
Django 实现xadmin后台菜单改为中文
2019/11/15 Python
Python生成个性签名图片获取GUI过程解析
2019/12/16 Python
selenium中get_cookies()和add_cookie()的用法详解
2020/01/06 Python
html5 application cache遇到的严重问题
2012/12/26 HTML / CSS
html5的pushstate以及监听浏览器返回事件的实现
2020/08/11 HTML / CSS
英国户外服装、鞋类和设备的领先零售商:Millets
2020/10/12 全球购物
预备党员转正思想汇报
2014/01/12 职场文书
春节联欢晚会主持词范文
2014/03/24 职场文书
应届大专生自荐书
2014/06/16 职场文书
研究生导师评语
2014/12/31 职场文书
2015年教师节慰问信
2015/03/23 职场文书
《作风建设永远在路上》心得体会
2016/01/21 职场文书
2016创先争优活动党员公开承诺书
2016/03/24 职场文书
52条SQL语句教你性能优化
2021/05/25 MySQL
python 中yaml文件用法大全
2021/07/04 Python
九大龙王魂骨,山龙王留下躯干骨,榜首死的最憋屈(被捏碎)
2022/03/18 国漫