PHP7语言基础——目录与文件操作

文章目录

  • 文件操作
    • 打开文件
    • 读取文件
    • 获得文件属性
    • 复制/删除/移动/重命名文件
  • 文件指针
  • 目录操作
    • 判断文件类型
    • 创建和删除目录
    • 打开读取和关闭目录
    • 获得路径中目录部分
    • 目录磁盘空间
    • 获取当前工作目录
    • 获得目录实例
    • 修改当前目录
  • 文件上传
    • 上传文件配置

掌握文件和目录处理对web开发非常必要,因为我们经常需要对文件进行处理,比如:读取配置文件,修改并存储配置文件等。

文件操作

数据可以通过文件(file)来实现存储和读取,数据的存取过程也就是文件的处理过程。

打开文件

要对文件进行操作,首先必须打开文件。在PHP中使用fopen()函数打开文件,函数说明如下:

fopen(string $filename, string $mode[, bool $use_include_path=false[, resource $context]]):resource

该函数将$filename指定的名字资源绑定到一个流上。

参数说明:

  • filename:如果filename是“scheme://...”的格式,则被当成一个URL,PHP将搜索协议处理器(也被称为封装协议)来处理此模式。如果该协议尚未注册封装协议,PHP将发出一条消息来帮助检查脚本中潜在的问题并将filename当成一个普通的文件名继续执行下去。
    如果PHP认为filename指定的是一个本地文件,将尝试在该文件上打开一个流。该文件必须是PHP可以访问的,因此需要确认文件访问权限允许该访问。如果激活了安全模式或者open_basedir则会应用进一步的限制。
    如果PHP认为filename指定的是一个已注册的协议,而该协议被注册为一个网络URL,PHP将检查并确认allow_url_fopen已被激活。如果关闭了,PHP将发出一个警告,而fopen的调用则失败。
    PHP带有很多内置URL风格的封装协议,可以用于类似fopen()copy()file_exists()filesize()的文件系统函数。除了这些封装协议,还能通过stream_wrapper_register()来注册自定义的封装协议。
    内置的封装协议有:

    • file://——访问本地文件系统。
    • http://——方位HTTP(s)网址。
    • ftp://——访问FTP(s)URLs。
    • php://——访问各个输入/输出流(I/O streams)。
    • zlib://——压缩流。
    • data://——数据流(RFC2397).
    • glob://——查找匹配的文件路径模式
    • phar://——PHP归档。
    • ssh2://——Secure Shell 2.
    • rar://——RAR。
    • ogg://——音频流。
    • expect://——处理交互的流。
  • mode:指定了所要请求到该流的访问类型。可以是一下值:

    mode 说明
    r 只读方式打开,将文件指针指向文件头
    r+ 读写方式打开,将文件指针指向文件头
    w 写入方式打开,将文件指针指向文件头并将文件大小截为零。如果文件不存在就尝试创建之。
    w+ 读写方式打开,将文件指针指向文件头并将文件大小截为零。如果文件不存在就尝试创建之。
    a 写入方式打开,将文件指针指向文件末尾。如果文件不存在就尝试创建之。
    a+ 读写方式打开,将文件指针指向文件末尾。如果文件不存在就尝试创建之。
    x 创建并以写入方式打开,将文件指针指向文件头。如果文件已经存在,那么fopen()调用失败并返回false,并生成一条E_WARNING级别的错误信息。如果文件不存在就尝试创建之。这和给底层的open(2)系统调用指定O_EXCL|O_CREAT标记是等价的。
    x+ 创建并以读写方式打开,其他行为和‘x’一样。
    c 以只写方式打开文件,如果文件不存在就创建之。如果文件存在不会清空文件内容,将文件指针指向文件头。
    c+ 以读写方式打开文件,如果文件不存在就创建之。如果文件存在不会清空文件内容,将文件指针指向文件头。

    这里需要注意的是不同的操作系统对行结束符的定义不一样。UNIX使用\n作为行结束字符,Windows使用\r\n作为行结束字符,Mac使用\r作为行结束字符。Windows下提供了一个文本转换标记(‘t’)可以透明地将\n转换为\r\n。还可以使用’b’来强制使用二进制模式,这样就不会转换数据。要使用这些标记,要么用’b’或者’t’作为mode参数的最后一个字符。

    为移植性考虑,建议在用fopen()打开文件时总是使用’b’标记。

  • use_include_path:如果也需要在include_path中搜寻文件的话,可以将可选的第三个参数设为1或TRUE。

  • context:在PHP5.0.0中新增了对上下文(Context)的支持。

