学习文件处理本质上面就是学习文件处理的函数。 ヾ(๑╹◡╹)ノ”
一. 读取文件
1.1 readfile读取文件
读取一个文件内容的函数:int readfile ( string $文件名)
功能:传入一个文件路径,输出这个文件里面的内容。
<?php
//linux类的读取方式
readfile("/home/paul/test.txt");
//windows类的读取方式
readfile("c:\\boot.ini");
?>
注意:上面的代码中windows的斜线是\斜线,可能会转义掉一些字符。因此,我们写的时候写上两个斜线。
1.2 file_get_contents打开文件
上面的是单纯打文件就直接输出了,有没有打开文件后,能够赋值给一个变量的操作方式呢。string file_get_contents ( string filename)
功能:传入一个文件或文件路径,打开这个文件返回文件的内容。文件的内容是一个字符串。
<?php
$filename = 'NoAlike.txt';
$filestring = file_get_contents($filename);
echo $filestring;
?>
上面的代码,就打开了一个文件,并且将文件当中的内容进行了输出。
我们来针对之前的知识把代码进行一下扩展。用一用之前的知识点。
<?php
//假设我们有一个多行的文件叫NoAlike.txt,没有的话你可以新建一个这个文件
$filename = 'NoAlike.txt';
//打开这个文件,将文件内容赋值给$filestring
$filestring = file_get_contents($filename);
//因为每一行有一个回车即\n,我用\n来把这个字符串切割成数组
$filearray = explode("\n", $filestring);
//把切割成的数组,下标赋值给$key,值赋值给$val,每次循环将$key加1。
while (list($key, $val) = each($filearray)) {
++$key;
$val = trim($val);
//用的单引号,单引号不解释变量进行了拼接而已
print 'Line' . $key .':'. $val.'<br />';
}
?>
上述的explode()、list()两个字符串函数和each()数组函数。
1. explode()函数:把字符串打散为数组。[PHP explode() 函数] [PHP String 函数]
语法:explode(separator,string,limit)
参数 | 描述 |
---|---|
separator | 必需。规定在哪里分割字符串。 |
string | 必需。要分割的字符串。 |
limit | 可选。规定所返回的数组元素的数目。 可能的值: 大于 0 - 返回包含最多 limit 个元素的数组 小于 0 - 返回包含除了最后的 -limit 个元素以外的所有元素的数组 0 - 返回包含一个元素的数组 |
2. list()函数:把数组中的值赋给一些变量,在一次操作中给一组变量赋值。[PHP list() 函数]
<?php
$my_array = array("Dog","Cat","Horse");
list($a, $b, $c) = $my_array;
echo "I have several animals, a $a, a $b and a $c.";
?>
3. each()函数:返回当前元素的键名和键值。该元素的键名和键值返回到带有四个元素的数组中。
两个元素(1 和 Value)包含键值,两个元素(0 和 Key)包含键名。[PHP each() 函数]
<?php
$people = array("Bill", "Steve", "Mark", "David");
var_dump(each($people));
var_dump(each($people));
?>
运行结果:
G:\WAMP\www\2-20-1.php:3:
array (size=4)
1 => string 'Bill' (length=4)
'value' => string 'Bill' (length=4)
0 => int 0
'key' => int 0
G:\WAMP\www\2-20-1.php:4:
array (size=4)
1 => string 'Steve' (length=5)
'value' => string 'Steve' (length=5)
0 => int 1
'key' => int 1
1.3 fopen、fread、fclose操作读取文件
上面file_get_contents打开文件的方式简单、粗暴。下面的
resource fopen ( string $文件名, string 模式)string fread ( resource $操作资源, int 读取长度)
bool fclose ( resource $操作资源 )
通过上面的函数我们来讲解资源类型的通常操作方式:
1.打开资源
2.使用相关函数进行操作
3.关闭资源
参数主要有两个:1.文件打开的路径,2.打开文件的模式
例:$fp=fopen(‘NoAlike.txt’, “r”);
2. fread函数:读取打开的文件资源。返回类型是一个资源类型。
资源类型需要其他的函数来操作这个资源。所有的资源有打开就要有关闭。
也包含两个参数,读取指定长度的文件资源,读取一部份向后移动一部份。至到文件结尾。
例:$contents = fread($fp, 1024);
3. fclose函数:fclose函数的功能是关闭资源。资源有打开就有关闭。
包含一个参数,这个参数就是fopen()返回的资源。
例:fclose($fp);
fopen的模式有下面几个(。・∀・)ノ
模式 | 说明 |
---|---|
r | 只读方式打开,将文件指针指向文件头。 |
r+ | 读写方式打开,将文件指针指向文件头。 |
w | 写入方式打开,将文件指针指向文件头并将文件大小截为零。如果文件不存在则尝试创建 |
w+ | 读写方式打开,将文件指针指向文件头并将文件大小截为零。如果文件不存在则尝试创建 |
a | 写入方式打开,将文件指针指向文件末尾。如果文件不存在则尝试创建 |
a+ | 读写方式打开,将文件指针指向文件末尾。如果文件不存在则尝试创建之 |
x | 创建并以写入方式打开,将文件指针指向文件头。如果文件已存在,则 fopen() 调用失败并返回 FALSE,并生成一条 E_WARNING 级别的错误信息。如果文件不存在则尝试创建 |
x+ | 创建并以读写方式打开,将文件指针指向文件头。如果文件已存在,则 fopen() 调用失败并返回 FALSE,并生成一条 E_WARNING 级别的错误信息。如果文件不存在则尝试创建 |
r模式示例:
1.打开文件:fopen()
<?php
//你可以创建一个NoAlike.txt,以只读模式打开
$fp = fopen('NoAlike.txt', "r");
//var_dump()操作一下$fp看看效果,输出的是不是只有类型提示的是resource
var_dump($fp);
?>
2.读取文件:fread()
<?php
$fp = fopen('NoAlike.txt', "r");
//打开一个文件类型后,读取长度
$contents = fread($fp, 1024);
?>
3.关闭文件:fclose()
<?php
$fp = fopen($filename, 'r');
$contents = fread($fp, 1024);
fclose($fp);
echo $contents;
?>
其他注意事项:
模式 | 说明 |
---|---|
t | windows下将\n转为\r\n |
b | 二进制打开模式 |
说明:
Windows 下提供了一个文本转换标记(’t’)可以透明地将 \n 转换为 \r\n。
与此对应还可以使用 ‘b’ 来强制使用二进制模式,这样就不会转换数据。要使用这些标记,要么用 ‘b’ 或者用 ‘t’ 作为 mode 参数的最后一个字符。
二. 创建和修改文件内容
2.1 file_put_contents写入文件
int file_put_contents ( string $文件路径, string $写入数据])功能:向指定的文件当中写入一个字符串,如果文件不存在则创建文件。返回的是写入的字节长度
<?php
$data = "在PHP中文网学好PHP,妹子票子不再话下!";
$numbytes = file_put_contents('bin.txt', $data);
if($numbytes){
//$numbytes接收到整形的数字
echo '写入成功,我们读取看看结果试试:';
echo file_get_contents('bin.txt');
}else{
echo '写入失败或者没有权限,注意检查';
}
?>
2.2 fwrite配合fopen进行写入操作、fopen()打开模式的比较
int fwrite ( resource $文件资源变量, string $写入的字符串 [, int 长度])注:fwrite的别名函数是fputs
1. fopen()的w模式:写入方式打开,将文件指针指向文件头并将文件大小截为零。如果文件不存在则尝试创建。每一次写入新的数据时,都会将原来的数据清空之后才写入!
<?php
$filename = 'test.txt';
$fp= fopen($filename, "w");
$len = fwrite($fp, '我是一只来自北方的狼,却在南方冻成了狗');
fclose($fp);
print $len .'字节被写入了\n';
?>
总结:
1. 不论有没有新建都会打开文件重新写入
2.原有的文件内容会被覆盖掉
3.文件不存在会创建
那我们来对比一下以下几个模式的不同:
模式 | 说明 |
---|---|
r | 只能读不能使用fwrite写 |
r+ | 可操作读、写(可使用fwrite写入) |
w | 只可以写功能 |
w+ | 即可读又可以写 |
2.3 a模式和w模式、x模式和w模式的不同
1. a模式和w模式总结:模式 | 总结 |
---|---|
x | 每次写入会干掉原有文件的内容,文件不存在都会创建 |
a | 每次写入都会向文件的尾端追加内容 |
2. x模式和w模式总结:
<?php
$filename = 'test.txt';
$fp= fopen($filename, "x");
$len = fwrite($fp,'读大学迷茫了,PHP中文网学PHP给你希望');
echo $len .'字节被写入了\n';
?>
总结:
1.文件存在的时候会报错
2.如果把$filename 改成其他的文件名,就可以了。但是,再次刷新的时候又报错了
3.x+ 是增强的x模式。读取时也可以使用。
三. 创建临时文件
使用这个函数:resource tmpfile ( )
功能:创建一个临时文件,返回资源类型。关闭文件即被删除。
<?php
//创建了一个临时文件,创建后并且打开这个文件
$handle = tmpfile();
//向里面写入了数据
$numbytes = fwrite($handle, '写入临时文件');
//关闭临时文件,文件即被删除
fclose($handle);
echo '向临时文件中写入了'.$numbytes . '个字节';
?>
四. 移动、拷贝和删除文件
4.1 重命名文件
bool rename(oldname,newname,context);参数 | 描述 |
---|---|
oldname | 必需。规定要重命名的文件或目录(文件夹)。 |
newname | 必需。规定文件或目录的新名称。 |
context | 可选。规定文件句柄的环境。context 是可修改流的行为的一套选项。 |
<?php
//旧文件名
$filename = 'test.php.old';
//新文件名
$filename2 = 'test.php';
//复制文件
rename($filename, $filename2);
?>
4.2 复制文件
bool copy(源文件,目标文件);功能:将指定路径的源文件,复制一份到目标文件的位置。如果复制到当前目录下,则必须重新改一个名字,其他目录下的话也要在目的路径下加上文件名,不管改不改名字。
copy(source,destination):
参数 | 描述 |
---|---|
source | 必需。规定要复制的文件。 |
destination | 必需。规定复制文件的目的地。 |
(1)创建文件并复制到当前文件夹下面↓↓
<?php
//创建文件
$fi = fopen('copy.txt',"w");
$a=fwrite($fi,"");
//旧文件名
$filename = 'copy.txt';
//新文件名
$filename2 = $filename . '_new.txt';
//修改名字。
copy($filename, $filename2);
fclose($fi);
?>
(2)创建文件并复制到其他文件夹下面↓↓
<?php
//创建文件
$fi = fopen('copy.txt',"w");
$a=fwrite($fi,"");
//旧文件名
$filename = 'copy.txt';
//新文件名
$filename2 = "./01/copy.txt";
//修改名字。
copy($filename, $filename2);
fclose($fi);
?>
4.3 删除文件
bool unlink(指定路径的文件);<?php
$filename = 'test.txt';
if (unlink($filename)) {
echo "删除文件成功 $filename!\n";
} else {
echo "删除 $filename 失败!\n";
}
?>
五. 检测文件属性函数
函数 | 功能 |
---|---|
bool file_exists ( $指定文件名或者文件路径) | 文件是否存在 |
bool is_readable ( $指定文件名或者文件路径) | 文件是否可读 |
bool is_writeable ( $指定文件名或者文件路径) | 文件是否可写 |
bool is_executable ( $指定文件名或者文件路径) | 文件是否可执行 |
bool is_file ( $指定文件名或者文件路径) | 是否是文件 |
bool is_dir ( $指定文件名或者文件路径) | 是否是目录 |
void clearstatcache ( void ) | 清楚文件的状态缓存 |
<?php
$g=file_exists("install.txt");
echo $g;
if(file_exists('install.txt')){
echo '已安装,请不要再次进行安装';
exit;
}
else
echo 5462564;
?>
运行结果:1 已安装,请不要再次进行安装
六. 文件常用函数和常量
6.1 目录分割符常量
平台 | 分割符 |
---|---|
windows | \ 或者 / |
类unix | / |
- windows 的路径格式为 d:\xxx\xxx 注意:windows支持 d:/xxx/xxx
- linux 的路径格式为 /home/xxx/xxx 注意:如果\home\xxx\xxx 在linux上是错误的
- 所以当开启转义之类的话,转义字符 \ 用一起的话 d:\xxx\xxx 是一样的。判断时候有两个 \ 有的话 再转成一个\ 再把 \ 替换成 /当路径分割,这样在linux上或者windos上的路径就能保持统一了。
6.2 DIRECTORY_SEPARATOR常量
在 Windows 中,斜线(/)和反斜线(\)都可以用作目录分隔符,在linux上路径的分隔符是/,这就导致了一个问题,比如开发机器是windows,有一个图片上传程序,,而我们又使用了(\)作为文件分隔符,调试机器上指定的上传文件保存目录是:define(‘ROOT’,dirname(__FILE__).”\upload”),在本地调试都很正常,但是上传到linux服务器的时候会发现会出错。
这个问题就是出在文件的分隔符上,windows上习惯性的使用\作为文件分隔符,但是在linux上人家是不认识这个标识的,人家只认识/,于是就要引入下面这个php内置变量了:DIRECTORY_SEPARATOR。
上面的写法可以改写为以下无错写法:
define(‘ROOT’,dirname(__FILE__).DIRECTORY_SEPARATOR.”upload”);
这样就可以确保不会出错了。
总结:
DIRECTORY_SEPARATOR是一个返回跟操作系统相关的路径分隔符的php内置命令,在windows上返回\,而在linux或者类unix上返回/,就是这么个区别,通常在定义包含文件路径或者上传保存目录的时候会用到。
6.3 文件指针操作函数
rewind ( resource handle)fseek ( resource handle, int offset [, int from_where])功能:指针回到开始处
功能:文件指针向后移动指定字符
注意:我们在之前的读取当中我们发现fread读取指定长度的数据。读取指定长度的内容,下次再读取的时候从原位置开始再接着向后读取。
[PHP fseek() 函数]参数 | 描述 |
---|---|
file | 必需。规定要在其中定位的文件。 |
offset | 必需。规定新的位置(从文件头开始以字节数度量)。 |
whence | 可选。 可能的值: SEEK_SET - 设定位置等于 offset 字节。默认。 SEEK_CUR - 设定位置为当前位置加上 offset。 SEEK_END - 设定位置为文件末尾加上 offset (要移动到文件尾之前的位置,offset 必须是一个 负值)。 |
6.4 filesize 检测文件的大小
<?php
$filename = 'demo.txt';
echo $filename . '文件大小为: ' . filesize($filename) . ' bytes';
?>
还有一些其他操作文件的函数,读取文件:
函数名 | 功能 |
---|---|
file | 把整个文件读入一个数组中 |
fgets | 从文件指针中读取一行,读到最后返回false |
fgetc | 从文件指针中读取一个字符,读到最后返回false |
ftruncate | 将文件截断到给定的长度 |
6.5 文件的时间函数
函数名 | 功能 |
---|---|
filectime | 文件创建时间 |
filemtime | 文件修改时间 |
fileatime | 文件上次访问时间 |
<?php
$filename = 'demo.txt';
if (file_exists($filename)) {
echo '$filename文件的上次访问时间是:' . date("Y-m-d H:i:s", fileatime($filename));
echo '$filename文件的创建时间是: ' . date("Y-m-d H:i:s", filectime($filename));
echo '$filename文件的修改时间是: ' . date("Y-m-d H:i:s", filemtime($filename));}
?>
七. 文件锁处理机制
注意:不论加上了文件锁后要注意释放。文件锁的用途:
若一个人在写入一个文件,另外一个人同时也打个了这个文件进行写入文件。
这情况下,如果遇到一定的碰撞概率的话,不知道到底谁的操作为准。
因此,这个时候我们引入锁机制。
若用户A在写入或者读取这个文件的时候,将文件加上共享所。我可以读,其他人也可以读。
但是,我如果这与的时候。我使用独占锁。这个文件归我了,你们都别动,除非我将文件锁进行释放。
bool flock(file,lock,block)
参数 | 描述 |
---|---|
file | 必需。规定要锁定或释放的已打开的文件。 |
lock | 必需。规定要使用哪种锁定类型。 lock 参数可以是以下值之一: 要取得共享锁定(读取的程序),将 lock 设为 LOCK_SH(PHP 4.0.1 以前的版本设置为 1) 要取得独占锁定(写入的程序),将 lock 设为 LOCK_EX(PHP 4.0.1 以前的版本中设置为 2) 要释放锁定(无论共享或独占),将 lock 设为 LOCK_UN(PHP 4.0.1 以前的版本中设置为 3) 如果不希望 flock() 在锁定时堵塞,则给 lock 加上 LOCK_NB(PHP 4.0.1 以前的版本中设置为 4) |
block | 可选。若设置为 1 或 true,则当进行锁定时阻挡其他进程。 |
示例:
<?php
$fp = fopen("demo.txt", "r+");
// 进行排它型锁定
if (flock($fp, LOCK_EX)) {
fwrite($fp, "文件这个时候被我独占了哟\n");
// 释放锁定
flock($fp, LOCK_UN);
} else {
echo "锁失败,可能有人在操作,这个时候不能将文件上锁";
}
fclose($fp);
?>
说明:
- 上例中我为了写入文件,把文件加上了独占锁。
- 如果我操作完成,写入完成后,解除掉了独占锁。
八. 目录(文件夹)处理函数
处理文件夹的基本思想如下:
- 读取某个路径的时候判断是否是文件夹
- 是文件夹的话,打开指定文件夹,返回文件目录的资源变量
- 使用readdir读取一次目录中的文件,目录指针向后偏移一次
- 使用readdir读取到最后,没有可读的文件返回false
- 关闭文件目录
常用函数:
函数名 | 功能 |
---|---|
opendir() | 打开文件夹,返回操作资源 [PHP opendir() 函数] |
readdir() | 读取文件夹资源,返回目录中下一个文件的文件名。 [PHP readdir() 函数] |
is_dir() | 判断是否是文件夹 [PHP is_dir() 函数] |
closedir() | 关闭文件夹操作资源 [PHP is_dir() 函数] |
filetype() | 显示是文件夹还是文件,文件显示file,文件夹显示dir 可能的类型:(fifo、char、dir、block、link、file、unknown) [PHP is_dir() 函数] |
九. 文件权限设置
文件权限设置的函数在系统管理级别的软件中很常用。
例如:某个文件不准许guest组(来宾用户)查看。在企业管理中,某些用户或者某些用户文件只准读取不准修改。这都是非常常用的功能。
注:windows下面有些功能无法实现。
函数名 | 功能 |
---|---|
chmod | 修改读取模式 |
chgrp | 修改用户组 |
chown | 修改权限 |
上面的函数用法与linux的权限操作的用法一样。
chmod 主要是修改文件的的权限
<?php
//修改linux 系统/var/wwwroot/某文件权限为755
chmod("/var/wwwroot/index.html", 755);
chmod("/var/wwwroot/index.html", "u+rwx,go+rx");
chmod("/somedir/somefile", 0755);
?>
十. 文件路径函数
我们经常会遇到处理文件路径的情况。
- 文件后缀需要取出来
- 路径需要取出名字不取目录
- 只需要取出路径名中的目录路径
- 或者把网址中的各个部份进行解析取得独立值
- 甚至是自己组成一个url出来
……
常用路径处理函数:
函数名 | 功能 |
---|---|
pathinfo() | 返回文件的各个组成部份 |
basename() | 返回文件名 |
dirname() | 文件目录部份 |
parse_url() | 网址拆解成各部份 |
http_build_query() | 生成url 中的query字符串 |
http_build_url() | 生成一个url |
10.1 pathinfo()函数
功能:以关联数组的形式返回文件路径的信息pathinfo(path,options)
参数 | 描述 |
---|---|
path | 必需。规定要检查的路径。 [PHP pathinfo() 函数] |
process_sections | 可选。规定要返回的数组元素。默认是 all。 可能的值: PATHINFO_DIRNAME - 只返回 dirname PATHINFO_BASENAME - 只返回 basename PATHINFO_EXTENSION - 只返回 extension |
<?php
$path_parts = pathinfo('d:/www/index.inc.php');
echo '文件目录名:'.$path_parts['dirname']."<br />";
echo '文件全名:'.$path_parts['basename']."<br />";
echo '文件扩展名:'.$path_parts['extension']."<br />";
echo '不包含扩展的文件名:'.$path_parts['filename']."<br />";
?>
结果如下:
文件目录名:d:/www
文件全名:lib.inc.php
文件扩展名:php
不包含扩展的文件名:lib.inc
10.2 basename()函数
功能:返回路径中不带有文件扩展名的文件名basename(path[,suffix])
参数 | 描述 |
---|---|
path | 必需。规定要检查的路径。 [PHP basename() 函数] |
suffix | 可选。指定文件名到了指定字符停止。 |
<?php
echo "1: ".basename("d:/www/index.d", ".d").PHP_EOL;
echo "2: ".basename("d:/www/index.php").PHP_EOL;
echo "3: ".basename("d:/www/passwd").PHP_EOL;
?>
执行结果如下
1: index
2: index.php
3: passwd
10.3 dirname()函数
功能:返回文件路径的文件目录部份,不包含文件名。dirname(path)
参数 | 描述 |
---|---|
path | 必需。规定要检查的路径。 [PHP dirname() 函数] |
<?php
echo dirname(__FILE__);
?>
执行结果如下
G:\WAMP\www
10.4 parse_url()函数
功能:将网址拆解成各个部份,返回一个数组mixed parse_url ( string $路径 )
<?php
$url = 'http://username:password@hostname:9090/path?arg=value#anchor';
var_dump(parse_url($url));
?>
结果如下:
array(8) {
["scheme"]=> string(4) "http"
["host"]=> string(8) "hostname"
["port"]=> int(9090)
["user"]=> string(8) "username"
["pass"]=> string(8) "password"
["path"]=> string(5) "/path"
["query"]=> string(9) "arg=value"
["fragment"]=> string(6) "anchor"
}
10.5 http_build_query()函数
功能:生成url 中的query字符串string http_build_query ( mixed $需要处理的数据)
<?php
//定义一个关联数组
$data = [
'username'=>'php',
'area'=>'hubei'
];
//生成query内容
echo http_build_query($data);
?>
结果如下:
username=php&area=hubei
注:PHP_EOL 常量
在 windows平台相当于 echo “\r\n”;
在unix\linux平台相当于 echo “\n”;
在mac平台相当于 echo “\r”;
十一. 文件系统实例案例
11.1 文件留言本
先来说两个下面用到的两个字符串函数和一个数组函数:
[trim()函数]:移除字符串两侧的空白字符或其他预定义字符。[explode()函数]:把字符串打散为数组。
[each()函数]:返回当前元素的键名和键值。该元素的键名和键值返回到带有四个元素的数组中。
[视频教程]
1. 文件结构:
index.php —展示输入框和留言内容,并将内容提交到write.php;
write.php —接收并处理来自index.php的内容,然后向message.txt写入数据;
message.txt —接收并存入来自write.php的聊天内容。
index.php文件:
<?Php
//设置时区
date_default_timezone_set('PRC');
//读了内容
@$string = file_get_contents('message.txt');
//如果$string 不为空的时候执行,也就是message.txt中有留言数据
if (!empty($string)) {
//每一段留言有一个分格符,但是最后多出了一个&^。因此,我们要将&^删掉
$string = rtrim($string, '&^');
//以&^切成数组
$arr = explode('&^', $string);
//将留言内容读取
foreach ($arr as $value) {
//将用户名和内容分开
list($username, $content, $time) = explode('$#', $value);
echo '用户名为<font color="gree">' . $username . '</font>内容为<font color="red">' . $content . '</font>时间为' . date('Y-m-d H:i:s', $time);
echo '<hr />';
}
}
?>
<h1>基于文件的留言本演示</h1>
<form action="write.php" method="post">
用户名:<input type="text" name="username" /><br />
留言内容:<textarea name="content"></textarea><br />
<input type="submit" value="提交" />
</form>
write.php文件:
<?php
//追加方式打开文件
$fp=fopen('message.txt','a');
//设置时间
$time=time();
//得到用户名
$username=trim($_POST['username']);
//得到内容
$content=trim($_POST['content']);
//组合写入的字符串:内容和用户之间分开,使用$#
//行与行之间分开,使用&^
$string=$username.'$#'.$content.'$#'.$time.'&^';
//写入文件
fwrite($fp,$string);
//关闭文件
fclose($fp);
header('location:index.php');
?>
步骤1:在www目录下的index.php里面复制上面相对应的内容、新建一个write.php文件并复制相应的内容、新建一个message.txt空文件;
步骤2:运行index.php如下:
步骤3:向留言框输入文字并点击提交
11.2 修改配置文件
[视频教程]