使用表单来上传文件
<form action="upload.php" method="post" enctype="multipart/form-data"> <label for=“file”>文件名:</label> <input type="file" name=“photo" /> <input type=“submit” name=“sub” value=“提交" /> </form> |
上传文件的过程其实就是一个文件的复制过程,在客户端Web页面用户通过HTTP协议将文件复制(上传)到服务端(服务器上)的临时文件夹,然后再使用PHP的系统函数,将临时文件移动到指定的目录中,从而完成整个上传过程。
文件上传简介
案例:
test.php <?php ?> <meta charset=utf-8 /> <form action="./upload.php" method="post" enctype="multipart/form-data"> <input type="file" name=“photo" /> <br /> <input type=“submit” name=“sub” value=“提交" /> </form> upload.php <?php $max_size=700*1024; if($_FILES['photo']['size']>$max_size){ echo "文件太大"; exit; } if($_FILES['photo']['error']==0){ //文件已经被上传到服务器临时目录下 $rs=move_uploaded_file($_FILES['photo']['tmp_name'],'./up/'.$_FILES['photo']['name']); }else{ echo '文件上传失败'; } ?> |
在服务器端,使用 PHP 的全局数组$_FILES(肯定是一个二维数组),来获取用户上传的文件的信息 (文件上传的信息统一存放在二维数组里$_FILES)
$_FILES 是一个二维数组,元素的索引值为input框的name属性的值,索引对应的内容为一个一维数组,此数组固定有5个元素,记录了被上传文件的详细信息
$_FILES['photo']['name']: 上传文件在客户端原名称
$_FILES['photo']['type']: 文件类型
$_FILES['photo']['size']: 被上传的大小,单位:byte
$_FILES['photo']['tmp_name']: 服务器端临时文件名(文件上传会短暂存在临时文件夹里,脚本结束就会巴临时文件删除)
$_FILES['photo']['error']: 上传时产生的错误信息代码
如果没有设置enctype的话,$_FILES接收不到数据
错误代码取值范围
错误值2的,MAX_FILE_SIZE,现在已经没有使用价值,因为谷歌浏览器的审查元素,可以直接对其更改,避开了系统设置的值,所以这个属性已经没有意义了。
移动临时文件
临时的复制文件会在脚本结束时消失。要保存被上传的文件,需要把他拷贝到另外一个位置
bool move_uploaded_file(string $tmp_file, string $path) $tmp_file:临时文件的名字,$_FILES[‘photo’][‘tmp_name’] $path:移动文件到这个位置 |
PHP代码
<?php
if ($_FILES["photo"]["error"] > 0) {
echo "错误代码: " . $_FILES["photo"]["error"] . "<br />";
} else{
$path = ‘./upload/’.$_FILES[‘photo’][‘name’(名字可以自己设置,而且这个地方必须设置名字)];
//需要注意的是,上传之后的文件名,如果再次上传一个同名的文件,会把之前的覆盖掉
move_uploaded_file($_FILES[‘photo’][‘tmp_name’], $path);
}
?>
解决文件名覆盖的办法:
1、每天创建子文件夹,命名为每天的日期,每天的数据存在每天的文件夹里面。 2、保证文件名唯一,使用uniqid()函数生成一个唯一数。//依据时间戳返回值是一个唯一的字符串 |
<?php
echo uniqid().<br />;
sleep(1);//脚本执行很快,不加这句话,前后两个是生成的一样的,这个函数可以让程序在这间隔一秒
也可以用uniqid('a'),在生成的字串前面加上前缀,以便于区分
echo uniqid().<br />;
?>
我们可以通过修改PHP配置文件(php.ini),来对上传功能进行设置
配置名 | 默认值 | 说明 |
file_uploads | ON | 服务器是否支持上传(ON / OFF) |
memory_limit | 128M | 服务器处理单次请求,能分配出的最大内存 |
upload_max_filesize | 64M | 单个上传文件的最大值 |
post_max_size | 3M | 单次POST请求允许提交的最大数据量 |
upload_tmp_dir | wamp/tmp | 临时文件的存储目录,如果为空,则使用系统默认值 |
允许用户上传文件是一个巨大的安全风险,如果你的web应用用不到上传功能,请配置你的php.ini,关闭此功能
通常要对上传的文件进行一定的限制
文件类型限制
文件大小限制
限制文件的类型
<?php
if($_FILES[‘files’][‘type’] == ‘image/jpeg’ || $_FILES[‘files’][‘type’] == ‘image/pjpeg’ or $_FILES[‘files’][‘type’] == ‘image/gif’ ){
(上传操作)
} else {
echo ‘类型不正确!';
}
?>
(if($_FILES[‘files’][‘type’] == ‘image/jpeg’ || $_FILES[‘files’][‘type’] == ‘image/pjpeg’ or $_FILES[‘files’][‘type’] == ‘image/gif’)如果有很多种类型,每个都这样写的话,特别麻烦,所以考虑优化,使用in_array函数进行设置。$type=array('image/jpg','inmage/pjpeg','image/png',....);然后if(in_array($_FILES['photo']['type'],$type)){};注意:if属于项目逻辑代码,以后项目在修改的时候,对于这种逻辑的内容尽量不要修改,就是类似这种提出到数组的思想,可以提高程序的灵活性。
而且对于,一些文件类型相同,但是后缀名不一样的话,需要更精确的判断,需要对文件后缀名进行限制。
$txt=substr($_FILES['photo']['name'],syrrpos($_FILES['photo']['name'],'.'))//取得文件后缀名
限制文件的大小
<?php
$max_size = 2*1024*1024; //2MB 设定大小时要转化成B(字节)。
if ($_FILES[“photo”][“size”] < $max_size) {
(上传操作)
} else {
echo ‘请上传小于2MB的文件';
}
?>
多文件上传
多文件上传和单独文件上传的方式相同,只需要在HTML中增加多个“file”类型的input标签,并制定不同的“name”值即可
多文件上传案例:
demo.php <?php ?> <meta charset=utf-8 /> <form action="./upload.php" method="post" enctype="multipart/form-data"> <input type="file" name=“photo" /> <input type="file" name=“logo" /> <input type="file" name=“txt" /> <br /> <input type=“submit” name=“sub” value=“提交" /> </form> upload.php <?php $max_size=700*1024;//这一部分可以放在配置文件中 //$config=include(./config/config.php); //if($row['size']>$config['max_size']){ // echo '文件太大';exit; //} if($_FILES['photo']['size']>$max_size){ echo "文件太大"; exit; } foreach($_FILES as $key => $row){ if($row['error']!=0){ continue; } $tmp=uniqid(key); //或者rand生成随机数,rand(int $i,int $k),生成$i--$k的随机数 // $rs=rand(10,99); //$tmp=uniqid($rs); //保证文件名长度相等$tmp=md5($tmp); $new_path='./up'.date('Ymd').$tmp; if(!file_exists($new_path)){ mkdir($new_path,0777); } $hz=strrchr($row['name'],'.');//这个函数取得‘.’开始知道字符串结束的部分,并返回这段字符。 $new_path.=$hz; move_uploaded_file($row['tmp_name'],$new_path); } } ?> |
配置文件:
config.php
<?php
return array(
'max_size'=>900*1024,
'type'=>array(
'image/jpg',
'image/png'
)
)
?>
多文件上传的补充知识:
如果不确定客户要上传多少个文件,怎么让客户自由选择上传多少文件?
<meta charset=utf-8 />
<form action="./upload.php" method="post" enctype="multipart/form-data">
<input type="file" name=“photo" />
<input type="file" name=“logo" />
<input type="file" name=“txt" />
<br />
<input type=“submit” name=“sub” value=“提交" />
</form>
<?php
if(empty($_GET['NUM'])){
$i=0;
}ele{
$i=$_GET['num'];
}
if($_GET['act']==add){
}
<a href='./up3.php?act=add&num=<?php echo $i;?>'>新增一个上传框</a>
?>
<?php
$num=$_GET['num'];
for($i=0;$i<$num;$i++){
echo '<input type="file" name="name'.$i.'"';
}
?>
文件下载
文件下载有2种方式:
url模式: <a href=“http://www.itaotmall.com/a.zip”>下载</a>
href中的地址不可以写c:/a/...这种本地的地址,href对应的必须是在线的一个页面,一个合法的url,也可以是一个相对路径。
文件读取模式: 首先需要告知浏览器,将要进行下载文件的处理
然后将文件内容读取出来,输出到浏览器端
<?php $file = fopen("upload/aaa.jpg","r"); header("Content-type:application/octet-stream"); //数据以二进制方式传输 header("Accept-Ranges:bytes"); //按照字节格式返回 header("Accept-Length:".filesize("upload/aaa.jpg")); //返回文件的大小 // attachment:作为附件下载,filename:默认的文件名字 header("Content-Disposition: attachment; filename=aaa.jpg"); //防止服务器瞬时压力增大,分段读取 while(!feof($file)){ echo fread($file,1024); } fclose($file); ?> |
a标签的安全性不好,会把文件的路径展示出来,容易让别人把网站内容采集走,所以建议是采用文件读取模式下载。
download.php <?phpif(!empty($_GET['name'])){ $file_name=$_GET['name']; } $path='./up/2016/'.$file_name; $download_name=$file_name; header("Content-type:application/octet-stream"); //数据以二进制方式传输 header("Accept-Ranges:bytes"); //按照字节格式返回 header("Accept-Length:".filesize("upload/$path")); //返回文件的大小 // attachment:作为附件下载,filename:默认的文件名字 header("Content-Disposition: attachment; filename=$download_name(这个名字可以自定义)"); $file = fopen("upload/$download_name","r"); //防止服务器瞬时压力增大,分段读取 while(!feof($file)){ echo fread($file,1024); } fclose($file); ?> |
下面是图片的页面
<?php
?>
<a href=“./download.php?name=js.rar”>下载</a>
<a href=“./download.php?name=jas.rar”>下载</a>
宠物免费领养小程序,欢迎来踩