【示例】


// 只读方式打开上级目录中的1.php,这里使用相对路径
$handle = fopen("../1.php", "r");
// 读写方式打开d盘根目录下的1.txt文件,(windows)
$handle = fopen("d:\\1.txt", "r+");
// 写入方式代开home目录下rasums目录中的file.txt文件(Unix)
$handle = fopen("/home/rasmus/file.txt", "w");
// 二进制模式打开当前目录下的2.php
$handle = fopen("2.php", "wb");
// 在开启了allow_url_fopen选项后,打开远程文件
$handle = fopen("http://www.example.com/", "r");
// 以二进制写入方式打开远程文件
$handle = fopen("ftp://user:[email protected]/somefile.txt", "wb");

读取文件

打开文件后可以使用一些函数读取文件:

  1. fgets()

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

    该函数从文件指针中读取一行。
    参数说明:

    • handle:文件指针必须是有效的,必须指向由fopen()fsockopen()成功打开的文件(并还未由fclose()关闭)。
    • length:可选参数,从handle指向的文件中读取一行并返回长度最多为length-1字节的字符串。碰到换行符(包括在返回值中)、EOF或者已经读取了length-1字节后停止。如果没有指定length,则默认为1k。

    【示例】

    读取当前目录下的text.txt文件:

    
    // 首先需要成功打开一个文件
    $handle = fopen('test.txt', 'r');
    if ($handle) {
        while(($buffer = fgets($handle, 4096)) !== false) {
            echo $buffer . "
    "
    ; } if (!feof($handle)) { echo "Error:unexpected fgets() fail
    "
    ; } // 不要忘记关闭文件,打开了就一定要关闭 fclose($handle); }

    test.txt文件内容如下:

    在这里插入图片描述

    与之对应的还有一个fgetss()函数,该函数的作用与fgts()相同,只是该函数会尝试从读取的文本中过滤掉任何HTML和PHP标记。

  2. fgetc()

    fgetc(resource $handle):string
    

    该函数从文件指针中获取一个字符。
    参数说明:

    • handle:文件指针必须是有效的,必须指向由fopen()fsockopen()成功打开的文件(并还未由fclose()关闭)。

    【示例】

    
    $fp = fopen('test.txt', 'r');
    if (!$fp) {
        echo '打开test.txt文件失败!';
    }
    while(false !== ($char = fgetc($fp))) {
        echo "$char 
    "
    ; }

    test.txt文件内容为:abcdefghijklmnopqrstuvwxyz
    程序输出结果:
    在这里插入图片描述

    这里需要注意:如果读取的文件中是中文,则会输出乱码。

获得文件属性

文件的属性包括文件的上次访问修改时间、文件大小、文件类型等信息。

  1. fileatime()
    获得文件上次访问的时间,失败时返回false,返回的是UNIX时间戳。

    flieatime(string $filename):int
    

    参数:

    • filename:文件的路径。

    【示例】

    
    $filename = "test.txt";
    if (file_exists($filename)) {
        echo "$filename 最后访问时间为:" . date("y m d H:i:s", fileatime($filename));
    }
    ?>
    

    程序输出结果:

    test.txt 最后访问时间为:20 03 09 02:24:42

  2. filemtime()
    取得文件修改的时间,成功时返回文件上次被修改的时间,失败时则返回false。时间以UNIX时间戳的方式返回。

    filemtime(string $filename):int
    

    参数:

    • filename:文件的路径。

    【示例】

    
    $filename = "test.txt";
    if (file_exists($filename)) {
        echo "$filename 最后修改时间为:" . date("y m d H:i:s", filemtime($filename));
    }
    ?>
    

    程序输出结果:

    test.txt 最后修改时间为:20 03 09 02:24:42

    注意:不同文件系统对时间的判断方法可能不相同。

  3. filectime()
    该函数返回文件上次inode被修改的时间,失败时返回FALSE。时间以UNIX时间戳的方式返回。

    filectime(string $filename):int
    

    参数:

    • filename:文件的路径。

    【示例】

    
    $filename = "test.txt";
    if (file_exists($filename)) {
        echo "$filename 最后修改时间为:" . date("y m d H:i:s", filectime($filename));
    }
    ?>
    

    程序输出结果:

    test.txt 最后修改时间为:20 03 09 02:06:49

    注意:在大多数UNIX文件系统中,当一个文件的inode数据被改变时则该文件被认为是修改了。也就是说,当文件的权限,所有者,所有组或其他inode中的元数据被更新时。某些unix说明文本中把ctime说成是文件建立的时间,这是错误的。在大多数UNIX文件系统中没有UNIX文件的建立时间。

  4. filesize()
    获得文件的大小,成功时返回文件大小的字节数,失败时返回false生成一条E_WARNING级别的错误。

    filesieze(string $filename):int
    

    参数:

    • filename:文件的路径。

    【示例】

    
    $filename = "test.txt";
    if (file_exists($filename)) {
        echo "$filename 大小为:" . filesize($filename) . "bytes";
    }
    ?>
    

    程序输出结果:

    test.txt 大小为:6bytes

  5. filetype()
    获得文件的类型,可能返回的值有fifo、char、dir、block、link、file和unknown。如果 stat 调用失败或者文件类型未知的话**filetype()**还会产生一个 E_NOTICE 消息。

    filetype(string $filename):string
    

    参数:

    • filename:文件的路径。

    【示例】

    
    echo filetype("test.txt") . "
    "
    ; echo filetype("fgets.php") . "
    "
    ; echo filetype("/"); ?>

    程序输出结果:

    file
    file
    dir

  6. stat()
    获取由 filename 指定的文件的统计信息。如果 filename 是符号连接,则统计信息是关于被连接文件本身的,而不是符号连接。如果出错,stat()函数返回FALSE。

    stat(string $filename):array
    

    参数:

    • filename:文件的路径。

    【示例】

    
    echo "
    ";
    print_r(stat("test.txt"));
    echo "
    "
    ; ?>

    PHP7语言基础——目录与文件操作_第1张图片

以上数组中数字键的含义如下:

数字下标 关联键名 说明
0 dev device number-设备名
1 ino inode number-inode号码
2 mode inode protection mode-inode保护模式
3 nlink number of links-被连接数目
4 uid userid of owner-所有者的用户id
5 gid groupid of owner-所有者的组id
6 rdev device type,if inode device*-设备类型,如果是inode设备的话
7 size size in bytes-文件大小的字节数
8 atime time of last access(unix timestamp)-上次访问时间(Unix时间戳)
9 mtime time of last modification(unix timestamp)-上次修改时间(Unix时间戳)
10 ctime time of last change(unix timestamp)-上次改变时间(Unix时间戳)
11 blksize blocksize of filesystem IO *-文件系统IO的块大小
12 blocks number of blocks allocated-所占据块的数目

在这里有必要提一下UNIX系统中7中文件类型:

文件类型 描述
block 块设备文件,如某个磁盘分区,光驱等。
char 字符设备是指在I/O传输过程中以字符为单位进行传输的设备,如键盘、打印机等。
dir 目录类型,目录也是文件的一种
fifo 命名管道,常用于将信息从给一个进程传递到另一个进程
file 普通文件类型,如文本文件或可执行文件等
link 符号连接,是指向文件指针的指针。类似于windows中的快捷方式。
unknown 未知类型。也就是除以上6种类型以外的类型。

其中rdev在Windows下总是0。st_blksize仅在支持st_blksize类型的系统下有小。其他系统(如Windows)返回-1。

因为PHP的整数类型是有符号整形而且很多平台使用32位整型,对2GB以上的文件,一些文件系统函数可能返回无法预期的结果。

还有两个和stat()类似的函数,一个是lstat():给出一个文件或符号连接的信息,他与stat()的区别在于lstat()会返回符号连接的状态。另一个是fstat():通过已打开的文件指针取得文件信息。它与stat()的区别是它作用于已经打开的文件指针而不是文件名。

与文件属性相关的函数列表

函数名 作用 参数 返回值
file_exists() 检查文件或目录是否存在 文件名 存在返回TRUE,不存在返回FALSE
filesize() 取得文件大小 文件名 返回文件大小的字节数,出错返回FALSE
is_readable() 判断文件是否可读 文件名 文件可读返回TRUE
is_writable() 判断文件是否可写 文件名 文件可写返回TRUE
is_executeable() 判断文件是否可执行 文件名 文件可执行返回TRUE
filectime() 获取文件文件上次inode被修改的时间 文件名 返回UNIX时间戳
filemtime() 获取文件的修改时间 文件名 返回UNIX时间戳
fileatime() 获取文件的访问时间 文件名 返回UNIX时间戳
stat() 获取文件大部分属性 文件名 返回给定属性信息的数组

复制/删除/移动/重命名文件

  1. 复制文件
    在PHP中使用copy()函数赋值文件:

    copy(string $source, string $dest [, resource $context]):bool
    

    该函数将文件从source拷贝到dest。

    参数:

    • source:源文件路径。
    • dest:目标路径。如果dest是一个URL,则如果封装协议不支持覆盖已有的文件时拷贝操作会失败。其他情况下,如果目标文件已存在,将会被覆盖。
    • $content:使用stream_context_create()创建的有效上下文资源。

    【示例】

    
    $file = "test.txt";
    $newfile = "test.txt.bak";
    if (!copy($file, $newfile)) {
        echo "复制文件$file...失败
    "
    ; } else { echo "文件复制成功!"; } ?>

    程序输出结果:

    文件复制成功!

  2. 删除文件
    在PHP中使用unlink删除文件:

    unlink(string $filename[, resource $context]):bool
    

    删除由filename指定的文件。发生错误时会产生一个E_WARNING级别的错误。

    参数:

    • filename:文件的路径。
    • context:在PHP5.0.0中新增了对上下文(Context)的支持。

    【示例】

    
    $file = "test.txt.bak";
    if (!unlink($file)) {
        echo "删除文件$file 失败!";
    } else {
        echo "删除文件成功!";
    }
    ?>
    

    程序输出结果:

    删除文件成功!

    再次执行该代码将得到如下错误提示:

    Warning: unlink(test.txt.bak): No such file or directory
    删除文件test.txt.bak 失败!

  3. 移动/重命名文件
    rename()函数可以重命名或者移动一个文件或目录,成功返回TRUE,失败返回FALSE。

    rename(string $oldname, string $newname[, resource $context]):bool
    

    该函数尝试把oldname重命名为newname

    参数:

    • oldname:原文件或目录名。
    • newname:新的名字。
    • context:在PHP5.0.0中增加了上下文的支持。

    用于oldname中的封装协议必须和用于newname中的相匹配。

    【示例】

    
    if (rename("test.txt", "../newtest.txt")) {
        echo "移动成功!";
    } else {
        echo "移动失败!";
    }
    

    程序输出结果:

    移动成功!

    以上代码将当前目录下的test.txt移动到了上层目录下,并更名为newtest.txt。

文件指针

对文件的读取/写入少不了和文件指针打交道,PHP可以实现文件指针的定位及查询,从而实现所需信息的快速查询。指针的位置就是从文件头部开始的字节数,默认的文件指针通常存在与文件头或文件尾,可以通过PHP提供的fseek()feof()ftell()等函数对指针位置进行操作。

  1. rewind()
    倒回文件指针的位置。成功时返回TRUE,失败时返回FALSE。

    rewind(resource $handle):bool
    

    将handle的文件位置指针设为文件流的开头。

    参数:

    • handle:文件指针必须合法,并指向由fopen()成功打开的文件。
  2. fseek()
    在文件指针中定位,成功返回0,否则返回-1。**注意:**移动到EOF之后的位置不算错误。

    fseek(resource $handle, int $offset[, int $whence=SEEK_SET]):int
    

    在与handle关联的文件中设定文件指针位置。新位置从文件头开始以字节数度量,是以whence指定的位置加上offset。

    参数:

    • handle:文件系统指针,是典型地由fopen()创建的resource资源类型。
    • offset:偏移量。要移动到文件尾之前的位置(反向移动),需要给offset传递一个负值,并设置whence为SEEK_END。
    • whence:该值包含以下常量:
      • SEEK_SET—设定位置等于offset字节。
      • SEEK_CUR—设定位置为当前位置加上offset。
      • SEEK_END—设定位置为文件尾加上offset。
  3. ftell()
    返回文件指针读/写的位置。如果出错,返回FALSE。

    ftell(resource $handle):int
    

    该函数返回由handle指定的文件指针的位置,也就是文件流中的偏移量。

    参数:

    • handle:文件指针必须是有效的,切必须指向一个通过fopen()popen()成功打开的文件。在附件模式(加参数"a"打开文件)中ftell()会返回未定义错误。

【文件指针操作示例】

在当前目录中创建文件1.txt,内容为:the quick brown fox jumps over the lazy dog


// 定义文件路径及文件名
$filename = "1.txt";
// 判断是否为一个文件
if (is_file($filename)) {
    echo "文件总字节数:" . filesize($filename) . "
"
; // 以rb方式打开文件 $handle = fopen($filename, "rb"); echo "初始指针位置是:" . ftell($handle) . "
"
; // 将指针向后移动5个字节 fseek($handle, 5); echo "使用fseek()函数后指针位置:" . ftell($handle) . "
"
; // 当前指针后面的内容从5字节开始,fgets()函数输出5字节以后的内容 echo "输出当前指针后面的内容:" . fgets($handle) . "
"
; // 判断是否到文件尾 if (feof($handle)) { // 当前指针指向文件末尾时,指针的位置等于文件的总字节数 echo "当前指针指向文件末尾:" . ftell($handle) . "
"
; } // 重置文件指针的位置 rewind($handle); // fgets()函数执行成功时从参数handle所指向的文件中读取一行 // 并返回长度最多为lenght-1字节的字符串,因此设置为6时可以输出前5个字节的内容 echo "输出前5个字节的内容:" . fgets($handle, 6); // 关闭文件资源 fclose($handle); } else { echo "文件不存在或为一个目录。"; }

程序输出结果:

PHP7语言基础——目录与文件操作_第2张图片

目录操作

查看文件时一定会涉及目录操作,在PHP中,利用相关函数可以实现对目录的操作。常见目录操作函数的使用方法和技巧如下。

判断文件类型

可使用filetype函数确定文件的类型,语法如下:

filetype(string $filename):string

该函数反问filename的文件类型。可能的值有fifo、char、dir、block、link、file和unknown。如果出错则返回FALSE。如果stat函数调用失败或者文件类型未知的话filetype()还会产生一条E_NOTICE消息。

参数:

  • filename:文件的路径。

【示例】


echo filetype('1.jpg') . "
"
; echo filetype('1.txt') . "
"
; echo filetype('test'); ?>

程序输出结果:

file
file
dir

filetype()函数外,还可以使用is_dir()函数判断文件是否是一个目录,如果是就返回TRUE,否则返回FALSE,使用is_file()函数判断传入的文件名是否是一个正常的文件。

is_dir()

is_dir(string $filename):bool

该函数判断给定文件名filename是否是一个目录,如果文件名存在,并且是个目录,返回TRUE,否则返回FALSE。

参数:

  • filename:文件的路径,如果filename是一个相对路径,则按照当前工作目录检查其相对路径。

is_file()

is_file(string $filename):bool

该函数判断给定文件名是否为一个正常的文件。如果文件存在并且为正常的文件则返回TRUE,否则返回FALSE。

参数:

  • filename:文件的路径。

【示例】


echo "
";
var_dump(is_dir('test'));
var_dump(is_file('1.jpg'));
var_dump(is_dir('1.php'));
echo "
"
; ?>

程序输出结果:

bool(true)
bool(true)
bool(false)

创建和删除目录

  1. 创建目录
    在PHP中使用mkdir创建目录,语法如下:

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

    该函数尝试新建一个由pathname指定的目录。

    参数:

    • pathname:目录的路径

    • mode:默认的是0777,意味着最大可能的访问权。

      mode在Windows下被忽略。

    • recursive:允许递归创建由pathname所指定的多级嵌套目录。

    • context:在PHP5.0.0中增加了对上下文的支持。

    【示例】

    
    $structure = "./depth1/depth2/depth3/";
    if(!mkdir($structure, 0777, true)){
        die("目录创建失败!");
    } else {
        echo "目录创建成功!";
    }
    

    运行以上代码后,会在当前目录下递归地创建/depth1/depth2/depth3/目录。

  2. 删除目录
    在PHP中使用rmdir删除目录,语法如下:

    rmdir(string $dirname[, resource $context]):bool
    

    该函数尝试删除dirname所指定的目录。该目录必须是空的,而且要有相应的权限。失败时会产生一个E_WARNING级别的错误。

    参数:

    • dirname:目录的路径。
    • context:在PHP5.0.0中增加了对上下文(Context)的支持。

    【示例】

    
    $structure = "./depth1/depth2/depth3/";
    if(!rmdir($structure)){
        die("删除目录失败!");
    } else {
        echo "删除目录成功!";
    }
    

    执行以上代码只会删除depth3目录,并不会递归删除。

打开读取和关闭目录

在PHP中使用opendir()函数打开目录,语法如下:

opendir(string $path[, resource $content]):resource

该函数打开一个目录句柄,可用于之后的closedir()readdir()rewinddir()调用中。如果成功则返回目录句柄的resource,失败则返回FALSE。如果 path 不是一个合法的目录或者因为权限限制或文件系统错误而不能打开目录,opendir() 返回 FALSE 并产生一个 E_WARNING级别的错误信息。可以在 opendir() 前面加上@符号来抑制错误信息的输出。

参数:

  • path:要打开的目录路径。
  • context:上下文。

readdir()

使用readdir()函数从目录句柄中读取条目,语法如下:

readdir([resource $dir_handle]):string

该函数返回目录中一个文件的文件名。文件名以在文件系统中的排序返回。

参数:

  • dir_handle:目录句柄的resource,之前由opendir()函数打开。如果目录句柄没有指定,那么会假定为是opendir()函数打开的最后一个句柄。

closedir()

使用closedir()函数关闭目录句柄,语法如下:

closedir([resource $dir_handle]):void

该函数关闭由dir_handle指定的目录流。流必须之前被opendir()所打开。

参数:

  • dir_handle:目录句柄的resource,之前由opendir()函数打开。如果目录句柄没有指定,那么会假定为是opendir()函数打开的最后一个句柄。

【示例】


// 定义目录路径为程序文件所在目录
$dir = "./";
// 判断$dir定义的路径是否是一个目录
if (is_dir($dir)) {
    // 如果是一个目录则打开目录句柄
    if ($dh = opendir($dir)) {
        // 循环遍历目录句柄中的所有文件和目录
        while (($file = readdir($dh)) !== false){
            echo "目录名:$file 、文件类型:" . filetype($dir.$file) . "
"
; } // 关闭目录句柄,这里可以不传入参数,因为最后一次打开的就是$dh。 closedir($dh); } }

程序输出结果:

PHP7语言基础——目录与文件操作_第3张图片

PHP中还有一个函数综合了上述两个函数的功能,可以使用scandir()函数列出指定路径中的文件和目录,语法如下:

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

该函数返回一个array,包含有directory中的文件和目录。成功则返回包含有文件名的array,如果失败则返回FALSE。如果directory不是个目录,则返回FALSE并生成一条E_WARNING级别的错误。

参数:

  • directory:要被浏览的目录。
  • sorting_order:默认的排序顺序是按字母升序排列。如果使用了可选参数sorting_order(设为1),则排序顺序是按字母降序排列。
  • context:上下文。

【示例】


// 定义目录路径为程序文件所在目录
$dir = "./";
// 不指定sorting_order,默认使用字母升序排列
$files1 = scandir($dir);
// 指定sorting_order为1,使用字母降序排列
$files2 = scandir($dir, 1);
echo "
";
print_r($files1);
print_r($files2);
echo "
"
;

程序输出结果:

PHP7语言基础——目录与文件操作_第4张图片

获得路径中目录部分

使用dirname()返回路径中的目录部分,语法如下:

dirname(string $path):string

该函数给出一个包含有指向一个文件的全路径的字符串,返回去掉文件名后的目录名。该函数将返回path的父目录,如果在path中没有斜线,则返回一个点(’.’),表示当前目录。否则返回的是吧path中结尾的/component(最后一个斜线以及后面部分)去掉之后的字符串。

参数:

  • path:一个路径。在windows中,斜线(/)和反斜线(\)都可以用作目录分隔符。在其他环境下是斜线(/)。

【示例】


echo dirname('file.php') . "
"
; echo dirname('./depth1/depth2');

程序输出结果:

在这里插入图片描述

目录磁盘空间

在PHP中可以使用以下两个函数查看磁盘空间:

(1)disk_free_space()函数,语法如下:

disk_free_space(string $directory):float

本函数根据给出的包含有一个目录的字符串以及相应的文件系统或磁盘分区返回可用的字节数。

注意:当前目录可用字节数与目录所在分区的可用字节数是一样的。

参数:

  • directory:文件系统目录或者磁盘分区。

如果指定了文件名而不是目录,这个函数的行为将并不统一,会因操作系统和PHP版本而异。

【示例】


// 在UNIX下,返回根目录下可用的字节数
// $df = disk_free_space("/");

// 在Windows下:
$df_c = disk_free_space("c:");
$df_d = disk_free_space("d:");
$df = disk_free_space("./");
echo "C盘空间为:$df_c KB,D盘空间为:$df_d KB,当前目录空间为:$df KB。";

此函数不能作用于远程文件,被检查的文件必须是可通过服务器的文件系统访问的。

(2)disk_total_space()函数,语法如下:

disk_total_space(string $directory):float

给出一个包含有一个目录的字符串,本函数将根据相应的文件系统或磁盘分区返回所有的字节数。【注】本函数返回的是该目录所在的磁盘分区的总大小,因此在给出同一个磁盘分区的不同目录作为参数所得到的结果完全相同。在 Unix 和 Windows中都支持将一个磁盘分区加载为一个子目录,这时正确使用本函数就很有意义。

参数:

  • directory:文件系统的目录或磁盘分区。

【示例】


// 在UNIX下,返回根目录下可用的字节数
// $df = disk_total_space("/");

// 在Windows下:
$df_c = disk_total_space("c:");
$df_d = disk_total_space("d:");
$df = disk_total_space(".");
echo "C盘总容量为:$df_c KB,D盘总容量为:$df_d KB,当前目录总容量为:$df KB。";

此函数不能作用于远程文件,被检查的文件必须是可通过服务器的文件系统访问的。

通过实例可以看出两个函数的区别在于disk_free_space()返回剩余空间,disk_total_space()返回总大小。

获取当前工作目录

使用getcwd()函数可以获取当前工作目录,语法如下:

getcwd(void):string

该函数执行成功返回当前工作目录,失败返回FALSE。要特别注意在UNIX下,有一些UNIX的变种,如果任何父目录没有设定可读或搜索模式,及时当前目录设定了,getcwd()也会返回FALSE。

【示例】


// 获取当前路径
$d1 = getcwd();
// 输出当前路径
echo $d1;

获得目录实例

通过dir()函数可以创建一个Directory类的实例,而不用通过new操作符。

Directory类摘要如下:

Directory {
    /* 属性 */
    public string $path;
    public resource $handle;
    
    /* 方法 */
    public close([resource $dir_handle]):void
 	public read([resource $dir_handle]):string
    public rewind([resource $dir_handle]):void
}

其中:path属性是被打开目录的路径。handle是目录句柄。可以被其他的目录操作函数使用。

dir()函数的语法如下:

dir(string $directory[, resource $context]):Directory

该函数以面向对象的方式访问目录。打开directory参数指定的目录。

参数:

  • directory:被打开的目录。
  • context:上下文。

【示例】


// 获得当前目录的Directory对象
$d = dir(".");
echo "句柄:" . $d->handle . "
"
; echo "路径:" . $d->path . "
"
; while (false !== ($entry = $d->read())) { echo $entry . "
"
; } $d->close();

程序输出结果:

PHP7语言基础——目录与文件操作_第5张图片

修改当前目录

使用chdir()函数可以修改当前目录路径,如果成功返回TRUE,否则返回FALSE。函数语法如下:

chdir(string $directory):bool

该函数将PHP当前目录改为directory

参数:

  • directory:新的当前目录。

【示例】


// 输出当前目录
echo "当前目录为:" . getcwd() . "
"
; // 修改当前目录 chdir('test'); // 再次输出当前目录 echo "修改后的当前目录为:" . getcwd() . "
"
;

文件上传

文件上传是PHP应用中使用非常频繁的功能,用户把一个文件上传到服务器,需要在客户端和服务器建立一个通道传递文件的字节流,并在服务器中进行上传操作。

上传文件配置

想实现文件上传功能,需要配置php.ini中的几个参数:

配置参数 示例 说明
file_uploads file_uploads=on 是否允许HTTP文件上传,默认为on,允许HTTP文件上传,此选项不能设置为off
upload_max_filesize upload_max_filesize=50M 上传文件的最大尺寸。这个选项默认值为2M,即文件上传的大小为2MB,如果想上传一个TOMB的文件,就必须设置upload_max_filesize=50M
post_max_size post_max_size=8M 通过表单POST给PHP时所能接受的最大值,包括表单里的所有值,默认为8MB。如果POST数据超出限制,那么$_POST$_FILES将会为空。另外如果启用了内存限制,那么该值应当小于memory_limit选项的值。
upload_tmp_dir upload_tmp_dir=’/usr/local/picture’ 文件上传的临时存放目录。如果没有自定则PHP会使用系统默认的临时目录。该选项默认为空,在手动配置PHP运行环境时容易遗忘,如果不配置这个选项,文件上传功能将无法实现。
max_execution_time max_execution_time=600 每个PHP页面运行的最大时间值(单位为秒),默认为30秒。如果超过30秒,该脚本就停止执行,如果设置为0,就表示无时间限制。
max_input_time max_input_time=600 每个PHP脚本解析请求数据所用的时间(单位为秒),默认为60秒。如果设置为0,就表示没有时间限制。
memory_limit memory_limit=128M 这个选项用来设置单个PHP脚本所能申请到的最大内存空间。如果不需要任何内存上的限制就将其设置为-1。

注意:需要保持memory_limit > post_max_size > upload_max_filesize

【示例】

首先创建一个实现文件上传功能的页面,为了实现上传文件的存储,我们需要在脚本目录下新建一个名为upload的文件夹。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>文件上传</title>
</head>
<body>
<h3 align="center">上传文件</h3>
<form method="post" action="fileupload.php" enctype="multipart/form-data">
    <table border="0" cellspacing="0" align="center" width="800">
        <tr>
            <td height="16">
                <input name="file_name" type="file" value="浏览" />
                <input type="submit" value="上传" name="add" />
            </td>
        </tr>
    </table>
</form>
</body>
</html>

然后建立处理上传的php文件


if ($_POST['add'] == "上传") {
    // 根据当前时间产生一个随机数作为文件名
    $rand1 = rand(0, 9);
    $rand2 = rand(0, 9);
    $rand3 = rand(0, 9);
    $filename = date("Ymdhms") . $rand1 . $rand2 . $rand3;
    // 判断文件内容是否为空
    if (empty($_FILES['file_name']['name'])) {
        // $_FILES['file_name']['name']为获取客户端机器文件的原名称
        echo "文件名不能为空!";
        exit;
    }
    $oldfilename = $_FILES['file_name']['name'];
    echo "
原文件名为:"
. $oldfilename; // 获取源文件类型 $filetype = substr($oldfilename, strrpos($oldfilename, "."), strlen($oldfilename) - strrpos($oldfilename, ".")); echo "
原文件类型为:"
. $filetype; // 设置文件上传白名单 if (($filetype != '.doc') && ($filetype != '.xls') && ($filetype != '.DOC') && ($filetype != '.XLS')) { echo ""; echo ""; exit; } echo "
上传文件的大小为(字节):"
. $_FILES['file_name']['size']; if ($_FILES['file_name']['size'] > 100000) { echo ""; echo ""; exit; } echo "
文件上传服务器后的临时文件名为:"
. $_FILES['file_name']['tmp_name']; // 取得保存文件的临时文件名(含路径) $filename = $filename . $filetype; $savedir = "upload/" . $filename; if (move_uploaded_file($_FILES['file_name']['tmp_name'], $savedir)) { // 取得保存文件的文件名(不含路径) $file_name = basename($savedir); echo "
文件上传成功!保存为:"
. $savedir; } else { echo ""; echo ""; exit; } } ?>

你可能感兴趣的:(PHP学习笔记)