PHP文件系统处理

文件系统概述

文件类型

PHP是以UNIX的文件系统为模型的,因此Windows系统中我们只能获得"file"、"dir"或者"unknown"三种文件类型。而UNIX系统中,可以获得"block"、"char"、"dir"、"fifo"、"file"、"link"和"unknown"7种类型。

使用filetype()函数获取文件的上述类型,该函数接受一个文件名作为参数,如果文件不存在将返回false。

is_file()判断给定的文件名是否为一个正常的文件。

is_dir()判断给定的文件名是否是一个目录。

is_link()判断给定的文件名是否是一个符号链接。

文件的属性

PHP的文件属性处理函数

clearstatcache()函数清除被PHP缓存的文件信息。对同一个文件名进行多次操作,并且需要该文件信息不被缓存时才需要调用它。

目录的基本操作

解析目录路径

UNIX系统中必须使用正斜线"/"作为路径分隔符,而windows系统中默认使用反斜线"\"作为路径分隔符,在程序中表示时还要将"\"转义,但也接受正斜线"/"作为分隔符的写法。建议使用正斜线"/"作为路径分隔符。

PHP内置常量DIRECTORY_SEPARATOR,其值为当前操作系统的默认文件路径分隔符。

basename()

返回路径中文件名部分。


1

2

3

4

5

<?php

    $path = "D:/amp/php/php.ini";   

    echo basename($path)."<br/>";           //php.ini

    echo basename($path,".ini")."<br/>";    //php

    echo basename($path,".php");            //php.ini

dirname()

给出一个包含有指向一个文件的全路径的字符串,本函数返回去掉文件名后的目录名。


1

2

3

<?php

    $path = "D:/amp/php/php.ini";

    echo dirname($path)."<br/>";        // D:/amp/php

pathinfo()

返回一个关联数组,其中包括指定路径中的目录名、基本名、扩展名三部分。分别通过dirname、basename、extension来引用。


1

2

3

4

5

6

<?php

    $path = "D:/amp/php/php.ini";

    $path_parts = pathinfo($path);

    echo $path_parts[‘dirname‘]."<br/>";    //D:/amp/php

    echo $path_parts[‘basename‘]."<br/>";   //php.ini   

    echo $path_parts[‘extension‘]."<br/>"//i

遍历目录
opendir()

用于打开指定目录,接受一个目录及目录名作为参数,函数返回值可供其他目录函数使用的目录句柄(资源类型)。如果该目录不存在或者没有访问权限,则返回false。

readdir()

读取指定目录,接受已经用opendir()函数打开的可操作目录句柄作为参数,函数返回当前目录指针位置的一个文件名,并将目录指针向后移动一位。当指针位于目录的结尾时,因为没有文件存在则返回false。

closedir()

关闭指定目录,接受已经用opendir()函数打开的可操作目录句柄作为参数。函数无返回值,运行后将关闭打开的目录。

rewinddir()

倒回目录句柄,接受已经用opendir()函数打开的可操作目录句柄作为参数。将目录指针重置到目录开始处,即倒回目录的开头。


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

<?php

    date_default_timezone_set("PRC");

    $num = 0;                                   //用来统计子目录和文件的个数

    $dirname = ‘d:/amp/php‘;                    //保存当前目录下用来遍历的一个目录名

    $dir_handle = opendir($dirname);            //用opendir打开目录

    //将遍历的目录和文件名使用表格格式输出

    echo ‘<table border="0" align="center" width="600" cellspacing="0" cellpadding="0">‘;

    echo ‘<caption><h2>目录‘.$dirname.‘下面的内容</h2></caption>‘;        

    echo ‘<tr align="left" bgcolor="#cccccc">‘;                      

    echo ‘<th>文件名</th><th>文件大小</th><th>文件类型</th><th>修改时间</th></tr>‘;

    

    //使用readdir循环读取目录里的内容

    while($file = readdir($dir_handle)) {  

        //将目录下的文件和当前目录连接起来,才能在程序中使用

        $dirFile = $dirname."/".$file;     

        $bgcolor $num++%2==0 ? ‘#FFFFFF‘ : ‘#CCCCCC‘;                //隔行一种颜色

        echo ‘<tr bgcolor=‘.$bgcolor.‘>‘;                

        echo ‘<td>‘.$file.‘</td>‘;                                      //显示文件名

            echo ‘<td>‘.filesize($dirFile).‘</td>‘;                     //显示文件大小

            echo ‘<td>‘.filetype($dirFile).‘</td>‘;                     //显示文件类型

            echo ‘<td>‘.date("Y/n/t",filemtime($dirFile)).‘</td>‘;      //格式化显示文件修改时间

            echo ‘</tr>‘;

    }

    echo ‘</table>‘;                                                  //关闭表格标记

    closedir($dir_handle);                                              //关闭文件操作句柄

    echo ‘在<b>‘.$dirname.‘</b>目录下的子目录和文件共有<b>‘.$num.‘</b>个‘;

统计目录大小

disk_free_space()计算磁盘空闲容量大小。

disk_total_apace()计算磁盘大小。


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

