php多文件上传与上传文件原理分析

首先用php教程的socket函数库建立一个临时的http服务器,在某一端口监听,然后把 ip地址和端口号通知客户端,客户端把上传表单提交(临时服务器), 临时服务器接受客户端请求,并读取post数据,分析并获取客户端上传的文件信息,把文件保存在服务器上,然后关闭临时服务器,释放资源,上传完成。有点绕,不过思路还是简单的。

<?php

class upload {
public $up_ext=array(), $up_max=5210, $up_dir;
private $up_name, $up_rename=true, $up_num=0, $up_files=array(), $up_ret=array();

function __construct($name, $ext=array(), $rename=true) {
if (!empty($name)) {
$this->up_name = $name;
!empty($ext) && $this->up_ext = $ext;
$this->up_rename = $rename;
$this->up_dir = website_dirroot.
$globals['cfg_upload_path'];
$this->initupload();
} else {
exit('upload文件域名称为空,初始化失败!');
}
}

private function initupload() {
if (is_array($_files[$this->up_name])) {
$up_arr = count($_files[$this->up_name]);
$up_all = count($_files[$this->up_name], 1);
$up_cnt = ($up_all - $up_arr) / $up_arr;
for ($i = 0; $i < $up_cnt; $i ++) {
if ($_files[$this->up_name]['error'][$i] != 4) {
$this->up_files[] = array(
'tmp_name' => $_files[$this->up_name]['tmp_name'][$i],
'name' => $_files[$this->up_name]['name'][$i],
'type' => $_files[$this->up_name]['type'][$i],
'size' => $_files[$this->up_name]['size'][$i],
'error' => $_files[$this->up_name]['error'][$i]
);
}
}
$this->up_num = count($this->up_files);
} else {
if (isset($_files[$this->up_name])) {
$this->up_files = array(
'tmp_name' => $_files[$this->up_name]['tmp_name'],
'name' => $_files[$this->up_name]['name'],
'type' => $_files[$this->up_name]['type'],
'size' => $_files[$this->up_name]['size'],
'error' => $_files[$this->up_name]['error']
);
$this->up_num = 1;
} else {
exit('没找找到需要upload的文件!');
}
}

$this->chkupload();
}

private function chkupload() {
if (empty($this->up_ext)) {
$up_mime = array('image/wbmp', 'image/bmp', 'image/gif', 'image/pjpeg', 'image/x-png');
foreach ($this->up_files as $up_file) {
$up_allw = false;
foreach ($up_mime as $mime) {
if ($up_file['type'] == $mime) {
$up_allw = true; break;
}
}
!$up_allw && exit('不允许上传'.$up_file['type'].'格式的文件!');

if ($up_file['size'] / 1024 > $this->up_max) {
exit('不允许上传大于 '.$this->up_max.'k 的文件!');
}
}
} else {
foreach ($this->up_files as $up_file) {
$up_ext = end(explode('.', $up_file['name']));

$up_allw = false;
foreach ($this->up_ext as $ext) {
if ($up_ext == $ext) {
$up_allw = true; break;
}
}
!$up_allw && exit('不允许上传.'.$up_ext.'格式的文件!');

if ($up_file['size'] / 1024 > $this->up_max) {
exit('不允许上传大于 '.$this->up_max.'k 的文件!');
}
}
}

$this->uploading();
}

private function uploading() {
if (io::dircreate($this->up_dir)) {
if (chmod($this->up_dir, 0777)) {
if (!empty($this->up_files)) {
foreach ($this->up_files as $up_file) {
if (is_uploaded_file($up_file['tmp_name'])) {
$file_name = $up_file['name'];
if ($this->up_rename) {
$file_ext = end(explode('.', $file_name));
$file_rnd = substr(md5(uniqid()), mt_rand(0, 26), 6);
$file_name = date('ymdhis').'_'.$file_rnd.'.'.$file_ext;
}
$file_name = $this->up_dir.'/'.$file_name;

if (move_uploaded_file($up_file['tmp_name'], $file_name)) {
$this->up_ret[] = str_replace(website_dirroot, '', $file_name);
} else {
exit('文件上传失败!');
}
}
}
}
} else {
exit('未开启写入权限!');
}
} else {
exit('上传目录创建失败!');
}
}

public function getupload() {
return empty($this->up_ret) ? false : $this->up_ret;
}

function __destruct() {}
}
?>

