用PHP上传进度栏


Answers:


70

这是到目前为止(在经过数小时的搜索和尝试脚本之后)最简单的设置,也是我发现的最好的上载器

https://github.com/FineUploader/fine-uploader

它不需要APC或任何其他外部PHP库,我可以在共享主机上获得文件进度反馈,它声称支持html5拖放(未经个人测试)和多个文件上传。


11
我相信您会改用它:github.com/valums/file-uploader-同一作者。
迈克尔·里德

5
并且请参阅会话上传进度,这是PHP提供的开箱即用的文件获取进度的工具。
hakre 2011年

6
@jpeskin对开发者来说是不公平的。仅仅因为您“愿意付钱给他们”并没有像妓女那样强迫他们为您工作。如果您不知道如何调试它,那么我就不会四处指指您自己以外的其他人了–您在互联网上找到的软件是“按原样”提供的,所以不要四处抨击那些无非就是要提供帮助。
sucitivel 2012年

3
@sucitivel:更详细:我提出付款并接受了他,然后我们经历了麻烦,记录了我们所看到的所有错误,然后他停止了回复任何电子邮件(仅是礼貌的电子邮件,要求状态更新以及是否他仍然对这项工作感兴趣)。我认为没有人有义务赚钱。对于那些可能想了解开发人员的可用性和/或对自由职业的兴趣的其他人来说,它只是一个观察性数据点。该项目是分叉的,所以我并不是唯一一个意识到开发人员对维护失去兴趣的人。
jpeskin 2012年

5
blueimp.github.com/jQuery-File-Upload-这真的很好。至少我喜欢它,因为它不会在Ubuntu下滞后=)
BeRocket 2012年

13

如果安装了APC,则它具有用于上载进度的回调挂钩。

Rasmus Lerdorf(PHP的创建者)使用YUI对此进行了示例(哦,这是PHP的源代码)。

请参阅此处的文档


相同或php源链接都不再起作用..请问您有一个alt链接吗?
supersan

@supersan这个答案已经过时了。APC已经死了,会话上传API现在又是另外一回事了。如果服务器使用的是FastCGI,它也将无法正常工作。
Powerlord

13

很遗憾地说,就我所知,由于PHP的工作方式,纯PHP上传进度条,甚至PHP / Javascript上传进度条都是不可能的。最好的选择是使用某种形式的Flash上​​传器。

AFAIK这是因为直到所有超全局变量(包括$ _FILES)都被填充后,您的脚本才会执行。在您的PHP脚本被调用时,文件已完全上传。

编辑:这不再是事实。那是在2010年。


13
为什么要三票否决票?是的,他们是完全没有道理的。我敢于向任何人展示可以在本机PHP上运行的进度栏,并且不需要额外的扩展/ Apache模块/ perl脚本/其他内容即可工作。
Pekka

1
好吧,这是2011年,现在有了HTML5成为可能。看到这里的第一个反应:stackoverflow.com/questions/76976/...
Zarel

10
好吧,这是2012年,通过XMLHttpRequest以HTML5格式上传的文件在所有主流浏览器中仍然不可用。
Damien B

3
@Pekka웃这不是真的。如果您已经安装了APC(并且应该安装),则可以完全用PHP原生完成它,也不需要使用javascript。
Ariel

2
@Pekka웃更不用说使用PHP> = 5.4中的会话信息进行上传了。
Wookie88

8

一种适用于我的PHP式(5.2+)和无Flash方式:

首先,请参阅这篇文章,说明如何启动和运行“ uploadprogress”扩展。

然后,在包含您要从中上传文件的表单的页面中,创建以下iframe:

<iframe id="progress_iframe" src="" style="display:none;" scrolling="no" frameborder="0"></iframe>

接下来,将此代码添加到“提交”按钮:

onclick="function set() { f=document.getElementById('progress_iframe'); f.style.display='block'; f.src='uploadprogress.php?id=<?=$upload_id?>';} setTimeout(set);"

现在,您的表单中有一个隐藏的iframe,当您单击“提交”以开始上传文件时,该iframe将可见并显示uploadprogress.php的内容。$ upload_id必须与您用作表单中隐藏字段“ UPLOAD_IDENTIFIER”的值相同。

uploadprogress.php本身看起来像这样(修复并根据需要进行调整):

<html>
<head>
<META HTTP-EQUIV='REFRESH' CONTENT='1;URL=?id=<?=$_GET['id']?>'>
</head>
<body>
Upload progress:<br />
<?php
    if(!$_GET['id']) die;
    $info = uploadprogress_get_info($_GET['id']);
    $kbytes_total = round($info['bytes_total'] / 1024);
    $kbytes_uploaded = round($info['bytes_uploaded'] / 1024);
    echo $kbytes_uploaded.'/'.$kbytes_total.' KB';
?>
</body>
</html>

请注意,每秒刷新一次。如果愿意,您当然可以在此处添加一些不错的视觉进度条(例如2个嵌套的<div>具有不同的颜色)。具有上载进度的iframe自然仅在上载过程中起作用,并且在提交表单并且浏览器重新加载到下一页后,其可见寿命就结束了。


您如何在php中没有$ _FILES的情况下上传文件

4

上传进度条的实现很容易,不需要任何其他PHP扩展,JavaScript或Flash。但是您需要PHP 5.4及更高版本

您必须通过将指令设置session.upload_progress.enabledOnin来启用收集上传进度信息php.ini