<?php

    /**

        自定义一个函数dirSize(),统计传入参数的目录大小

        @param  string  $directory  目录名称

        @return double              目录的尺寸大小

    */

    function dirSize($directory) {     

        $dir_size = 0;                                      //用来累加各个文件大小

        if($dir_handle = @opendir($directory)) {            //打开目录,并判断是否能成功打开

            while( $filename = readdir($dir_handle) ) {     //循环遍历目录下的所有文件

                if($filename != "." && $filename != "..") { //一定要排除两个特殊的目录

                    $subFile = $directory."/".$filename;    //将目录下的子文件和当前目录相连

                    if(is_dir($subFile))                    //如果为目录

                        $dir_size += dirSize($subFile);     //递归地调用自身函数,求子目录的大小

                    if(is_file($subFile))                   //如果是文件

                        $dir_size += filesize($subFile);    //求出文件的大小并累加

                }

            }

            closedir($dir_handle);                          //关闭文件资源

            return $dir_size;                               //返回计算后的目录大小

        }

    }

    $dir_size = dirSize("d:/amp/php");                      //调用该函数计算目录大小

    echo round($dir_size/pow(1024,1),2)."KB";               //字节数转换为“KB”单位并输出

建立和删除目录

mkdir()创建一个新目录。rmdir()删除目录,只能删除一个空目录并且目录必须存在,如果是非空目录就需要先进入到目录中,使用unlink()函数将目录中的每个文件都删除掉,再回来将这个空目录删除。


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

<?php

    /**

        自定义函数递归的删除整个目录

        @param  string  $directory 目录名称

    */

    function delDir($directory) {          

        if(file_exists($directory)) {                           //如果不存在rmdir()函数会出错

            if($dir_handle = @opendir($directory)) {            //打开目录并判断是否成功

                while($filename = readdir($dir_handle)) {       //循环遍历目录

                    if($filename != "." && $filename != "..") { //一定要排除两个特殊的目录

                        $subFile = $directory."/".$filename;    //将目录下的文件和当前目录相连

                        if(is_dir($subFile))                    //如果是目录条件则成立

                            delDir($subFile);                   //递归调用自己删除子目录

                        if(is_file($subFile))                   //如果是文件条件则成立

                            unlink($subFile);                   //直接删除这个文件

                    }

                }

                closedir($dir_handle);                          //关闭目录资源

                rmdir($directory);                              //删除空目录

            }

        }

    }

    

    delDir("phpMyAdmin");       //调用delDir()函数,将程序所在目录中的“phpMyAdmin”文件夹删除

复制目录

首先对源目录进行遍历,如果遇到的是普通文件,直接使用copy进行赋值;如果遍历时遇到一个目录,则必须建立该目录,然后再对该目录下的文件进行复制操作,如果还有子目录,则使用递归重复操作,最终将整个目录复制完成。


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

<?php

    /**

        自定义函数递归的复制带有多级子目录的目录

        @param  string  $dirSrc  原目录名称字符串

        @param  string  $dirTo  目标目录名称字符串

    */

    function copyDir($dirSrc, $dirTo) {        

        if(is_file($dirTo)) {                               //如果目标不是一个目录则退出

            echo "目标不是目录不能创建!!";

            return;                                         //退出函数

        }

        

        if(!file_exists($dirTo)) {                          //如果目标目录不存在则创建

            mkdir($dirTo);                                  //创建目录

        }

        

        if($dir_handle = @opendir($dirSrc)) {               //打开目录并判断是否成功

            while($filename = readdir($dir_handle)) {       //循环遍历目录

                if($filename != "." && $filename != "..") { //一定要排除两个特殊的目录

                    $subSrcFile = $dirSrc."/".$filename;    //将源目录的多级子目录连接

                    $subToFile = $dirTo."/".$filename;      //将目标目录的多级子目录连接

                        

                    if(is_dir($subSrcFile))                 //如果源文件是一个目录

                        copyDir($subSrcFile, $subToFile);   //递归调用自己复制子目录

                    if(is_file($subSrcFile))                //如果源文件是一个普通文件

                        copy($subSrcFile, $subToFile);      //直接复制到目标位置

                }

            }

            closedir($dir_handle);                          //关闭目录资源

        }  

    }

    

    //测试函数,将目录"phpMyAdmin"复制到"D:/admin"

    copyDir("phpMyAdmin", "D:/admin");     

文件的基本操作

文件的打开与关闭

fopen()建立与文件资源的连接,fclose()关闭通过fopen函数打开的文件资源。

fopen()

  • 第一个参数:需要被打开的文件URL。
  • 第二个参数:文件操作模式

  • 第三个参数是可选的,如果资源位于本地系统,php则认为可以使用本地路径或是相对路径来访问此资源。如果将这个参数设置为1,就会是php考虑配置指令include_path中指定的路径(在php的配置该文件中设置)。
  • 第四个参数也是可选的。fopen()函数允许文件名称以协议名称开始。例如"http://"并且在一个远程位置打开该文件。通过设置这个参数,还可以支持一些其他的协议。

如果fopen()函数成功地打开一个文件,该函数将返回一个指向这个文件的文件指针。对该文件进行操作所使用的读、写一起其他的文件操作函数,都要使用这个资源来访问该文件。如果打开失败,则返回false。

