数据可以通过文件(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()
来注册自定义的封装协议。
内置的封装协议有:
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");
打开文件后可以使用一些函数读取文件:
fgets()
fgets(resource $handle[, int $length]):string
该函数从文件指针中读取一行。
参数说明:
fopen()
或fsockopen()
成功打开的文件(并还未由fclose()
关闭)。【示例】
读取当前目录下的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标记。
fgetc()
fgetc(resource $handle):string
该函数从文件指针中获取一个字符。
参数说明:
fopen()
或fsockopen()
成功打开的文件(并还未由fclose()
关闭)。【示例】
$fp = fopen('test.txt', 'r');
if (!$fp) {
echo '打开test.txt文件失败!';
}
while(false !== ($char = fgetc($fp))) {
echo "$char
";
}
test.txt文件内容为:abcdefghijklmnopqrstuvwxyz
程序输出结果:
这里需要注意:如果读取的文件中是中文,则会输出乱码。
文件的属性包括文件的上次访问修改时间、文件大小、文件类型等信息。
fileatime()
获得文件上次访问的时间,失败时返回false,返回的是UNIX时间戳。
flieatime(string $filename):int
参数:
【示例】
$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
filemtime()
取得文件修改的时间,成功时返回文件上次被修改的时间,失败时则返回false。时间以UNIX时间戳的方式返回。
filemtime(string $filename):int
参数:
【示例】
$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
注意:不同文件系统对时间的判断方法可能不相同。
filectime()
该函数返回文件上次inode被修改的时间,失败时返回FALSE。时间以UNIX时间戳的方式返回。
filectime(string $filename):int
参数:
【示例】
$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文件的建立时间。
filesize()
获得文件的大小,成功时返回文件大小的字节数,失败时返回false生成一条E_WARNING级别的错误。
filesieze(string $filename):int
参数:
【示例】
$filename = "test.txt";
if (file_exists($filename)) {
echo "$filename 大小为:" . filesize($filename) . "bytes";
}
?>
程序输出结果:
test.txt 大小为:6bytes
filetype()
获得文件的类型,可能返回的值有fifo、char、dir、block、link、file和unknown。如果 stat 调用失败或者文件类型未知的话**filetype()
**还会产生一个 E_NOTICE
消息。
filetype(string $filename):string
参数:
【示例】
echo filetype("test.txt") . "
";
echo filetype("fgets.php") . "
";
echo filetype("/");
?>
程序输出结果:
file
file
dir
stat()
获取由 filename
指定的文件的统计信息。如果 filename
是符号连接,则统计信息是关于被连接文件本身的,而不是符号连接。如果出错,stat()
函数返回FALSE。
stat(string $filename):array
参数:
【示例】
echo ""
;
print_r(stat("test.txt"));
echo "
";
?>
以上数组中数字键的含义如下:
数字下标 | 关联键名 | 说明 |
---|---|---|
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() | 获取文件大部分属性 | 文件名 | 返回给定属性信息的数组 |
复制文件
在PHP中使用copy()函数赋值文件:
copy(string $source, string $dest [, resource $context]):bool
该函数将文件从source拷贝到dest。
参数:
stream_context_create()
创建的有效上下文资源。【示例】
$file = "test.txt";
$newfile = "test.txt.bak";
if (!copy($file, $newfile)) {
echo "复制文件$file...失败
";
} else {
echo "文件复制成功!";
}
?>
程序输出结果:
文件复制成功!
删除文件
在PHP中使用unlink删除文件:
unlink(string $filename[, resource $context]):bool
删除由filename
指定的文件。发生错误时会产生一个E_WARNING
级别的错误。
参数:
【示例】
$file = "test.txt.bak";
if (!unlink($file)) {
echo "删除文件$file 失败!";
} else {
echo "删除文件成功!";
}
?>
程序输出结果:
删除文件成功!
再次执行该代码将得到如下错误提示:
Warning: unlink(test.txt.bak): No such file or directory
删除文件test.txt.bak 失败!
移动/重命名文件
rename()
函数可以重命名或者移动一个文件或目录,成功返回TRUE,失败返回FALSE。
rename(string $oldname, string $newname[, resource $context]):bool
该函数尝试把oldname
重命名为newname
。
参数:
用于oldname中的封装协议必须和用于newname中的相匹配。
【示例】
if (rename("test.txt", "../newtest.txt")) {
echo "移动成功!";
} else {
echo "移动失败!";
}
程序输出结果:
移动成功!
以上代码将当前目录下的test.txt移动到了上层目录下,并更名为newtest.txt。
对文件的读取/写入少不了和文件指针打交道,PHP可以实现文件指针的定位及查询,从而实现所需信息的快速查询。指针的位置就是从文件头部开始的字节数,默认的文件指针通常存在与文件头或文件尾,可以通过PHP提供的fseek()
、feof()
和ftell()
等函数对指针位置进行操作。
rewind()
倒回文件指针的位置。成功时返回TRUE,失败时返回FALSE。
rewind(resource $handle):bool
将handle的文件位置指针设为文件流的开头。
参数:
fopen()
成功打开的文件。fseek()
在文件指针中定位,成功返回0,否则返回-1。**注意:**移动到EOF之后的位置不算错误。
fseek(resource $handle, int $offset[, int $whence=SEEK_SET]):int
在与handle关联的文件中设定文件指针位置。新位置从文件头开始以字节数度量,是以whence指定的位置加上offset。
参数:
fopen()
创建的resource
资源类型。ftell()
返回文件指针读/写的位置。如果出错,返回FALSE。
ftell(resource $handle):int
该函数返回由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 "文件不存在或为一个目录。";
}
程序输出结果:
查看文件时一定会涉及目录操作,在PHP中,利用相关函数可以实现对目录的操作。常见目录操作函数的使用方法和技巧如下。
可使用filetype
函数确定文件的类型,语法如下:
filetype(string $filename):string
该函数反问filename
的文件类型。可能的值有fifo、char、dir、block、link、file和unknown。如果出错则返回FALSE。如果stat
函数调用失败或者文件类型未知的话filetype()
还会产生一条E_NOTICE消息。
参数:
【示例】
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。
参数:
is_file()
is_file(string $filename):bool
该函数判断给定文件名是否为一个正常的文件。如果文件存在并且为正常的文件则返回TRUE,否则返回FALSE。
参数:
【示例】
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)
创建目录
在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/目录。
删除目录
在PHP中使用rmdir删除目录,语法如下:
rmdir(string $dirname[, resource $context]):bool
该函数尝试删除dirname
所指定的目录。该目录必须是空的,而且要有相应的权限。失败时会产生一个E_WARNING级别的错误。
参数:
【示例】
$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()
前面加上@符号来抑制错误信息的输出。
参数:
readdir()
使用readdir()
函数从目录句柄中读取条目,语法如下:
readdir([resource $dir_handle]):string
该函数返回目录中一个文件的文件名。文件名以在文件系统中的排序返回。
参数:
opendir()
函数打开。如果目录句柄没有指定,那么会假定为是opendir()
函数打开的最后一个句柄。closedir()
使用closedir()
函数关闭目录句柄,语法如下:
closedir([resource $dir_handle]):void
该函数关闭由dir_handle
指定的目录流。流必须之前被opendir()
所打开。
参数:
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);
}
}
程序输出结果:
PHP中还有一个函数综合了上述两个函数的功能,可以使用scandir()
函数列出指定路径中的文件和目录,语法如下:
scandir(string $directory[, int $sorting_order[, resource]]):array
该函数返回一个array,包含有directory
中的文件和目录。成功则返回包含有文件名的array,如果失败则返回FALSE。如果directory
不是个目录,则返回FALSE并生成一条E_WARNING级别的错误。
参数:
【示例】
// 定义目录路径为程序文件所在目录
$dir = "./";
// 不指定sorting_order,默认使用字母升序排列
$files1 = scandir($dir);
// 指定sorting_order为1,使用字母降序排列
$files2 = scandir($dir, 1);
echo ""
;
print_r($files1);
print_r($files2);
echo "
";
程序输出结果:
使用dirname()
返回路径中的目录部分,语法如下:
dirname(string $path):string
该函数给出一个包含有指向一个文件的全路径的字符串,返回去掉文件名后的目录名。该函数将返回path
的父目录,如果在path
中没有斜线,则返回一个点(’.’),表示当前目录。否则返回的是吧path
中结尾的/component
(最后一个斜线以及后面部分)去掉之后的字符串。
参数:
【示例】
echo dirname('file.php') . "
";
echo dirname('./depth1/depth2');
程序输出结果:
在PHP中可以使用以下两个函数查看磁盘空间:
(1)disk_free_space()
函数,语法如下:
disk_free_space(string $directory):float
本函数根据给出的包含有一个目录的字符串以及相应的文件系统或磁盘分区返回可用的字节数。
注意:当前目录可用字节数与目录所在分区的可用字节数是一样的。
参数:
如果指定了文件名而不是目录,这个函数的行为将并不统一,会因操作系统和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中都支持将一个磁盘分区加载为一个子目录,这时正确使用本函数就很有意义。
参数:
【示例】
// 在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对象
$d = dir(".");
echo "句柄:" . $d->handle . "
";
echo "路径:" . $d->path . "
";
while (false !== ($entry = $d->read())) {
echo $entry . "
";
}
$d->close();
程序输出结果:
使用chdir()
函数可以修改当前目录路径,如果成功返回TRUE,否则返回FALSE。函数语法如下:
chdir(string $directory):bool
该函数将PHP当前目录改为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;
}
}
?>