然后,其他任何文件输入之前,将隐藏的输入添加到HTML上载表单。name该隐藏输入的HTML属性应与session.upload_progress.namefrom的指令值相同php.ini(最终以开头session.upload_progress.prefix)。该value属性取决于您,它将用作会话密钥的一部分。

HTML表单可能如下所示:

<form action="upload.php" method="POST" enctype="multipart/form-data">
   <input type="hidden" name="<?php echo ini_get('session.upload_progress.prefix').ini_get('session.upload_progress.name'); ?>" value="myupload" />
   <input type="file" name="file1" />
   <input type="submit" />
</form>

发送此表单时,PHP应该在$_SESSION超全局结构中创建一个新密钥,该密钥将填充有上传状态信息。键是串联的namevalue也包含隐藏的输入。

在PHP中,您可以查看填充的上传信息:

var_dump($_SESSION[
    ini_get('session.upload_progress.prefix')
   .ini_get('session.upload_progress.name')
   .'_myupload'
]);

输出将类似于以下内容:

$_SESSION["upload_progress_myupload"] = array(
  "start_time" => 1234567890,   // The request time
  "content_length" => 57343257, // POST content length
  "bytes_processed" => 54321,   // Amount of bytes received and processed
  "done" => false,              // true when the POST handler has finished, successfully or not
  "files" => array(
    0 => array(
      "field_name" => "file1",    // Name of the <input /> field
      // The following 3 elements equals those in $_FILES
      "name" => "filename.ext",
      "tmp_name" => "/tmp/phpxxxxxx",
      "error" => 0,
      "done" => false,            // True when the POST handler has finished handling this file
      "start_time" => 1234567890, // When this file has started to be processed
      "bytes_processed" => 54321, // Number of bytes received and processed for this file
    )
  )
);

创建进度条需要所有的信息-如果上传仍在进行中,您将获得这些信息;总共将要传输多少字节以及已经传输了多少字节。

要将上传进度呈现给用户,请编写另一个PHP脚本而不是上传脚本,该脚本将仅查看会话中的上传信息并以JSON格式返回。可以使用AJAX和提供给用户的信息定期(例如每秒)调用此脚本。

您甚至可以通过将设置为$_SESSION[$key]['cancel_upload']来取消上传true

有关详细信息,其他设置和用户注释,请参见PHP manual


2

另一个完整的JS上传器:http : //developers.sirika.com/mfu/

  • 它是免费的(BSD许可证)
  • 可国际化
  • 兼容跨浏览器
  • 您可以选择是否安装APC(进度条VS进度条)
  • 可定制外观,因为它使用了dojo模板机制。您可以根据您的CSS在te模板中添加您的类/ ID

玩得开心


2

HTML5引入了文件上传api,可让您监视文件上传的进度,但是对于较旧的浏览器,有一个plupload框架专门用于监视文件上传并提供有关文件的信息。加上它具有大量的回调,因此它可以在所有浏览器中使用


2

Gears和HTML5在HttpRequest对象中都有一个progress事件,用于通过AJAX提交文件上传。

http://developer.mozilla.org/en/Using_files_from_web_applications

别人已经回答的您的其他选择是:

  1. 基于Flash的上传器。
  2. 基于Java的上传器。
  3. 向Web服务器发送的第二个彗星样式请求或脚本,用于报告接收到的数据大小。一些Web服务器(例如Lighttpd)提供了在进程内执行此模块的模块,以节省调用外部脚本或进程的开销。

从技术上讲,有类似YouTube上传的第四个选项,使用Gears或HTML5,您可以使用Blob将文件分成小块,然后分别上传每个块。完成每个块后,您可以更新进度状态。


1

您将需要使用Javascript创建进度条。一个简单的Google搜索使我想到了这篇文章:WebAppers CSS的Simple Javascript Progress Bar

Dojo文件上载进度栏小部件是使用Dojo Javascript框架的另一个选项。

编辑:假设您上传了大量图像(例如相册),并将其发布到PHP脚本中,则可以使用javascript从帖子中读取结果,并根据上传的图像数更新进度条/图片总数。这具有仅在每个帖子完成后进行更新的副作用。在这里查看有关如何使用JS发布的一些信息。


6
-1 Javascript进度条很好用,但据我所知与文件上传无关。而且Dojo上传进度条没有提供任何PHP接口,如果我错了,请纠正我。
Pekka

1

可以完成一个php / ajax进度条。(在pear中检出Html_Ajax库)。但是,这需要将自定义模块安装到php中。

其他方法需要使用iframe,php会通过iframe查看已上传了多少文件。但是,此隐藏的iframe可能会被某些浏览器插件阻止,因为隐藏的iframe通常用于向用户计算机发送恶意数据。

如果您无法控制服务器,最好的选择是使用某种形式的Flash进度条。


一些插件可能会阻止iframe,但是浏览器呢?你能给我举个例子吗?
2010年

谷歌搜索“ ajax php文件上传”一词会返回前5个结果中的第4个,全部使用iframe(不确定第5个结果是否会加载(页面不会加载))。看一下每个站点上的示例。
Ali Lown

确实,他们使用iframe,但更不用说在任何情况下都可以将其阻止。还是我错过了?
2010年

抱歉,误读了您要问的问题,不,我无法提供任何直接阻止iframe的浏览器示例,我在想人们使用的附加组件,例如阻止iframe的noscript。更新了帖子中的文本,以供将来参考。
阿里·洛文
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.