fclose()

资源类型属于php的基本类型之一,一旦完成资源的处理,已定要将其关闭,否则可能会出现一些预料不到的错误。函数fclose()就会撤销fopen()打开的资源类型,成功时返回true,否则返回false。参数必须是使用fopen()或者fsocketopen()函数打开的已存的文件指针。在目录操作中opendir()函数也是开启一个资源,使用closedir()将其关闭。

写入文件

fwrite()函数就可以将字符串内容写入文件中。在文件中通过字符序列\n表示换行符,表示文件中一行的末尾。当需要一次输入或输出一行信息时。

  • 第一个参数:需要打开的文件资源。
  • 第二个参数:需要输入的字符串内容。
  • 第三个参数:可选。将在输入length个字符串时停止。

1

2

3

4

5

6

7

8

9

10

11

<?php

    //声明一个变量用来保存文件名

    $filename = "d:\\data.txt";

    //使用fopen()函数以只写的模式打开文件,如果不存在则创建它,打开失败则通过程序

    $handle = fopen($filename, "w") or die("打开文件失败!");

    //写入文件

    for ($i = 0; $i < 10; $i++){

        fwrite($handle, $i."写啊写!\r\n");

    }

    //关闭打开的文件资源

    fclose($handle);

读取文件内容

在读取文件时,不仅要注意行结束符号"\n",程序也需要一种标准的方式来识别何时到达文件的末尾,这个标准通常称为EOF(End Of File)字符。在PHP中,使用fepf()函数。该函数接受一个打开的文件资源,判断一个文件指针是否位于的结束出,如果在文件末尾处,则返回true。

fread()

用来在打开文件中读取指定长度的字符串。也可以安全用于二进制文件,在区分二进制文件和文本文件的系统上打开文件时。fopen()函数的mode参数要加上‘b‘。函数Fread()的原型:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

<?php

    header("ContentType:text/html;charset:utf8");

    //从文件中读取制定字节数的内容存入到一个变量中

    $filename = "d:\\data.txt";

    $handle = fopen($filename, "r") or die("文件打开失败!");

    $contents = fread($handle, 100);

    fclose($handle);

    echo $contents."<hr/>";

    

    //从文件中读取全部内容存入到一个变量中,每次读取一部分,循环读取

    $filename = "d:\\01.jpg";

    $handle = fopen($filename, "rb") or die("文件打开失败!");

    $contents = "";

    while (!feof($handle)){

        $contents .= fread($handle, 1024);

    }  

    fclose($handle);

    echo $contents."<hr/>";

    

    //另一种从文件中读取全部内容的方法

    $filename = "d:\\data.txt";

    $handle = fopen($filename, "r") or die("文件打开失败!");

    $contents - fread($handle, filesize($filename));

    fclose($handle);

    echo $contents;

如果只是讲一个文件的内容读入到另一个字符串中,可以用file_get_contents()函数,它的性能比上面的代码好得多。

fgets()、fgetc()

fgets()一次至多从打开的文件资源中读取一行内容。失败返回false。

第一个参数:打开的资源。

第二个参数:可选。length,返回length-1个字节。或者遇到换行或EOF之前读取的所有内容。如果忽略length,默认为1024个字符。


1

2

3

4

5

6

7

<?php

    $handle = fopen("d:\\data.txt", "r") or die("文件打开失败!");

    while (! feof($handle)){

        $buffer = fgets($handle, 4096);

        echo $buffer."<br/>";

    }

    fclose($handle);

fgetc()再打开的文件资源中只读取当前指针位置处的一节字符。如果遇到文件结束标志EOF,将返回false值。


1

2

3

4

5

6

<?php

    $handle = fopen("d:\\data.txt", "r") or die("文件打开失败!");

   while (false !== ($char = fgetc($handle))){

       echo $char."<br/>";

   }

    fclose($handle);

file()

可以把整个文件读入到一个数组中。数组中的每个元素对应文件中相应的行,各元素有换行符分隔,同事换行符仍附加在每个元素的末尾。这样,就可以使用数组的相关函数对文件内容进行处理。

readfile()

该函数可以读取指定的整个文件,立即输出缓冲区,并返回读取的字节数。该函数也不需要使用fopen()函数打开文件。


1

2

<?php

    readfile("d:\\data.txt");

远程访问文件

如果需要访问远程文件,必须在PHP的配置文件中激活"allow_url_fopen"选项,才能使用fopen()函数打开远程文件,而且其他服务器具有访问权限。使用PHP访问远程文件就像访问本地文件一样,都是使用相同的读写函数处理。

如果有合法的访问权限,可以以一个用户的身份和某FTP服务器建立链接,这样就可以想改FTP服务器端的文件进行写操作了。可以用该技术来存储远程日志文件等操作,但仅能用该方法来创建新的文件,如果尝试覆盖已经存在的文件,fopen()函数的调用将会失败。而且要以匿名以外的用户名链接服务器,并需要指明用户名(甚至密码)。"ftp:user:[email protected]/root"。

为了避免由于访问远程主机时发生的超时错误,可以使用set_time_limit()函数对程序的运行时间加以限制。

移动文件指针

int ftell()

