PHP文件系统

1、文件检测

1.1、存在性检测:bool file_exists(string $filename);

1.2、类型检测: string filetype(string $filename),可能的返回值有 fifo,char,dir,block,link,file 和 unknown,出错返回false

bool is_file(string $filename);判断是否是文件

bool is_dir(string $filename);判断是否是目录

1.3、文件大小检测:filesize(string $filename);文件大小或目录大小

 

2、打开和关闭文件

2.1、resource fopen(string filename,string mode):打开文件或URL,mode可设置文件的打开模式

打开模式:

"r" 只读方式打开,将文件指针指向文件头

"r+" 读写方式打开,将文件指针指向文件头

"w" 写入方式打开,将文件指针指向文件头并将文件大小截为零,文件不存在则新建文件

"w+" 读写方式打开,将文件指针指向文件头并将文件大小截为零,文件不存在则新建文件

"a" 写入方式打开,将文件指针指向文件结尾,如果文件不存在则创建文件

"a+" 读写方式打开,将文件指针指向文件结尾,如果文件不存在则创建文件

返回值:函数执行成功返回一个文件句柄,否则返回 FALSE。

fopen()函数也用于创建文件:如果用 fopen() 打开并不存在的文件,则会创建文件 例:创建名为 "testfile.txt" 的新文件:$myfile = fopen("testfile.txt", "w");

touch函数也可以创建一个文件

2.2、bool fclose(resource $handle):关闭一个已打开的文件

3、文件指针操作

3.1、bool rewind(resource $handle);将指针设为文件流的开头

3.2、int fseek(resource  $handle, int offset);;将指针在文件中定位,成功则返回 0;否则返回 -1

3.3、ftell(resource $handle);返回文件指针的读/写位置

4、读取文件内容

4.1、读取相关检测函数

is_readable(string $filename);判断给定文件名是否可读

feof(resource $handle);检查是否已到达文件末尾 "end-of-file" (EOF) 如果文件指针到了 EOF 或者出错时则返回 TRUE,否则返回一个错误(包括 socket 超时),其它情况则返回 FALSE。

4.2、读取fopen打开的文件资源

fread()从文件读取最多length个字节。length参数常搭配filesize()函数使用

string fread(resource $handle,int $length) 

应用:读取图片内容并输出

header('content-type:image/jpeg'); 
$file='test.jpg'; 
$fr=fopen($file,'r') or die("Unable to open file!"); 
echo fread($fr,filesize($file));
fclose($fr);

fgets()从文件资源中读取一行,调用此函数后,文件指针会移动到下一行。

string fgets(resource $handle[, int $length ]) 

拓展:fgetss函数从文件指针中读取一行并过滤掉 HTML 标记

fgetc() 从文件资源中读取一个字符,调用此函数后,文件指针会移动到下一个字符。

string fgetc(resource $handle) 

应用:逐字符读取文件,直到 end-of-file: 

$myfile = fopen("test.txt", "r") or die("Unable to open file!"); 
while(!feof($myfile)) { 
    echo fgetc($myfile); 
} 
fclose($myfile);

4.3、不需要资源,直接读取

readfile() 读取文件并写入到输出缓冲,不用echo,读取后直接输出

int readfile(string $filename[, bool $use_include_path = false[,resource $context ]]) 

file()将文件的每一行作为一个元素存入数组中返回

array file(string $filename)
$f_arr = file('test.txt');
foreach($f_arr as $cont){ 
    echo $cont." "; 
}

 

file_get_contents() 将整个文件读入一个字符串,此函数性能比fread函数性能好

 

string file_get_contents(string $filename[,bool $use_include_path=false[,resource $context[,int $offset = -1[,int $maxlen ]]]]) 

 

应用:网站数据采集器 

$url='http://www.baidu.com'; 
$str=file_get_contents($url); 
echo $str;

5、写入文件

5.1、fwrite()将字符串写入指定文件,返回写入的字符数,出现错误时则返回 FALSE

int fwrite(resource $handle,string $string[,int $length ])

5.2、file_put_contents()

int file_put_contents(string $filename, mixed $data[,int $flags=0[,resource $context]])
file_put_contents($file,'abc');  //覆盖写入
file_put_contents($file,'abc',FILE_APPEND);//追加写入 等同于依次调用 fopen(),fwrite()以及fclose()

应用:页面静态化 

 

$url='http://www.baidu.com'; 
$str=file_get_contents($url); 
file_put_contents('baidu.html',$str);

 

6、重命名、复制、删除、移动

bool rename(string $oldname,string $newname[,resource $context])    //重命名
bool copy(string $source,string $dest[,resource $context])          //复制
bool unlink(string $filename[,resource $context])                   //删除
$sfile='1.jpg'; $dfile='img/'.$sfile; copy($sfile,$dfile);sleep(3); unlink($sfile);//移动(先复制,再删除) 

7、文件上传与下载

 7.1、常见数据格式

图片文件 image/gif、image/jpg、image/jpeg、image/png 

纯文件和html text/plain、text/html

二进制文件 application/octet-stream

