文件系统概述
- 在window中,我们只能获得file、dir、unknown三种文件类型
- 在Unix中,我们能够获得的文件类型如下:
- filetype()函数,能够获取文件的类型,文件不存在,则返回false
<?php
echo filetype("php.ini");
// 运行结果:
// file
?>
- 可以是用is_file()判断是否是文件,is_dir()判断是否是目录,is_link()判断是否是符号连接
- 文件的属性,以下列出php获得文件属性的几个函数
<?php
echo filetype("php.ini")."<br/>";
echo is_readable("php.ini")."<br/>";
echo filesize("php.ini");
// 运行结果:
// file
// 1
// 0
?>
目录的基本操作
解析目录路径
- 使用“.”表示当前路径,使用“..”表示父目录
- DIRECTORY_SEPARATOR常量,能够获得当前系统的路径分隔符
<?php
$var=DIRECTORY_SEPARATOR;
echo $var;
// 运行结果:
// \ 由于本程序是在window操作系统中运行
?>
- 函数basename():返回路径中文件名称的部分
第二个为可选参数,规定文件的扩展名,如果提供了则不会输出文件的扩展名
- dirname():给出一个全路径,返回去掉文件名后的路劲
- pathinfo():返回一个关联数组包含目录名、基本名、扩展名三个部分,分别通过:dirname、basename、extension下标来获得
<?php
$array=pathinfo("D:/phpstudy_pro/WWW/index.php");
echo $array["dirname"]."<br/>";
echo $array["basename"]."<br/>";
echo $array["extension"];
// 运行结果:
// D:/phpstudy_pro/WWW
// index.php
// php
?>
遍历目录
- 函数opendir(),接受一个目录的路径或目录名,返回目录句柄(整数类型),如果不存在,返回false
- 函数readdir(),接受一个可操作的句柄,返回当前目录指针位置的一个文件名,当指针位于目录的结尾时,因为没有文件,则返回false
- 函数closedir(),接受一个可操作的句柄,没有返回值,关闭已经打开的目录
- 函数rewinddir(),接受一个可操作的句柄,将目录指针重置到目录的开头
<?php
$file=opendir("D:\phpstudy_pro\WWW");
while (readdir($file)) {
echo readdir($file)."<br/>";
}
closedir($file);
// 运行结果:
// .. 表示父目录
// error
// index.php
// php.ini
?>
统计目录大小
- 以下代码完成统计一个目录当中的所有文件大小
- 统计磁盘大小可以使用disk_free_space()和disk_total_space()来实现
<?php
function file_size($filePath){
$filesize=0;
$fileHandle=opendir($filePath);
while($file=@readdir($fileHandle)){
if($file=="." or $file=="..") #排除当前目录与父目录
continue;
$filename=$filePath.DIRECTORY_SEPARATOR."$file"; #获得完整目录
if(is_dir($filename)){
$filesize+=file_size($filename); #递归计算子目录大小
}
if(is_file($filename)){
$filesize+=filesize($filename); #计算文件大小
}
}
closedir($fileHandle);
return $filesize; #返回最终结果
}
$filePath="D:\phpstudy_pro\WWW";
echo round(file_size($filePath)/1024,2) ."KB"; #转换成KB,并保留两位小数
?>
建立和删除目录
- mkdir()建立一个目录
- rmdir()删除目录,且是删除空目录,目录当中没有文件
- unlink()将目录中的每个文件都删除掉
- 如果当前删除目录当中有子目录,就必须要递归删除
<?php
function remove_dir($dirPath){
if (!file_exists($dirPath))
return 0; #返回0表示目录不存在
$dirHandle=opendir($dirPath);
while($file=readdir($dirHandle)){ #如果有子目录或者子文件,进行循环删除
if ($file=="." or $file=="..")
continue;
$filename=$dirPath.DIRECTORY_SEPARATOR.$file;
if(is_dir($filename)){
remove_dir($filename);
rmdir($filename);
}
if(is_file($filename))
unlink($filename);
}
closedir($dirHandle);
rmdir($dirPath); #删除自己本身目录
return 1; #返回1表示删除成功
}
echo remove_dir("D:\phpstudy_pro\WWW\\remove");
?>
复制目录
- 复制文件使用copy()函数进行,第一参数是要复制的文件,第二个参数是要复制到那个位置,都是提供完整的路径名称
- 创建目录使用mkdir()函数,提供完整的目录名
- PHP中没有直接复制目录的命令,因此需要使用递归完成
文件的基本操作
文件的打开与关闭
- fopen()函数
- 第一个参数,要打开文件的url,可以是服务器中的绝对路径、相对路径,还可以是网络当中的资源
- 第二个参数,打开文件的模式
- 第三个参数是可选的,如果资源位于本地文件系统,PHP则认为可以使用本地路径或是相对路径来访问资源的,如果将参数设置为1,这样就会使PHP考虑配置指令include_path中指定的路径
- 第四个参数也是可选的,fopen()函数允许文件名称以协议名称开始,在一个远程位置打开这个文件
- 如果打开成功,该函数返回文件的指针,否则返回false
- fclose()函数,接受一个文件指针,并关闭这个文件,成功返回True,失败返回False
写入文件
- 第一个参数,文件指针
- 第二个参数,要写入的字符串
- 第三个参数,表示要写入length长度的字符串,否则将一直写入,知道将内容全部写入为止
- file_put_contents():可以快速写入文件
- 第一个参数,文件名
- 第二个参数,要写入的内容
<?php
$text="你好,世界";
$filename=".\data.txt";
echo file_put_contents($filename, $text); #快速写入文件
?>
读取文件
- 判断文件是否到达末尾feof()函数,接受一个文件指针,文件指针达到末尾,返回True
- 函数 fread()
- 该函数打开handle的文件内容,并读取length的长度,当到达长度或者遇到文件结尾EOF时,停止读取,并返回读取的内容
<?php
#写入数据
$text="你好,世界";
$filename=".\data.txt";
file_put_contents($filename, $text);
#读取文件
$file=fopen($filename, "r+");
echo fread($file, 15);
fclose($file);
// 运行结果:
// 你好,世界
?>
- file_get_contents()
- 接受一个文件路径,返回读取的内容,能够快速读取需要的内容
- fgets()函数
- 返回length-1个字节,如果忽略length参数,则默认为1024个字节,读取失败返回false
- fgetc()函数:只读取当前指针位置处的一个节符,如果遇到EOF标志,则返回false
- file()函数:接受一个文件路径,返回一个数组,该数组的每个元素存储了文件中的一行,并且将换行符添加在元素的末尾,
<?php
$filename=".\data.txt";
$array=file($filename);
print_r($array);
// 运行结果:
// Array ( [0] => 你好,世界 [1] => hello,siqu )
?>
- readfile():接受一个文件路径,读取整个文件,并立即输出到缓冲区,并返回读取的字节数,能够轻松的将内容显示在浏览器当中
<?php
$filename=".\data.txt";
$byte_number=readfile($filename);
echo "<br/>".$byte_number;
#运行结果:
// 你好,世界 hello,siqu
// 27
?>
移动文件指针
由于有的时候,需要读取文件中不同位置的文件数据,因此需要对文件指针进行移动,主要有以下三个函数
- ftell函数,获取指定文件中当前指针位置的偏移量
- fseek函数,将文件指针移动到offset的位置,如果没有指定第三个参数,则将位置设定为文件开头的offset字节处,
- SEEK_CUR:设置指针位置为当前位置加上第二个参数所提供的offset字节
- SEEK_END:设置指针位置为EOF加上offset字节。在这里offset必须为负数
- SEEK_SET:设置指针位置加上offset字节处,这与忽略第三个参数whence效果相同
文件的锁定机制
文件的锁定机制,避免多个进程对同一文件进行操作,以免造成文件的损坏,因此,当一个进程在访问文件时,应该将文件进行锁定
- 第二个参数规定使用哪种锁类型
- LOCK_SH:取得共享锁定(从文件中读取数据时锁定)
- LOCK_EX:取得独占锁定(从文件中写入数据时锁定)
- LOCK_UN:释放锁定(无论共享或独占锁,都用它释放)
- LOCK_NB:附加锁定(如果不希望flock()在锁定时堵塞,则应在上述锁定后加上该锁)
云端留言板案例:
<html>
<head><title>云端留言板</title></head>
<body>
<form action="" method="POST">
姓名:<input type="text" name="username"/><br/><br/>
内容:<input type="text" name="userMessage"><br/><br/>
<input type="submit" name="sub" value="提交">
</form>
<?php
#定义写入函数
function writeMessage($filePath,$message){
$file=fopen($filePath, "a");
if(flock($file, LOCK_EX)){
fwrite($file,$message);
}else{
echo "文件锁定失败";
}
fclose($file);
}
#定义读取文件函数,返回一个结果的二维数组
function readMessage($filePath){
$file=fopen($filePath,"r");
if(flock($file, LOCK_SH)){
$i=0;
$array=array();
while(!feof($file)){ #循环到结尾为止
$message=fgets($file);
if ($message!=""){ #读出来的内容不为空时,才读取,排除最后一行空行
$message_array=explode("|", $message); #将一行内容分隔开
$array[$i]=$message_array; #将分隔开的数组添加进总数组当中
$i+=1;
}
}
}else{
echo "读取锁定失败";
}
return $array;
}
$filePath=".\data.txt";
if($_POST["sub"]){
$message=$_POST["username"]."|".$_POST["userMessage"]."\n"; #组成完成的内容:写入文件中
writeMessage($filePath,$message);
}
if(file_exists($filePath)){
$array=readMessage($filePath);
foreach ($array as $key=>$value) { #遍历数组,读取其中的内容
echo "姓名:".$value[0]." ";
echo "内容:".$value[1]."<br/>";
}
}
?>
</body>
</html>
运行结果:
文件的一些基本操作函数
文件的上传与下载
客户端的文件上传配置
- 在form表单中,通过type="file"来标记选择本地文件,如果支持上传操作,必须要在form表单中,将enctype和method两个属性指明相应的值
- enctype=“multipart/from-data”用来制定表单编码数据方式,让服务器知道,我们要传递一个文件,并带有常规的表单信息
- method=“POST”用来指明发送数据的方法
- 还需要在form中添加一个type=“hidden”的input框,name的值为“MAX_FILE_SIZE”的隐藏值域,并通过配置Value属性,来制定上传文件的最大大小,不能超过PHP配置中的upload_max_filesize值的大小
<html>
<head><title>云端留言板</title></head>
<body>
<form enctype="multipart/form-data" method="POST">
<input type="hidden" name="MAX_FILE_SIZE" value="10000" >
<input type="file" name="file" value="上传文件">
<input type="submit" name="sub" value="上传">
</form>
</body>
</html>
服务器端的配置
- 以下是PHP对文件处理的相关配置
- $_FILES全局数组,文件上传之后,会保存在临时目录中,并且提供相关信息给$_FILE全局数组
文件类型请查看MIME类型参考手册
第一维“myfile”字段将根据你在type=“file”的input框中name属性决定
- is_upload_file(),判断是否由HTTP POST方法上传,如果是则返回false,接受一个文件名称
- move_upload_file(),可以使用该函数移动文件到新的位置,
该函数有一个额外的功能,即确保所上传的文件是合法的(通过POST方法传递的),如果不合法或者移动失败,则返回false,成功返回true
<html>
<head><title>文件上传</title></head>
<body>
<form enctype="multipart/form-data" method="POST">
<input type="hidden" name="MAX_FILE_SIZE" value="10000" >
<input type="file" name="file" value="上传文件">
<input type="submit" name="sub" value="上传">
</form>
<?php
#上传“.\data.txt”文件
if($_POST["sub"] and $_FILES["file"]["error"]==0 ){ #如果点击上传按钮
if(is_uploaded_file($_FILES["file"]["tmp_name"])){ #检查是否合法
move_uploaded_file($_FILES["file"]["tmp_name"], ".\up.txt"); #移动上传文件的位置
echo "上传成功"; #输出成功提示
}
}else{
echo "文件上传失败";
}
?>
</body>
</html>
最后,我们当前目录中,的确看到了上传成功的文件up.txt
- 另外,如果同时上传多个文件,则可以使用多个file文件框,而$_FILES则会变成一个三维数组,例如:
$_FILE["file"]["error"][0]
,最后的下标表示上传file文件框的编号
文件的下载
- 简单的文件下载可以使用a标签,但是只能下载一些浏览器不能默认识别的MIME类型文件
- 为了提高安全性,不希望在a标签中直接给出下载链接,则可以通过以下方法实现,利用PHP给浏览器发送一些特定的信息
<html>
<head><title>文件下载</title></head>
<body>
<?php
$filename=".\data.txt";
header("Content-Type:text/plain");
header('Content-Disposition:attachment;filename='."'".$filename."'");
header("Content-Length:".filesize($filename));
readfile($filename);
?>
</body>
</html>
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END
暂无评论内容