返回文件指针的当前位置的偏移量。

int fseek()

移动文件指针到第二个参数offset指定的位置。如果没有提供第三个可选参数whence,则位置将设置为从文件开头的offset字节处,否则,第三个可选参数whence可以设置为三个可能的值。

  • SEEK_CUR:设置指针位置为当前位置加上第二个参数所提供的offset字节。
  • SEEK_END:设置指针位置为EOF加上offset字节。在这里,offset必须设置为负值。
  • SEEK_SET:设置指针位置为offset字节处。这与忽略第三个参数whence效果相同。

执行成功,返回0,失败则返回-1。如果将文件以追加模式"a"或"a+"打开,写入文件的任何数据总是会被附加在后面,不会管文件指针的位置。


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

<?php

    //以只读模式打开文件

    $fp = fopen(‘data.txt‘, ‘r‘) or die("文件打开失败"); 

    

    echo ftell($fp)."<br>";       //输出刚打开文件的指针默认位置,指针在文件的开头位置为0

    echo fread($fp, 10)."<br>";       //读取文件中的前10个字符输出,指针位置发生了变化

    echo ftell($fp)."<br>";       //读取文件的前10个字符之后,指针移动的位置在第10个字节处

    fseek($fp, 100, SEEK_CUR);      //将文件指针的位置,由当前位置向后移动100个字节数

    echo ftell($fp)."<br>";           //文件位置在110个字节处

    echo fread($fp, 10)."<br>";       //读取110到120字节数位置的字符串,读取后指针的位置为120

    fseek($fp, -10, SEEK_END);      //又将指针移动到倒数10个字节位置处

    echo fread($fp, 10)."<br>";       //输出文件中最后10个字符 

    rewind($fp);                    //又移动文件指针到文件的开头

    echo ftell($fp)."<br>";       //指针在文件的开头位置,输出0

    fclose($fp);                    //关闭文件资源

bool rewind():

移动文件指针到文件的开头。

文件的所定机制

flock()

可以对文件使用锁定机制(锁定或释放文件)。当一个进程早访问文件时加上锁,其他进程要想对该文件进行访问,必须等到锁定被释放以后。这样避免在兵法访问同一个文件时破坏数据。

第一个参数:一个已经打开的文件资源。

第二个参数:规定使用哪种锁定类型。值为以下:

  • LOCK_SH取得共享锁定(从文件中读取数据时使用)。
  • LOCK_EX取得独占锁定(像文件中写入数据时使用)。
  • LOCK_UN释放锁定(无论何种锁定,均由此释放)。
  • LOCK_NB附加锁定(如果不希望flock()在锁定时堵塞,则应在上述锁定后加上此锁)。

如果锁定会堵塞的话(已经被flock()锁定的文件,再次锁定时,flock()函数会被挂起,这时成为锁定堵塞),也可以将可选的第三个参数设置为1,则当进行锁定时会阻塞其他进程。锁定操作也可以被fclose()释放。为了让flock()函数发挥作用,在所有访问文件的程序中都必须使用相同的锁定文件。该函数如果成功则返回true,失败则返回false。


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

<html>

    <head><title>网络留言板模式</title></head>

    <body>

        <?php

            //声明一个变量保存文件名,在这个文件中保存留言信息

            $filename = "text_data.txt";   

            

            //判断用户是否按下提交按钮,用户提交后则条件成功

            if(isset($_POST["sub"])){  

                //接收表单中三条内容,并整合为一条,使用“||”分隔,使用“<|>”结尾

                $message = $_POST["username"]."||".$_POST["title"]."||".$_POST["mess"]."<|>";

                writeMessage($filename, $message);  //调用自定义函数,将信息写入文件

            }

            if(file_exists($filename))                  //判断文件是否存在,如果存在则条件成立

                readMessage($filename);                 //文件存在则调用自定义函数,读取数据

            /**

                自定义一个向文件中写入数据的函数

                @param  string  $filename   写入的文件名

                @param  string  $message        写入文件的内容,即消息

            */

            function writeMessage($filename, $message) {   

                $fp = fopen($filename, "a");            //以追加模式打开文件

                if (flock($fp, LOCK_EX)) {              //进行排他型锁定(独占锁定)

                    fwrite($fp, $message);              //将数据写入文件

                        flock($fp, LOCK_UN);            //同样使用flock()函数释放锁定

                } else {                                //如果建立独占锁定失败

                        echo "不能锁定文件!";             //输出错误消息

                }

                fclose($fp);                            //关闭文件资源

            }

            

            /**

                自定义一个遍历读取文件的函数

                @param  string  $filename   读取的文件名

            */

            function readMessage($filename){       

                $fp = fopen($filename, "r");            //以只读的模式打开文件

                flock($fp, LOCK_SH);                    //建立文件的共享锁定

                $buffer = "";                           //将文件中的数据遍历后放入这个字符串中

                while (!feof($fp)) {                    //使用while循环将文件中数据遍历出来 

                    $buffer.= fread($fp, 1024);         //读出数据追加到$buffer变量中

                }  

                

                $data = explode("<|>", $buffer);          //通过“<|>”将每行留言分隔并存入到数组中

                foreach($data as $line) {               //遍历数组将每行数据以HTML输出

                    //将每行数据再分隔

                    list($username, $title, $message)=explode("||",$line);

                    //判断每部分是否为空

                    if($username!="" && $title!="" && $message!="") {  

                        echo $username.‘说:‘;        //输出用户名

                        echo ‘&nbsp;‘.$title.‘,‘;   //输出标题

                        echo $message."<hr>";         //输出留言主题信息

                    }

                }

                flock($fp, LOCK_UN);                    //释放锁定

                fclose($fp);                            //关闭文件资源

            }

        ?>

        

        <!-- 以下为用户输入表单界面(GUI)-->

        <form action="" method="post">

            用户名:<input type="text" size=10 name="username"><br>

            标&nbsp;&nbsp;题:<input type="text" size=30 name="title"><br>

            <textarea name="mess" rows=4 cols=38>请在这里输入留言信息!</textarea>

            <input type="submit" name="sub" value="留言">

        </form>

    </body>