那么上传的流程就是如下了:

1.给form标签的enctype属性赋值multipart/form-date,这个是必须的,而且也必须指定的,不然文件无法上传。

2.判断

这个判断一般有三个判断,一个是类型判断,一个是大小判断,一个是文件是否存在的判断。因为这三个判断是保证安全以及成功上传的前提。

3.保存上传的文件

因为文件上传的时候都被存放在一个临时的地方,所以要通过方法将其转移到指定的地方,这样调用也会很方便。

说了原理和流程,就是实际操作以及一些重要函数了。

首先就是指定文件规定类型,但是不能直接指定,必须指定mime类型,不然php会报错,如果你要了解每个文件后缀对应的mime类型,可以看这儿。

上传的文件的信息一般都包含在一个叫$_files的关联数组中,它包含了五方面的信息。

$_files['file']['name'] =>要上传的文件的原名

$_files['file']['type'] =>要上传的文件的类型

$_files['file']['size'] =>文件的大小

$_files['file']['tmp_name'] =>储存的临时文件名,一般是系统默认

$_files['file']['error'] =>上传相关的错误代码

错误代码可以是一串数字,也可以是一些常量。比如0->upload_err_ok->上传成功。你可以在这儿看到详细的对应。

在转移文件之前,最好使用is_uploaded_file()函数来测试临时文件是否是通过http post上传的,也可以检测文件是否存在,一般用文件的临时名作为参数。让后就是使用move_uploaded_file()函数来转移上传的文件,这个函数有两个参数,第一个是指定要转移的文件,第二个是指定要转移的文件。要转移的文件一般是临时文件,所以用临时文件名(tmp_name)来指定。而第二参数一般也作为新的文件名,存进数据库教程,以后就可以调用了。

这里要说的一个就是大文件上传,在不借助第三方工具的情况下,可以通过设定php.ini的参数来完成,一个是upload_max_filesize,这个是指定上传的最大限制,默认是2m,还有一个就是max_input_time,它指定了表单提交的最长时间限制,因为一般大文件上传比较好时,所以这个也是必须的。

表单还可以有一些其他的控制,比如post_max_size是控制表单能接受的最大值,而memory_list可以指定每个php页面能占有的最大内存,默认是8m,max_input_time可以指定每个php页面接受数据的最长时间,默认是60秒。

 

时间: 2024-10-22 11:37:59

php多文件上传与上传文件原理分析的相关文章

php限制上传文件类型并保存上传文件的方法

 这篇文章主要介绍了php限制上传文件类型并保存上传文件的方法,涉及php针对上传文件的常用操作技巧,非常具有实用价值,需要的朋友可以参考下     本文实例讲述了php限制上传文件类型并保存上传文件的方法.分享给大家供大家参考.具体如下: 下面的代码演示了php中如何获取用户上传的文件,并限制文件类型的一般图片文件,最后保存到服务器 ? 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 3

php基础教程:文件以二进制形式上传并放入数据库

  php基础教程:文件以二进制形式上传并放入数据库 conn.php: <?php $id=mysql_connect('localhost','root','root'); mysql_select_db("db_database12",$id); mysql_query("set names gb2312"); ?> index.php: <html> <head> <meta http-equiv="Con

Struts2教程7:上传任意多个文件

一.上传单个文件 上传文件是很多Web程序都具有的功能.在Struts1.x中已经提供了用于上传文件的组件.而在Struts2中提供了一个更为容易操作的上传文件组件.所不同的是,Struts1.x的上传组件需要一个ActionForm来传递文件,而Struts2的上传组件是一个拦截器(这个拦截器不用配置,是自动装载的).在本文中先介绍一下如何用struts2上传单个文件,最后介绍一下用struts2上传任意多个文件. 要用Struts2实现上传单个文件的功能非常容易实现,只要使用普通的Actio