音频格式 audio/mpeg

视频格式 video/avi、video/x-ms-wmv

7.2、HTML部分

7.1.1、上传文件一般使用POST方法提交

7.1.2、上传文件必须设置enctype="multipart/form-data"

<form action="upload.php" method="post" enctype="multipart/form-data"> 
    <input type="file" name="upFile">
    <input type="submit" value="上传"> 
</form>

7.3、PHP部分

7.3.1、上传的文件在PHP中可以通过$_FILES获取,超全局数组$_FILES存储的相关数据:

$_FILES['myfile']['name']      //文件名
$_FILES['myfile']['type']        //文件类型
$_FILES['myfile']['size']         //文件大小
$_FILES['myfile']['tmp_name']      //文件保存在临时目录中的路径
$_FILES['myfile']['error']        //错误级别

错误级别:

0 表示没有发生任何错误

1表示上传文件的大小超出了约定值,约定值是upload的值,但不能超过post的值

2表示上传文件的大小超过了 HTML 表单中 MAX_FILE_SIZE 选项指定的值

3表示文件只有部分被上传

4表示没有上传任何文件

7.3.2、PHP中文件默认会上传到一个临时目录, 接收完毕之后会自动删除

7.3.3、PHP上传文件四部曲

a.获取上传文件对应的信息

b.获取上传文件的名称

c.获取上传文件保存的临时路径

d.移动文件

$fileInfo = $_FILES["upFile"];
$fileName = $fileInfo["name"];
$filePath = $fileInfo["tmp_name"];
move_uploaded_file($filePath, "./source/".$fileName);

7.4、限制上传

7.3.1、php文件上传相关配置(pho.ini)

file_uploads = On ; 是否允许上传文件 On/Off 默认是On

upload_max_filesize = 2048M ; 上传文件的最大限制

post_max_size = 2048M ; 通过Post提交的最多数据

max_execution_time = 30000 ; 脚本最长的执行时间 单位为秒

max_input_time = 3000 ; 接收提交的数据的时间限制 单位为秒

memory_limit = 2048M ; 最大的内存消耗

7.3.2、限制大小

客户端限制:

<input type="hidden" name="MAX_FILE_SIZE" value="1000000" />

服务端限制: 

$filesize=$_FILES['files']['size']; 
if($filesize>1000000){
echo "对不起,您上传的文件超过规定的大小!!";
echo "<meta http-equiv=\"Refresh\" content=\"3;url=index.php\">将在3秒钟后返回前页...";
}

 

7.3.3、限制类型

获取文件后缀 

$farr=explode('.',$_FILES['upFile']['name']); 
$fext=array_pop($farr);

限制文件上传类型

$allows=array('jpg','png','gif'); 
if(in_array($fext,$allows)){ 
    ··· 
}else{
    echo "<script>alert('文件类型不允许,只允许上传png|jpg|gif!')</script>"; 
}

7.5、上传文件管理

创建上传日期目录

$year=date('Y'); 
$month=date('m'); 
$day=date('d'); 
$datedir=$uploaddir.'/'.$year.'-'.$month.'-'.$day; if(!file_exists($datedir)){ mkdir($datedir); } 

获取文件后缀

$farr=explode('.',$_FILES['img']['name']); 
$fext=array_pop($farr); 

文件名中加入时间戳和随机数,预防文件同名和猜测攻击 

$frand=time().mt_rand();

最终上传路径和文件名 

$dfile=$datedir.'/'.$frand.'.'.$fext;
//文件上传函数封装
/*
 *@param1 array $file,要上传的文件信息,包含5个元素
 *@param2 string $path,存储位置
 *@param3 string &error, 错误信息
 *@param4 array $type = array(),MIME类型限定
 *@param5 int $size = 2000000, 默认限制最大2M
 *@return mixed, 成功返回文件名,失败返回false
 */
function fileupload($file,$path,&$error,$type = array(),$size = 2000000){
    if(!isset($file['error'])){
        $error = '文件无效';
        return false;
    }
    //有效路径判定
    if(!is_dir($path)){
        $error = '存储路径无效';
        return false;
    }
    //文件上传错误类型判定
    switch($file['error']){
        case 1:
        case 2:
            $error = '文件超过服务器允许大小';
            return false;
        case 3:
            $error = '文件没有上传完整';
            return false;
        case 4:
            $error = '用户没有选择要上传的文件';
            return false;
        case 6:
        case 7:
            $error = '服务器出错';
            return false;
    }
    //判断类型
    if(!empty($type) && !in_array($file['type'],$type)){
        $error = '文件类型不符合';
        return false;
    }
    //大小限制
    if($file['size'] > $size){
        $error = '文件大小超出允许的范围,允许最大大小为:'.string($size/1000000).'M';
        return false;
    }
    //转存文件
    $newfilname = getNewName($file['name']);
    if(@move_uploaded_file($file['tmp_name'],$path.'/'.$newfilname)){
        return $newfilname;
    } else {
        $error = '文件上传失败';
        return false;
    }
}
function getNewName($filename,$rand = 4){
    $newname = date('YmdHis');
    $arr = array_merge(range('a','z'),range('A','Z'));
    shuffle($arr);
    for($i = 0; $i < $rand; $i++){
        $newname .= $arr[$i];
    }
    return $newname.strstr($filename,'.');
}