</html>

文件的一些基本操作函数

文件的上传与下载

文件上传

 客户端上传设置

如果支持文件上传操作,必须在<form>标签中将enctype和method两个属性指明相应的值。

  • enctype="multipart/form-data"用来指定表单编码数据方式,让服务器知道,我们要传递一个文件,并带有常规的表单信息。
  • method="POST"用来致命发送数据的方法。

另外,还需要在form表单中设置一个hidden类型的input框。其中name的值为MAX_FILE_SIZE的隐藏值域,并通过设置其VALUE的值限制上传文件的大小(单位字节),但这个值不能超过PHP的配置文件中upload_max_filesize值设置的大小。


1

2

3

4

5

<form action="upload.php"  method="post" enctype="multipart/form-data">

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

    选择文件:<input type="file" name="myfile">

    <input type="submit" value="上传文件">

</form>

在服务端通过php处理上传

要想通过PHP成功地管理文件上传,需要通过以下三方面信息:

  • 设置PHP配置文件中的指令:用于精细地调节PHP的文件上传功能。
  • $_FILES多维数组:用于存储各种与上传文件有关信息,其他数据还使用$_POST去接收。

  • PHP的文件上传处理函数:用于上传文件的后续处理。

文件上传与PHP配置文件的设置有关,首先,应该设置php.ini文件中的一些指令,精细调节PHP的文件上传功能。在PHP配置文件php.ini中和上传文件有关的指令如下表:

除了上述,还有两个专门用于文件上传所使用的is_uploaded_file()和move_uploaded_file()两个函数。

is_uploaded_file()

判断指定的文件是否是通过HTTP POST上传的,如果是返回true。用于防止潜在的攻击者对原本不能通过脚本交互的文件进行非法管理,这可以用来确保恶意的用户无法欺骗脚本去访问本不能访问的文件。

move_uploaded_file()

文件上传后,首先会存储与服务器的临时目录中,可以使用该函数将上传的文件移动到新位置。


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

<?php

    $allowtype = array("gif", "png", "jpg");   //设置充许上传的类型为gif, png和jpg

    $size = 1000000;                           //设置充许大小为1M(1000000字节)以内的文件

    $path = "./uploads";                       //设置上传后保存文件的路径

    

    //判断文件是否可以成功上传到服务器,$_FILES[‘myfile‘][‘error‘] 为0表示上传成功

    if($_FILES[‘myfile‘][‘error‘] > 0) {    

        echo ‘上传错误: ‘;

        switch ($_FILES[‘myfile‘][‘error‘]) {

            case 1:  die(‘上传文件大小超出了PHP配置文件中的约定值:upload_max_filesize‘); 

            case 2:  die(‘上传文件大小超出了表单中的约定值:MAX_FILE_SIZE‘); 

            case 3:  die(‘文件只被部分上载‘);

            case 4:  die(‘没有上传任何文件‘);

            default: die(‘末知错误‘);

        }

    }

    

    //判断上传的文件是否为充许的文件类型,通过文件的后缀名

    $hz = array_pop(explode(".", $_FILES[‘myfile‘][‘name‘]));

    //通过判断文件的后缀方式,来决定文件是否是充许上传的文件类型

    if(!in_array($hz, $allowtype)) {

        die("这个后缀是<b>{$hz}</b>,不是充许的文件类型!");

    }

    

    /* 也可以通过获取上传文件的MIME类型中的主类型和子类型,来限制文件上传的类型

    list($maintype,$subtype)=explode("/",$_FILES[‘myfile‘][‘type‘]);   

    if ($maintype=="text") {   //通过主类型限制不能上传文本文件,例如.txt .html .php等文件

        die(‘问题: 不能上传文本文件。‘);

    } */

    //判断上传的文件是否为充许大小

    if($_FILES[‘myfile‘][‘size‘] > $size ) {

        die("超过了充许的<b>{$size}</b>字节大小");

    }

    

    //为了系统安全,也为了同名文件不会被覆盖,上传后将文件名使用系统定义

    $filename = date("YmdHis").rand(100,999).".".$hz;

    

    //判断是否为上传文件

    if (is_uploaded_file($_FILES[‘myfile‘][‘tmp_name‘])) {

        if (!move_uploaded_file($_FILES[‘myfile‘][‘tmp_name‘], $path.‘/‘.$filename)) { 

            die(‘问题: 不能将文件移动到指定目录。‘);

        }

    }else{

        die("问题: 上传文件{$_FILES[‘myfile‘][‘name‘]}不是一个合法文件: ");

    }

    //如果文件上传成功则输出

    echo "文件{$upfile}上传成功,保存在目录{$path}中,大小为{$_FILES[‘myfile‘][‘size‘]}字节";  