Struts1.x系列教程(9):上传任意多个文件

从<Struts1.x系列教程(8):上传单个文件>中给出的例子可以看出,在Struts1.x中上传单个文件是非常简单的,但在实际应用中,上传文件的个数一般是不确定的,如在网络硬盘中,用户可以根据自己的需要上传任意多个文件(当然,网络硬盘一次上传文件的数目一般也是有上限的,如50个,但用户可以只上传了3个文件,因此,在这种情况下,上传文件的个数也是不确定的).如果读者用过"网易网盘"或其他类似的服务程序,它们的上传文件功能基本上都是根据用户选择的文件多少来添加要上传的文件(

asp.net上传execl文件后,在页面上加载显示

 本篇文章主要是对asp.net上传execl文件后,在页面上加载显示(示例代码)进行了介绍,需要的朋友可以过来参考下,希望对大家有所帮助  代码如下:     #region 上传Execl文件     protected void Button1_Click(object sender, EventArgs e)     {         if (FileUpload1.HasFile)         {             string NewFileName = string.E

php如何解决无法上传大于8M的文件问题

 这篇文章主要介绍了php如何解决无法上传大于8M的文件问题,需要的朋友可以参考下 开发一个文件上传共享网站,曾想使用下面的代码实现文件上传的功能:  代码如下: <form enctype="multipart/form-data" action="add_file.php" method="post">  <fieldset><legend>Fill out the form to upload a fil

文件上传功能,关闭网页后文件还能继续上传,再次打开网站的时候能显示文件的进度

问题描述 文件上传功能,关闭网页后文件还能继续上传,再次打开网站的时候能显示文件的进度 小弟,想开发一个b/s结构的文件上传功能,然后怎么能在关闭网页后文件还能继续上传 ,然后再次打开网站的时候能显示文件上传的进度,小弟先谢谢了! 解决方案 纯b/s肯定不行,浏览器关闭了谁去上传数据?只能是用activex去启动一个客户端程序,让它在后台上传文件. 解决方案二: 这个在B/S结构下是不能实现的,二楼的回答貌似是断点续传的实现,是你的想法? 建议你不要在这个想法上花心思了,没结果的, 冒昧问一下,

上传或下载当文件名包含有特殊字符&amp;quot;#&amp;quot;的处理

http://www.cnblogs.com/luointer123/archive/2010/03/10/1682728.html 在上传或下载文件时,当文件名包含有"#"特殊字符时,上传以后的文件会被改名字,造成下载也下载不了. 如类似以下的代码:             Uri uri = new Uri(targetUrl);//targetUrl对应文件的绝对路径             System.Net.HttpWebRequest request = (HttpWeb

android 开发 怎么向服务器上传视频和图片文件啊!

问题描述 android 开发 怎么向服务器上传视频和图片文件啊! 做到这里卡住了 希望会的大神指导下! 解决方案 http://download.csdn.net/download/tianzhu15/4568311 解决方案二: http://blog.csdn.net/jdsjlzx/article/details/44160603 解决方案三: 上传图片/文件到服务器java 上传文件以及各种视频图片!

asp.net-C# Activx 上传分块上传大文件时能由Activx来完成合并分块的工作吗

问题描述 C# Activx 上传分块上传大文件时能由Activx来完成合并分块的工作吗 我用C#做activx上传大文件,采用http分块上传的思想,可是服务器端的人说,分块和拼接的工作都应由activx完成,上传完了给服务器一个完成的信号,服务器端只负责把拼接的文件编入数据库和移动到合适的位置,可是网上的好多资料都是拼接工作在服务器端完成,Activx真的能实现远程拼接工作吗,如果能,能否给一些资料,谢谢 解决方案 服务器端的人说的不对,ActiveX只需要分块就可以了.再拼接上显然是服务器