【php】文件的上传与下载

php文件的上传与下载其实不难的,就那么的几行代码,比起JSP的要简单得多,具体可以参考:《【Servlet】利用Servlet3.0标准与JSTL表达式实现文件上传系统,支持图片上传后显示》(点击打开链接);《【Jsp】把Java写到Respond输出流里面供用户下载》(点击打开链接);《【Struts2】文件的上传与上传权限的控制》(点击打开链接);《【Struts2】中文文件的下载与下载权限的控制》(点击打开链接),但是网上的资料众说纷纭,还用来许许多多奇怪的函数,必须整理一下。


一、基本目标

设置一个文件上传系统,指定只能上传少于1M的图片,上传之后提供此文件的下载。

【php】文件的上传与下载_第1张图片

同时注意好本上传下载系统的防范工作,直接输入网址访问两个处理页是不行的。这里用到了《【php】使用重定向,伪装表单处理页面不存在》(点击打开链接)重定向的思想。

【php】文件的上传与下载_第2张图片

当然,自然能够在上传文件夹找到这张被改名的图片,服务器上的图片一般不存中文的,改名成时间戳,后附上用户信息等。



二、基本准备

1、设置上传与下载的系统之前,先打开php目录下的php.ini,如果通过《【php】本地开发环境的部署与helloworld》(点击打开链接)一键在windows安装php,则打开..\php-5.2.14-win32下的php.ini-dist:

【php】文件的上传与下载_第3张图片

2、利用Ctrl+F查询按钮找到File Uploads那行,把file_uploads参数设置为On,随便给一个临时上传文件夹给php,然后设置php最大上传大小,当然,我们不是每次上传都给这个最大限度给用户,这个大小,只是像《【Struts2】文件的上传与上传权限的控制》(点击打开链接)中抛出异常的大小。

【php】文件的上传与下载_第4张图片

3、在工程文件夹下新建一个upload文件夹去存放上传的图片,php找不到这个文件夹则拒绝上传,当然,你可以自己写代码新建。其基本目录结构如下所示,upload.html是文件表单页,upload.php则是上传处理页,download.php则是下载处理页。



三、制作过程

1、upload.html是文件表单页,没什么好说的,就一个表单:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>文件上传</title>
</head>

<body>
<form action="upload.php" method="post" enctype="multipart/form-data">
    <input type="file" name="file" /> 
    <input type="submit" name="submit" value="提交" />
</form>
</body>
</html>
2、上传处理页upload.php,关键一个$_FILES["xx"],其中xx而是upload.html中的文件域的name属性,还有如何保存上传文件的问题,保存上传文件,必须利用$basepath=str_replace('\\','/',realpath(dirname(__FILE__).'/'))."/";取得服务器的绝对路径,整个思想与JSP中《【Servlet】利用Servlet3.0标准与JSTL表达式实现文件上传系统,支持图片上传后显示》( 点击打开链接)是完全类似的,具体如下:

<?php
//看是否是通过正常途径传递一个file过来了
if(empty($_FILES["file"])){
	//如果不是,则非正常打开此页
	header("location: error.php");
	exit;
}
else{
	header("Content-type: text/html; charset=utf-8");
}
//这是判断是否上传的file
$canUpload=true;
//这样就能够取得上传的文件名
$fileName=$_FILES["file"]["name"];
//通过对$fileName的处理,就能够取得上传的文件的后缀名
$fileExtensions=strrchr($fileName, '.');
//这样就能够取得上传文件的大小
$fileSize=$_FILES["file"]["size"];
//即将被打印的错误信息
$errmsg="";

//这里是文件的异常,一般不会出现
if($_FILES["file"]["error"]>0){
	$errmsg .= "异常:".$_FILES["file"]["error"]."!";
	$canUpload=false;
}

//如果上传的文件名的后缀不是以下的几种则不能上传
if($fileExtensions!=".bmp" && $fileExtensions!=".gif" && $fileExtensions!=".jpg" && $fileExtensions!=".jpeg" && $fileExtensions!=".png"){
	$errmsg .= "只能上传图片类型!后缀名必须为:.bmp,gif,jpg,jpeg,png任一!";
	$canUpload=false;
}

//如果上传的文件大于1M则也不能上传
if($fileSize>1*1024*1024){
	$errmsg .= "文件太大!请少于1M!";
	$canUpload=false;
}

//如果文件可以上传
if($canUpload==true){
	//保存在服务器的名字则是时间戳,加文件后缀名
	$saveName=time().$fileExtensions;
	//取得服务器的目录的绝对路径。
	$basepath=str_replace('\\','/',realpath(dirname(__FILE__).'/'))."/";
	//然后则保存这个上传文件
    move_uploaded_file($_FILES["file"]["tmp_name"],$basepath."/upload/".$saveName);
	echo $fileName.",上传成功!大小:".($fileSize/1024)."KB";
	//把保存在服务器的名字传到下载页,供其处理	
	echo "<a href='download.php?saveName=$saveName'>下载</a>";
}
else{
	echo $errmsg."<a href='upload.html'>返回</a>";
}
  

?>
3、下载处理页download.php,这一页其实不写,可以正常显示图片的,但是通过把对象抛到respond对象中给用户下载,则可以提出一个下载提示框。整个思想还是与《【Jsp】把Java写到Respond输出流里面供用户下载》( 点击打开链接)一样,只是写作语言不同而已。

<?php
//防止输入网址直接访问
if(empty($_REQUEST["saveName"])){
	header("location: error.php");
	exit;
}
else{
	header("Content-type: text/html; charset=utf-8");
}
//取得保存在服务器的名字
$fileName=$_REQUEST["saveName"];
//取得服务器的绝对路径
$basepath=str_replace('\\','/',realpath(dirname(__FILE__).'/'))."/";
$filepath=$basepath."upload/".$fileName;
//读取这个文件夹,构造下载流
$fp=fopen($filepath,"r");
//返回文件给Respond对象,给用户下载
header("Content-type: application/octet-stream");
//取出文件大小,还是用于构造Respond对象
$filesize=filesize($filepath);
header("Accept-Length: ".$filesize);
//按照字节格式返回
header("Accept-Ranges: bytes");
//弹出客户端对话框,对应的文件名
header("Content-Disposition: attachment; filename=".$fileName);
//这样就不会有文件分段,导致文件下载之后损坏的问题的
$buffer=1024;
while(!feof($fp)){
    $file_data=fread($fp,$buffer);
    echo $file_data;
}
//关闭文件
fclose($fp);

?>

你可能感兴趣的:(PHP,下载,上传,文件,respond)