文件下载

PHP使用header()函数发送网页的头部信息给浏览器,该函数接受一个头信息的字符串作为参数。文件下载需要发送的头信息包括以下三部分,通过调用三次header()函数完成,在使用readfile()函数将文件内容读取出来并直接输出。


1

2

3

4

5

6

7

8

9

<?php

    $filename = "test.gif";                                        

    

    header(‘Content-Type: image/gif‘);                                   //指定下载文件类型

    header(‘Content-Disposition: attachment; filename="‘.$filename.‘"‘); //指定下载文件的描述

    header(‘Content-Length: ‘.filesize($filename));                      //指定下载文件的大小  

    

    //将文件内容读取出来并直接输出,以便下载

    readfile($filename);      

文件上传类:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

<?php

    /**

        file: fileupload.class.php  文件上传类FileUpload

        本类的实例对象用于处理上传文件,可以上传一个文件,也可同时处理多个文件上传

    */

    class FileUpload { 

        private $path = "./uploads";                    //上传文件保存的路径

        private $allowtype = array(‘jpg‘,‘gif‘,‘png‘);  //设置限制上传文件的类型

        private $maxsize = 1000000;                     //限制文件上传大小(字节)

        private $israndname = true;                     //设置是否随机重命名文件, false不随机

        

        private $originName;                            //源文件名

        private $tmpFileName;                           //临时文件名

        private $fileType;                              //文件类型(文件后缀)

        private $fileSize;                              //文件大小

        private $newFileName;                           //新文件名

        private $errorNum = 0;                          //错误号

        private $errorMess="";                          //错误报告消息

        

        /**

         * 用于设置成员属性($path, $allowtype,$maxsize, $israndname)

         * 可以通过连贯操作一次设置多个属性值

         *@param    string  $key    成员属性名(不区分大小写)

         *@param    mixed   $val    为成员属性设置的值

         *@return   object          返回自己对象$this,可以用于连贯操作

         */

        function set($key, $val){

            $key = strtolower($key);

            if( array_key_exists( $key, get_class_vars(get_class($this) ) ) ){

                $this->setOption($key, $val);

            }

            return $this;

        }

        /**

         * 调用该方法上传文件

         * @param   string  $fileFile   上传文件的表单名称

         * @return  bool                如果上传成功返回数true

         */

        

        function upload($fileField) {

            $return = true;

            /* 检查文件路径是滞合法 */

            if( !$this->checkFilePath() ) {             

                $this->errorMess = $this->getError();

                return false;

            }

            /* 将文件上传的信息取出赋给变量 */

            $name = $_FILES[$fileField][‘name‘];

            $tmp_name = $_FILES[$fileField][‘tmp_name‘];

            $size = $_FILES[$fileField][‘size‘];

            $error = $_FILES[$fileField][‘error‘];

            /* 如果是多个文件上传则$file["name"]会是一个数组 */

            if(is_Array($name)){       

                $errors=array();

                /*多个文件上传则循环处理 , 这个循环只有检查上传文件的作用,并没有真正上传 */

                for($i = 0; $i < count($name); $i++){

                    /*设置文件信息 */

                    if($this->setFiles($name[$i],$tmp_name[$i],$size[$i],$error[$i] )) {

                        if(!$this->checkFileSize() || !$this->checkFileType()){

                            $errors[] = $this->getError();

                            $return=false; 

                        }

                    }else{

                        $errors[] = $this->getError();

                        $return=false;

                    }

                    /* 如果有问题,则重新初使化属性 */

                    if(!$return)                   

                        $this->setFiles();

                }

            

                if($return){

                    /* 存放所有上传后文件名的变量数组 */

                    $fileNames = array();           

                    /* 如果上传的多个文件都是合法的,则通过销魂循环向服务器上传文件 */

                    for($i = 0; $i < count($name);  $i++){

                        if($this->setFiles($name[$i], $tmp_name[$i], $size[$i], $error[$i] )) {

                            $this->setNewFileName();

                            if(!$this->copyFile()){

                                $errors[] = $this->getError();

                                $return = false;

                            }

                            $fileNames[] = $this->newFileName;  

                        }                  

                    }

                    $this->newFileName = $fileNames;

                }

                $this->errorMess = $errors;

                return $return;

            /*上传单个文件处理方法*/

            } else {

                /* 设置文件信息 */

                if($this->setFiles($name,$tmp_name,$size,$error)) {

                    /* 上传之前先检查一下大小和类型 */

                    if($this->checkFileSize() && $this->checkFileType()){

                        /* 为上传文件设置新文件名 */

                        $this->setNewFileName();

                        /* 上传文件   返回0为成功, 小于0都为错误 */

                        if($this->copyFile()){

                            return true;

                        }else{

                            $return=false;

                        }

                    }else{

                        $return=false;

                    }

                } else {

                    $return=false; 

                }

                //如果$return为false, 则出错,将错误信息保存在属性errorMess中

                if(!$return)

                    $this->errorMess=$this->getError();  

                return $return;

            }

        }

        /**

         * 获取上传后的文件名称

         * @param   void     没有参数

         * @return  string  上传后,新文件的名称, 如果是多文件上传返回数组

         */

        public function getFileName(){

            return $this->newFileName;

        }

        /**

         * 上传失败后,调用该方法则返回,上传出错信息

         * @param   void     没有参数

         * @return  string   返回上传文件出错的信息报告,如果是多文件上传返回数组

         */

        public function getErrorMsg(){

            return $this->errorMess;

        }

        

        /* 设置上传出错信息 */

        private function getError() {

            $str = "上传文件<font color=‘red‘>{$this->originName}</font>时出错 : ";

            switch ($this->errorNum) {

                case 4: $str .= "没有文件被上传"; break;

                case 3: $str .= "文件只有部分被上传"; break;

                case 2: $str .= "上传文件的大小超过了HTML表单中MAX_FILE_SIZE选项指定的值"; break;

                case 1: $str .= "上传的文件超过了php.ini中upload_max_filesize选项限制的值"; break;

                case -1: $str .= "未允许类型"; break;

                case -2: $str .= "文件过大,上传的文件不能超过{$this->maxsize}个字节"; break;

                case -3: $str .= "上传失败"; break;

                case -4: $str .= "建立存放上传文件目录失败,请重新指定上传目录"; break;

                case -5: $str .= "必须指定上传文件的路径"; break;

                default: $str .= "未知错误";

            }

            return $str.‘<br>‘;

        }

        /* 设置和$_FILES有关的内容 */

        private function setFiles($name="", $tmp_name="", $size=0, $error=0) {

            $this->setOption(‘errorNum‘, $error);

            if($error)

                return false;

            $this->setOption(‘originName‘, $name);

            $this->setOption(‘tmpFileName‘,$tmp_name);

            $aryStr = explode(".", $name);

            $this->setOption(‘fileType‘, strtolower($aryStr[count($aryStr)-1]));

            $this->setOption(‘fileSize‘, $size);

            return true;

        }

    

        /* 为单个成员属性设置值 */

        private function setOption($key, $val) {

            $this->$key = $val;

        }

        /* 设置上传后的文件名称 */

        private function setNewFileName() {

            if ($this->israndname) {

                $this->setOption(‘newFileName‘, $this->proRandName());   

            } else{

                $this->setOption(‘newFileName‘, $this->originName);

            }

        }

        

        /* 检查上传的文件是否是合法的类型 */

        private function checkFileType() {

            if (in_array(strtolower($this->fileType), $this->allowtype)) {

                return true;

            }else {

                $this->setOption(‘errorNum‘, -1);

                return false;

            }

        }

        

        /* 检查上传的文件是否是允许的大小 */

        private function checkFileSize() {

            if ($this->fileSize > $this->maxsize) {

                $this->setOption(‘errorNum‘, -2);

                return false;

            }else{

                return true;

            }

        }

        /* 检查是否有存放上传文件的目录 */

        private function checkFilePath() {

            if(empty($this->path)){

                $this->setOption(‘errorNum‘, -5);

                return false;

            }

            if (!file_exists($this->path) || !is_writable($this->path)) {

                if ([email protected]mkdir($this->path, 0755)) {

                    $this->setOption(‘errorNum‘, -4);

                    return false;

                }

            }

            return true;

        }

        

        /* 设置随机文件名 */

        private function proRandName() {       

            $fileName = date(‘YmdHis‘)."_".rand(100,999);      

            return $fileName.‘.‘.$this->fileType;

        }

        

        /* 复制上传文件到指定的位置 */

        private function copyFile() {

            if(!$this->errorNum) {

                $path = rtrim($this->path, ‘/‘).‘/‘;

                $path .= $this->newFileName;

                if (@move_uploaded_file($this->tmpFileName, $path)) {

                    return true;

                }else{

                    $this->setOption(‘errorNum‘, -3);

                    return false;

                }

            } else {

                return false;

            }

        }

    }

