$_FILES数组
$_FILES 超级全局变量,它储存各种与上传有关的信息,这些信息对于通过 PHP 脚本
上传到服务器的文件至关重要。
1.存储在$_FILES["userfile"]["tmp_name"]变量中的值就是文件在 Web 服务器中临时存
储的位置。
2.存储在$_FILES["userfile"]["name"]变量中的值就是用户系统中的文件名称。
3.存储在$_FILES["userfile"]["size"]变量中的值就是文件的字节大小。
4.存储在$_FILES["userfile"]["type"]变量中的值就是文件的 MIME 类型,例如: text/plain
或 image/gif。
5.存储在$_FILES["userfile"]["error"]变量中的值将是任何与文件上载相关的错误代码。这是在 PHP4.2.0 中增加的新特性。
error 分别提供了一些数组常量:
0:表示没有发生错误,
1:表示上载文件的大小超出了约定值。文件大小的最大值是 PHP 配置文件中指定的,该指令是 upload_max_filesize 。
2:表示上载文件大小超出了 HTML 表单的 MAX_FILE_SIZE 元素所指定的最大值。
3:表示文件只被部分上载。
4:表示没有上载任何文件。
<?php
print_r($_FILES);
?>
PHP上传函数
PHP 的文件系统库中提供了大量文件处理函数,除此之外,PHP 还提供了两个专门用
于文件上传过程的函数:is_uploaded_file()和 move_uploaded_file()。
1.确定是否上传文件:is_uploaded_file()
if (is_uploaded_file($_FILES["userfile"]["tmp_name"])) {
echo '已经上传到临时文件夹';
} else {
echo '失败';
}
2.移动上传文件:move_uploaded_file()
if (!move_uploaded_file($_FILES [ "userfile"]["tmp_name"],$_FILES [ "userfile"]["name"])) {
echo ' 移动失败 ' ;
exit ;
}
示例:
upload.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form enctype="multipart/form-data" action="upload.php" method="post">
<input type="hidden" name="MAX_FILE_SIZE" value="1000000" />
上传文件: <input type="file" name="file" />
<input type="submit" value="上传" />
</form>
</body>
</html>
注意:
ENCTYPE=”multipart/form-data”,这里是固定写法,否则文件上传失败
ACTION=”upload.php“,定义要处理上传的程序文件路径
METHOD=”post”,定义传输方式为POST,一般情况下Form提交数据都设置为POST
input type=”hidden” name=”MAX_FILE_SIZE” value=”1000000”,这是一个隐藏域,定义了上传文件的大小上限,超过这个值时,上传失败。它必须定义在文件上传域的前面.而且这里定义的值不 能超过在php.ini 文件中upload_max_filesize设置的值,否则没有意义了 . (注意:MAX_FILE_SIZE 的值只是对浏览器的一个建议,实际上它可以被简单的绕过。因此不要把对浏览器的限制寄希望于该值。实际上,PHP.ini设置中的上传文件最大值,是不会 失效的。但是最好还是在表单中加上 MAX_FILE_SIZE,因为它可以避免用户在花时间等待上传大文件之后才发现该文件太大了的麻烦。)
input type=”file” name=”userfile” ,这是文件上传域,Type属性必须设置为file,但Name属性可以自定义,这个值会在代码文件中使用
upload.php
<?php
header("Content-Type: text/html;charset=utf-8");//避免乱码
echo $_FILES["file"];
//Array
echo "<br>";
print_r($_FILES["file"]);
//Array (
// [name] => 招聘需求.txt :用户系统中的文件名称
// [type] => text/plain :文件的 MIME 类型,例如: text/plain或 image/gif。
// [tmp_name] => D:\wamp64\tmp\php7E34.tmp :文件在 Web 服务器中临时存储的位置
// [error] => 0
//0:表示没有发生错误,
//1:表示上载文件的大小超出了约定值。文件大小的最大值是 PHP 配置文件中指定的,该指令是 upload_max_filesize 。
//2:表示上载文件大小超出了 HTML 表单的 MAX_FILE_SIZE 元素所指定的最大值。
//3:表示文件只被部分上载。
//4:表示没有上载任何文件。
// [size] => 2079 :文件的字节大小
// )
echo "<br>";
// iconv 解决utf-8和gb2312编码转换问题
//$content = iconv("utf-8","gb2312//IGNORE",$content);//把utf-8转化为gb2312
//explode() 函数使用一个字符串分割另一个字符串,并返回由字符串组成的数组。
//end() 函数将数组内部指针指向最后一个元素,并返回该元素的值(如果成功)
//file_exists() 函数检查文件或目录是否存在。如果指定的文件或目录存在则返回 true,否则返回 false。
//move_uploaded_file(file,newloc) 函数将上传的文件移动到新位置。若成功,则返回 true,否则返回 false
//is_uploaded_file() 函数检查指定的文件是否是通过 HTTP POST 上传的。如果文件是通过 HTTP POST 上传的,该函数返回 TRUE。
//in_array() 函数搜索数组中是否存在指定的值。
//is_array() 函数用于检测变量是否是数组,是 array,则返回 TRUE,否则返回 FALSE 。
//isset() 用于检测一个或多个变量是否设置,如果被检测的变量存在则返回 TRUE,否则返回 FALSE。
//下述情况,isset() 返回 FALSE :
// 变量被设置为 null
//$var = null;
// 被 unset() 释放了的变量
//unset($var);
// 类里变量被 var 关键字声明,但尚未设定
//var $var;
//下述情况,isset() 返回 TRUE :
//$var = "";
//$var = array();
//$var = 0;
//$var = false;
//empty() 用于检测一个变量是否为空,如果被检测的变量为空则返回 TRUE,否则返回 FALSE 。
//unset() 用于销毁一个或多个变量,没有返回值。
// 允许上传的图片后缀
$allowedExts = array("gif", "jpeg", "jpg", "png");
$temp = explode(".", $_FILES["file"]["name"]);
$extension = end($temp); // 获取文件后缀名
if ((($_FILES["file"]["type"] == "image/gif")
|| ($_FILES["file"]["type"] == "image/jpeg")
|| ($_FILES["file"]["type"] == "image/jpg")
|| ($_FILES["file"]["type"] == "image/pjpeg")
|| ($_FILES["file"]["type"] == "image/x-png")
|| ($_FILES["file"]["type"] == "image/png"))
&& ($_FILES["file"]["size"] < 204800) // 小于 200 kb
&& in_array($extension, $allowedExts)
) {
if ($_FILES["file"]["error"] > 0) {
echo "错误:: " . $_FILES["file"]["error"] . "<br>";
} else {
echo "上传文件名: " . $_FILES["file"]["name"] . "<br>";
echo "文件类型: " . $_FILES["file"]["type"] . "<br>";
echo "文件大小: " . ($_FILES["file"]["size"] / 1024) . " kB<br>";
echo "文件临时存储的位置: " . $_FILES["file"]["tmp_name"] . "<br>";
// 判断当期目录下的 upload 目录是否存在该文件
// 如果没有 upload 目录,你需要创建它,upload 目录权限为 777
if (file_exists("upload/" . $_FILES["file"]["name"])) {
echo $_FILES["file"]["name"] . " 文件已经存在。 ";
} else {
// 如果 upload 目录不存在该文件则将文件上传到 upload 目录下
move_uploaded_file($_FILES["file"]["tmp_name"], "upload/" . $_FILES["file"]["name"]);
echo "文件存储在: " . "upload/" . $_FILES["file"]["name"];
}
}
} else {
echo "非法的文件格式";
}
?>
此处直接在相对目录新建文件夹upload,存图片。
上传文件成功请求如下:
General:请求行
Request URL:http://localhost/upload.php
Request Method:POST
Status Code:200 OK
Remote Address:127.0.0.1:8888
Referrer Policy:no-referrer-when-downgrade
Response Header:响应头
Connection:Keep-Alive
Content-Length:1263
Content-Type:text/html; charset=UTF-8
Date:Sun, 03 Sep 2017 09:54:24 GMT
Keep-Alive:timeout=5, max=100
Server:Apache/2.4.23 (Win64) PHP/5.6.25
X-Powered-By:PHP/5.6.25
Request Header:请求头
上传重要的参数:
Connection : keep-alive
Content-Type:multipart/form-data; boundary=—-WebKitFormBoundaryvLQK3jbEuXLFiqkD
备注:boundary后面的—-WebKitFormBoundaryvLQK3jbEuXLFiqkD可以自定义。
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding:gzip, deflate, br
Accept-Language:zh-CN,zh;q=0.8
Cache-Control:max-age=0
Content-Length:36751
Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryvLQK3jbEuXLFiqkD
Cookie:Phpstorm-e504b8c0=ddaa8fde-8337-427d-b731-ffde2a135e37
Host:localhost
Origin:http://localhost
Proxy-Connection:keep-alive
Referer:http://localhost/upload.html
Upgrade-Insecure-Requests:1
User-Agent:Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36
Request Payload:请求体
表单form中input标签下的name要传给后台,如下:
input type=”hidden” name=”MAX_FILE_SIZE” value=”1000000”
input type=”file” name=”file” , 如果是文件还要传文件名:111.png
------WebKitFormBoundaryvLQK3jbEuXLFiqkD
Content-Disposition: form-data; name="MAX_FILE_SIZE"
1000000
------WebKitFormBoundaryvLQK3jbEuXLFiqkD
Content-Disposition: form-data; name="file"; filename="111.png"
Content-Type: image/png
------WebKitFormBoundaryvLQK3jbEuXLFiqkD--
完整的信息:
请求行+请求头+请求体
POST http://localhost/upload.php HTTP/1.1
Host: localhost
Connection: keep-alive
Content-Length: 36751
Cache-Control: max-age=0
Origin: http://localhost
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryvLQK3jbEuXLFiqkD
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Referer: http://localhost/upload.html
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.8
Cookie: Phpstorm-e504b8c0=ddaa8fde-8337-427d-b731-ffde2a135e37
------WebKitFormBoundaryvLQK3jbEuXLFiqkD
Content-Disposition: form-data; name="MAX_FILE_SIZE"
1000000
------WebKitFormBoundaryvLQK3jbEuXLFiqkD
Content-Disposition: form-data; name="file"; filename="111.png"
Content-Type: image/png
------WebKitFormBoundaryvLQK3jbEuXLFiqkD--
PhP获取文件:
$_FILES["file"]
所以还要和后台商量好文件的命名,比如这里我们定义了传递的名字为file的文件。
Android
Android 请求要自己来写请求信息,比较麻烦些,如下:
/**
* 上传文件到服务器类
*/
public class UploadUtil {
private static final int TIME_OUT = 10 * 1000; // 超时时间
private static String BOUNDARY = UUID.randomUUID().toString(); // 边界标识 随机生成
private static String PREFIX = "--";
private static String LINE_END = "\r\n";
private static String CONTENT_TYPE = "multipart/form-data"; // 内容类型
private static String CHARSET = "utf-8"; // 设置编码
/**
* Android上传文件到服务端
*/
public static String uploadFile(File file, String RequestURL, String user_agent) {
String result = "";
try {
URL url = new URL(RequestURL);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(TIME_OUT);
conn.setConnectTimeout(TIME_OUT);
conn.setDoInput(true); // 允许输入流
conn.setDoOutput(true); // 允许输出流
conn.setUseCaches(false); // 不允许使用缓存
conn.setRequestMethod("POST"); // 请求方式
conn.setRequestProperty("Charset", CHARSET); // 设置编码
conn.setRequestProperty("connection", "keep-alive");
conn.setRequestProperty("Content-Type", CONTENT_TYPE + ";boundary=" + BOUNDARY);
DataOutputStream dataOutputStream = new DataOutputStream(conn.getOutputStream());
// 添加表单字段内容
// addFormField(params, dataOutputStream);
// 添加图片内容
addImageContent(file, dataOutputStream);
// 请求结束标志
dataOutputStream.writeBytes(PREFIX + BOUNDARY + PREFIX + LINE_END);//写入
dataOutputStream.flush();
// 读取服务器返回结果
InputStream is = conn.getInputStream();
InputStreamReader isr = new InputStreamReader(is, "utf-8");
BufferedReader br = new BufferedReader(isr);
result = br.readLine();
Log.e("MyCenterActivity", "result==" + result);
dataOutputStream.close();
is.close();
dataOutputStream.close();
conn.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
/**
* 格式如下所示:
* --****************fD4fH3hK7aI6
* Content-Disposition: form-data; name="action"
* // 一空行,必须有
*
* @param params
* @param dataOutputStream
* @throws IOException
*/
private static void addFormField(Map<String, String> params, DataOutputStream dataOutputStream) throws IOException {
//构建表单字段内容:文本类型
if (params != null) {
StringBuilder sb = new StringBuilder();
for (Map.Entry<String, String> entry : params.entrySet()) {
sb.append(PREFIX);
sb.append(BOUNDARY);
sb.append(LINE_END);
sb.append("Content-Disposition: form-data; name=\"").append(entry.getKey()).append("\"").append(LINE_END);
// sb.append("Content-Type: text/plain; charset=").append(CHARSET).append(LINE_END);
sb.append(LINE_END);
sb.append(entry.getValue());
sb.append(LINE_END);
}
dataOutputStream.write(sb.toString().getBytes());//写入
}
}
/**
* 格式如下所示:
* --****************fD4fH3hK7aI6
* Content-Disposition: form-data; name="upload_file"; filename="apple.jpg"
* Content-Type: image/jpeg
*
* @param file
* @param dataOutputStream
* @throws IOException
*/
private static void addImageContent(File file, DataOutputStream dataOutputStream) throws IOException {
//文件的上传配置:二进制流
if (file != null) {
StringBuilder sb = new StringBuilder();
sb.append(PREFIX);
sb.append(BOUNDARY);
sb.append(LINE_END);
//$_FILES["upload"],PHP写的upload,Android这里name=也要写成upload
//filename为自己上传文件的名称
sb.append("Content-Disposition: form-data; name=\"upload\";filename=\"head.jpg\"" + LINE_END);
//上传的为JPG文件,mimetype要写:image/jpeg
sb.append("Content-Type: image/jpeg; charset=" + CHARSET + LINE_END);
//sb.append("Content-Disposition: form-data; name=\"uploadfile\"; filename=\""+ file.getName() + "\"" + LINE_END);
//sb.append("Content-Type: application/octet-stream; charset=" + CHARSET + LINE_END);
sb.append(LINE_END);
dataOutputStream.write(sb.toString().getBytes());//发送图片数据
FileInputStream is = new FileInputStream(file);
byte[] buffer = new byte[1024];
int len = 0;
while ((len = is.read(buffer)) != -1) {
dataOutputStream.write(buffer, 0, len);
}
is.close();
dataOutputStream.write(LINE_END.getBytes());//写入
}
}
}