$file = $_FILES['file'];

$res = fileupload($file,'upload/',$error);
if($res){
    echo '文件上传成功';
}else{
    echo $error;
}

 

7.6、多文件上传 使用数组格式的表单元素,例:

<form action="" method="post" enctype="multipart/form-data"> 
  <input name="file[]" type="file"> <input name="file[]" type="file"> <input name="file[]" type="file">
<input type="submit" value="上传" /> </form>

 

<?php 
if(!empty($_FILES['u_file']['name'])){ 
    $file_name = $_FILES['file']['name']; 
    $file_tmp_name = $_FILES['file']['tmp_name']; 
    for($i = 0; $i < count($file_name); $i++){ 
        if($file_name[$i] != ''){ 
move_uploaded_file($file_tmp_name[$i],$i.$file_name[$i]); echo '文件'.$file_name[$i].'上传成功。更名为'.$i.$file_name[$i].'<br>';
}
}
}
?>

<?php 
echo '<pre>';
var_dump($_FILES);
$files = $_FILES['file'];
for($i = 0, $len = count($files['name']); $i < $len; $i++){
  $file = array(
        'name'        =>$files['name'][$i],
        'type'        =>$files['type'][$i],
        'tmp_name'    =>$files['tmp_name'][$i],
        'error'        =>$files['error'][$i],
        'size'        =>$files['size'][$i]
    );
    $res = fileupload($file,'upload/',$error);
    if($res){
        echo '文件上传成功';
    }else{
        echo $error;
    }
}

 

7.7、文件下载 

$file=$_GET['file']; 
$downfile='img/'.$file; 
$filesize=filesize($downfile); 
header('content-type:application/octet-stream'); 
header("content-disposition:attachment;filename={$file}"); 
header("content-length:{$filesize}"); readfile($downfile);

8、目录操作

8.1、mkdir()创建目录

bool mkdir(string $pathname[,int $mode=0777[,bool $recursive=false[,resource $context]]]) 

 

创建已经存在的目录时会报错,容错写法:

file_exists($pathname) or mkdir($pathname);
//或@mkdir($pathname);

8.2、遍历目录

opendir()打开目录句柄
resource opendir(string $path [,resource $context ]);

readdir()返回目录中下一个文件的文件名。文件名以在文件系统中的排序返回,失败时返回 FALSE

string readdir([resource $dir_handle]); 

closedir()关闭目录句柄

closedir(resource $dir_handle);

使用资源方式遍历目录

$res = opendir('E:/webdev/www');
$file = '';
while($file = readdir($res)){
    echo $file."<br>";
}
closedir($res);

补充:rewinddir(resource $dir_handle):将opendir打开的资源指针重新回到第一个

使用非资源方式遍历目录:

scandir() 返回指定路径中的文件和目录数组,,失败返回false

//array scandir(string $directory[,int $sorting_order[,resource $context]])

$arr
=scandir($dir); foreach($arr as $key=>$val){ if($key>1){ echo $val.'<br>'; } }

递归深入遍历目录:

function myscandir($dir,$deep=0){
    $files = scandir($dir);
    foreach($files as $file){
        if($file == '.' || $file == '..') continue;
        echo str_repeat('&nbsp;',$deep*4),$file.'<br>';
        $tmp_dir = $dir.'/'.$file;
        if(is_dir($tmp_dir)){
            $func_name = __FUNCTION__;
            $func_name($tmp_dir,$deep+1);
        }
    }
}

 

8.3、删除空目录rmdir(string $pathname);

容错写法:@rmdir($dir);

8.4、删除非空目录

操作步骤:遍历、递归

function delDir($dir){ 
    $files=scandir($dir); 
    foreach($files as $key=>$val){ 
        if($key>1){ 
            $file=$dir.'/'.$val;
            if(is_dir($file)) delDir($file); 
            else unlink($file); 
         } 
     } 
     rmdir($dir); 
} 

 

延伸:清空目录及所有子目录文件

function clearDir($dir){
    $files=scandir($dir);
    foreach($files as $key=>$val){
        if($key>1){
            $file=$dir.'/'.$val;
                if(is_dir($file)){
                    clearDir($file);
            }else{
            unlink($file);
            }
         }
    }
}

 

8.6、移动完整目录=>先执行8.5->后执行8.4

8.7、取得当前工作目录:string getcwd ( void )

8.8、改变当前目录:bool chdir(string $directory)

8.9、重命名:同文件重命名,使用rename函数

9、其他函数

pathinfo($str) 返回关于文件路径的信息数组

basename($str) 返回路径中的文件名部分

dirname($str) 返回路径中的目录名称部分

disk_free_space($str)返回目录的可用空间

disk_total_space() 返回一个目录的磁盘总容量

 

posted @ 2019-02-10 09:45  chuanzi  阅读(611)  评论(0编辑  收藏  举报