来自为知笔记(Wiz)

时间: 2024-10-04 05:19:25

PHP文件系统处理的相关文章

刨根问底:ext3/ext4文件系统最大空间及单个文件大小演算法则

从ext3和ext4文件系统来窥探空间和文件大小的演算法则 学习操作系统就不得不研究磁盘以及磁盘文件系统,磁盘是底层物理设备,而文件系统则是管理磁盘的上层工具,文件系统规划了磁盘存放数据的格式,确定了一个操作系统能够支持多大的磁盘空间,每个分区能够支持多大的数据空间,以及每个文件所能支持的大小.通常对系统管理员而言,最需要的知道的就是最大磁盘空间,最大分区空间以及最大文件的大小.本论题只讨论这三种大小到底是怎么算出来的,而不是死记硬背.知道了原理,以后不管遇到什么文件系统,都会有章可循,至少知道

使用path监听指定文件系统的变化

在以前的JAVA版本中,如果程序需要检测文件的变化,那么需要开辟一个线程每隔一段时间去遍历一次指定的目录,如果发现此次遍历结果和上次不同,那么就认为文件变动了 ,这样的方式非常繁琐,JAVA 7之后的NIO.2 Path类提供了一个方法来监听指定文件目录内文件的变化状态. 1.获取文件系统的WatchService对 2.使用Path类的方法去注册一个监听,指定监听文件的哪些状态,如新增.修改.删除. package com.nio2; import java.io.IOException;im

