PHP 文件上传

1 通过PHP上传文件
1.1 PHP的文件上传/资源指令
file_uploads On|Off
file_uploads指令确定服务器上的PHP脚本是否可以接收文件上传。默认为On.

upload_tmp_dir = string
上传的文件在处理之前必须成功地传输到服务器,所以必须指定一个位置来临时放置这些文件,直到文件移到最终目的地为止。默认没有设置,PHP使用系统默认的临时目录。

upload_max_filesize = integerM
upload_max_filesize指令确定上传文件的最大大小,以MB为单位。此指令必须小于post_max_size。

max_file_uploads = interger
从PHP5.2.12开始提供,max_file_uploads指令对可以同时上传的文件数设置了一个上限。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
;;;;;;;;;;;;;;;;
; File Uploads ;
;;;;;;;;;;;;;;;;

; Whether to allow HTTP file uploads.
; http://php.net/file-uploads
file_uploads = On

; Temporary directory for HTTP uploaded files (will use system default if not
; specified).
; http://php.net/upload-tmp-dir
;upload_tmp_dir =

; Maximum allowed size for uploaded files.
; http://php.net/upload-max-filesize
upload_max_filesize = 8M

; Maximum number of files that can be uploaded via a single request
max_file_uploads = 20

 
另外,更文件上传还有关系的指令是资源限制类指令
max_input_time = interger
max_input_time指令确定解析输入所花费的最长时间,以秒为单位。大文件需要一段较长时间才能上传,这可能会超过这个指令设置的时间。

memory_limit = integerM
memory_limit指令设置脚本可以分配的最大内存量。可以防止失控脚本独占服务器资源。

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
;;;;;;;;;;;;;;;;;;;
; Resource Limits ;
;;;;;;;;;;;;;;;;;;;

; Maximum execution time of each script, in seconds
; http://php.net/max-execution-time
; Note: This directive is hardcoded to 0 for the CLI SAPI
max_execution_time = 600

; Maximum amount of time each script may spend parsing request data. It's a good
; idea to limit this time on productions servers in order to eliminate unexpectedly
; long running scripts.
; Note: This directive is hardcoded to -1 for the CLI SAPI
; Default Value: -1 (Unlimited)
; Development Value: 60 (60 seconds)
; Production Value: 60 (60 seconds)
; http://php.net/max-input-time
max_input_time = 600

; Maximum input variable nesting level
; http://php.net/max-input-nesting-level
;max_input_nesting_level = 64

; How many GET/POST/COOKIE input variables may be accepted
; max_input_vars = 1000

; Maximum amount of memory a script may consume (128MB)
; http://php.net/memory-limit
memory_limit = 256M

 
跟文件上传相关的还涉及到数据处理类的指令
post_max_size = intergerM
post_max_size对通过POST方法提交的数据大小设置了一个上限。由于文件使用POST上传,在处理大文件时,可能需要上调upload_max_filesize和这个值。

1.2 $_FILES数组
$_FILES变量存储与通过一个PHP脚本上传到服务器的文件有关的各种信息。这个数组共有5项。
1) $_FILES[‘userfile’][‘error’]
是一个数组,提供了与上传尝试结果有关的信息。
2) $_FILES[‘userfile’][‘name’]
客户端机器上声明的文件最初的名字,包含扩展名。
3) $_FILES[‘userfile’][‘size’]
从客户端上传的文件的大小,以字节为单位。
4) $_FILES[‘userfile’][‘tmp_name’]
上传到服务器后为文件赋予的临时名。
5) $_FILES[‘userfile’][‘type’]
从客户端上传的文件的MIME类型。

1.3 PHP的文件上传函数
PHP提供了两个专门用于文件上传过程的函数:is_uploaded_file()和move_uploaded_file()。
1) 确定是否已上传文件
boolean is_uploaded_file(string filename) 函数确定由输入参数filename指定的文件是否已使用POST方法上传。一般是如下使用:

1
2
3
if(is_uploaded_file($_FILES[‘userfile’][‘tmp_name’])){
//
}

 
它可以确保$_FILES[‘userfile’][‘tmp_name’]的确是通过POST上传的。

2) 移动已上传文件
boolean move_uploaded_file()函数是将已上传文件从临时目录转移到最终目标的一个便利方法。move_uploaded_file()函数将检查以确保由filename输入参数指定的文件确实是通过POST上传的,所以之前不需要使用is_uploaded_file()函数。

1.4 上传错误消息
上传错误消息由$_FILES[‘userfile’][‘error’]数组提供。

UPLOAD_ERR_OK 成功上传返回0
UPLOAD_ERR_INI_SIZE 如果上传文件超过upload_max_filesize指令值,返回1
UPLOAD_ERR_FORM_SIZE 如果超过在上传表单中设置的max_file_zize值,返回2
UPLOAD_ERR_PARTIAL 文件没有完全上传,返回3
UPLOAD_ERR_NO_FILE 如果用户没有指定上传的文件就提交表单,返回4
UPLOAD_ERR_NO_TMP_DIR 如果临时目录不存在,返回6
UPLOAD_ERR_CANT_WRITE 如果文件无法写磁盘,返回7
UPLOAD_ERR_EXTENSION 如果PHP的一个配置文件导致上传失败,返回8
1.5 文件上传例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<form action="" method="post" enctype="multipart/form-data">

Pictures:
<input type="file" name="pictures[]" />
<input type="file" name="pictures[]" />
<input type="file" name="pictures[]" />
<input type="submit" value="Send" />

</form>

//$key对应下标
foreach ($_FILES["pictures"]["error"] as $key => $error) {
if ($error == UPLOAD_ERR_OK) {
$tmp_name = $_FILES["pictures"]["tmp_name"][$key];
$name = $_FILES["pictures"]["name"][$key];
move_uploaded_file($tmp_name, "data/$name");
}
}

 
注意,文件上传的表达要求必须添加enctype=”multipart/form-data”这个属性,另外,如果是多文件上传,全部的文件表单域都必须是同名并且必须以‘[]’结尾(如果上传的个数是未知的,可以通过JavaScript动态添加文件域,必须使用此方式),也可以命名为多个不同的名字的表单域(如果上传个数是固定已知的)。

对于多文件上传:
如果是单文件上传,$_FILES数组比如$_FILES[‘userfile’][‘error’]、$_FILES[‘userfile’][‘name’]之类的变量就可以直接操作,否则它还要进行如上例的处理。至于如何区分多文件和单文件上传,只要文件表单域是以‘[]’结尾命名的,哪怕只有一个文件表单域,也是多文件上传,处理方式和上例同。

坚持原创技术分享,您的支持将鼓励我继续创作!