Busybox构建根文件系统和制作Ramdisk

定制根文件系统的方法很多,最常用的是使用BusyBox来构建定制根文件系统.它集成压缩了Linux的许多工具和命令,可以使用户迅速方便地建立一套相对完整.功能丰富的文件系统,其中包括大量常用的应用程序.下面详细介绍有关Busybox定制根文件系统. 一.系统环境: 1.操作系统:Ubuntu140.4 2.交叉编译工具:gcc version 6.1.1 20160711 (Linaro GCC 6.1-2016.08) 3.busybox源码包:busybox-1.26.2 二.构建rootf

RH124-14 文件系统和磁盘设备管理

第十四章 文件系统和磁盘设备管理 14.1 文件系统和磁盘设备的管理与使用 磁盘设备 磁盘设备是支持随机读写数据的设备. 在物理机器上,设备文件默认都存放在/dev/目录下,第一个硬盘是/dev/sda,第二个硬盘是/dev/sdb,如此类推.第一个硬盘的第一个分区是/dev/sda1,第二个分区是/dev/sda2,如此类推. 在xen或kvm的虚拟机上,硬盘的名字则是/dev/xvda或/dev/vda等,如此类推 有些存放数据的设备并不是直接硬件对应的设备文件,而是通过软件生成的块设备文件

第九章、文件与文件系统的压缩与打包

1. 压缩文件的用途与技术 2. Linux 系统常见的压缩命令 2.1 compress 2.2 gzip, zcat 2.3 bzip2, bzcat 3. 打包命令: tar 4. 完整备份工具:dump, restore 5. 光盘写入工具 5.1 mkisofs:创建映像档 5.2 cdrecord:光盘烧录工具 6. 其他常见的压缩与备份工具 6.1 dd 6.2 cpio 7. 重点回顾 1. 压缩文件的用途与技术 2. Linux 系统常见的压缩命令 压缩文件的扩展名大多是:『*

Windows挂载NFS文件系统

主机 操作系统 IP地址 软件包 NFS主机 Centos7.2 192.168.190.128 nfs-utils.rpcbind Windows Client Windows server 2008 192.168.190.129 网络文件系统 注:以下实验均关闭防火墙以及其它安全机制 NFS主机操作: # 使用yum安装nfs-utils和管理工具rpcbind [[email protected] ~]# yum -y install nfs-utilsrpcbind # 建立共享文件夹

ii 第七单元 访问网络共享文件系统

挂载网络文件系统 网络文件系统是由网络附加存储服务器通过网络向多个主机提供的一种文件系统 , 而不是由块设备 ( 例如硬盘驱动器 ) 提供的.客户端通过特殊的文件系统协议和格式访问远程存储 Linux 中有两种主要协议可用访问网络文件系统 : NFS 和CIFS . 访问网络共享的三个基本步骤– 1. 识别要访问的远程共享– 2. 确定挂载点 ( 应该将共享挂载到的位置 ), 并创建挂载点的空目录– 3. 通过相应的名利或配置更改挂载网络文件系统 1.cifsCIFS( Comon Intern

【第三章】BCMS中应用的文件系统

因为我的mac 上mysql 的问题,造成我选择file和mongodb来做数据的持久化操作. mongodb的话,写了一小部分,已经可是可以使用,但是存在问题,所以决定先写file来进行数据操作. 之前我和小伙伴思考和讨论过这个问题,用小文件和数据库储存文件哪个会更快,数据库保存数据的方式应该和文件系统的方式一致,至于效率有待验证. 既然要使用文件系统去做数据的存储,基础的文件读取修改等方法应该写的通用,我现在还在修改这部分,因为已经在应用中发现了问题,这里先贴出来. 这里是主文件file.r

Hadoop学习笔记(3) Hadoop文件系统二

1 查询文件系统 (1) 文件元数据:FileStatus,该类封装了文件系统中文件和目录的元数据,包括文件长度.块大小.备份.修改时间.所有者以及版权信息.FileSystem的getFileStatus()方法用于获取文件或目录的FileStatus对象. 例:展示文件状态信息 public class ShowFileStatusTest{ private MiniDFSCluster cluster; private FileSystem fs; @Before public void

第三课 文件系统(上)

unix_c_03.txt====================第三课 文件系统(上)====================一.系统调用------------应用程序 -----------+| |v |各种库 |(C/C++标准库.Shell命令和脚本. |X11图形程序及库) || |v |系统调用 <----------+(内核提供给外界访问的接口函数,调用这些函数将使进程进入内核态)|v内核(驱动程序.系统功能程序)1. Unix/Linux大部分系统功能是通过系统调用实现的.如o