2013-10-12 40 views
0

我想检查上传的文件的进度。我使用的是具有Session类的Kohana框架,但对于上传进度,我使用的是原生PHP会话。我在Kohana的bootstrap.php中调用session_start(),这意味着每个页面请求都会调用session_start()延迟填充session.upload_progress数据

上传表单提交后,我等了1秒钟,然后开始调用PHP文件来检查上传进度,使用jQuery $.ajax()

问题是$_SESSION[$key]($ key包含上传数据的关键字)没有在首次调用PHP时设置。我已经尝试过调试了这一点,并且session_id()返回了正确的会话ID,所以会话肯定是正确的,并且处于活动状态。在检查上传进度之前,我还等了1秒,所以这不是时间问题。即使未设置$_SESSION[$key],我仍可以通过继续解决此问题,但检查上传是否完成的方法是当$_SESSION[$key]未设置。

HTML表单是用jQuery实时创建的,因为这是一个多文件上传。下面是一个生成的表单中HTML:

<form action="ajax/upload" id="form-HZbAcYFuj3" name="form-HZbAcYFuj3" method="post" enctype="multipart/form-data" target="frame-HZbAcYFuj3"> 
    <iframe id="frame-HZbAcYFuj3" name="frame-HZbAcYFuj3"></iframe> 
    <input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="HZbAcYFuj3"> 
    <input type="file" id="file-HZbAcYFuj3" name="photo" accept="image/jpeg,image/pjpeg,image/png,image/gif"> 
    <button type="button">+ Select Photo</button> 
</form> 

下面是JavaScript的调用来检查其进度的PHP:

public function action_uploadprogress() 
{ 
    $id = isset($_POST['id']) ? $_POST['id'] : false; 

    if (!$id) 
     throw new Kohana_HTTP_Exception_404(); 

    $progress = 0; 
    $upload_progress = false; 

    $key = ini_get("session.upload_progress.prefix") . $id; 

    if (isset($_SESSION[$key])) 
     $upload_progress = $_SESSION[$key]; 
    else 
     exit('100'); 

    $processed = $upload_progress['bytes_processed']; 
    $size = $upload_progress['content_length']; 

    if ($processed <= 0 || $size <= 0) 
     throw new Kohana_HTTP_Exception_404(); 
    else 
     $progress = round(($processed/$size) * 100, 2); 

    echo $progress; 
} 

这里是jQuery的ajax()要求:

this.send_request = function() 
{ 
    $.ajax(
     { 
      url: 'ajax/uploadprogress', 
      type: 'post', 
      dataType: 'html', 
      data: { id: _this.id }, 
      success: 
       function(data, textStatus, jqXHR) 
       { 
        if (textStatus == "success") 
        { 
         if (data < 100) 
          setTimeout(_this.send_request, 1000); 
        } 
       } 
     } 
    ); 
}; 
+0

你在哪里设置send_request.id? –

+0

为什么echo而不是$ this-> response-> body($ progress)? – Darsstar

回答

1

您正在向PHP脚本发送名为'id'的POST。

但是,文档说只有当您发送与php.ini中配置的session.upload_progress.name同名的POST时,才能使用上载进度。

所以,换句话说,如果你的session.upload_progress.name设置为默认值(PHP_SESSION_UPLOAD_PROGRESS),你必须改变下面一行,在send_request功能:

变化:

data: { id: _this.id } 

要:

data: { PHP_SESSION_UPLOAD_PROGRESS: _this.id } 

你也必须改变$_POST['id']$_POST['PHP_SESSION_UPLOAD_PROGRESS']$_POST[ini_get("session.upload_progress.name")]在PHP SCR ipt(以及输入的名字,以防万一它不是默认的)。

上传过程将在上载过程中以及在POSTing与session.upload_progress.name INI设置相同名称的变量设置为时在$ _SESSION超全局中可用。当PHP检测到这样的POST请求时,它将填充$ _SESSION中的一个数组,其中索引是session.upload_progress.prefix和session.upload_progress.name INI选项的连接值。关键是通常通过阅读这些INI设置检索,即

来源:http://php.net/manual/pt_BR/session.upload-progress.php

+0

甜,这个固定它!我一直在这个问题上让自己的大脑在这两个星期里受到伤害我发现的所有示例只在隐藏输入中发送了'

'中的'session.upload_progress.name',而不是在ajax中检查进度,但他们甚至在同一台服务器上也能正常工作。这些都不在Kohana中,所以出于某种原因,在Kohana内部,当你提交表单并且PHP填充上传进度数据,但是在上传进度检查中发送'session.upload_progress.name'时,我想踢开始它?不知道,但我很高兴不再想这个了!再次感谢。 – Gavin

+0

它说我必须等待6个小时才能奖励赏金,但如果一切按计划进行,那么我会在当天适当喝醉,所以我明天可能会发送它:) – Gavin

+0

@Rafael Figueiredo。你会关心看看http://stackoverflow.com/questions/21703081/php-upload-progress-in-php-5-4-is-not-working-session-variables-not-set? – Sam

1

让我们看看我可以得到一些甜美的赏金。我的第一个想法是$ key字符串没有正确设置。

尝试回显其值并在整个$ _SESSION变量上执行print_r以跟踪事情。

现在我根本没有看到来自action_uploadprogress()的'成功'输出。我看到了100个我认为已经完成的工作,但你并没有在js中检查。我会建议调查。不妨回应一下你的计算。我认为它不太可能,但确保您正确上传文件,并能够确定其当前的大小没有任何问题。

另一个问题可能是你如何用jquery处理ajax。我对此并不十分确定,但我认为成功选项已被贬值(1.5+)。从

http://api.jquery.com/jQuery.ajax/

$.ajax({ 
    type: "POST", 
    url: "some.php", 
    data: { name: "John", location: "Boston" } 
}).done(function(msg) { 
    alert("Data Saved: " + msg); 
}); 

使用我见过成功的唯一途径是这样的....

$.ajax({ 
     type: "POST", 
     url: '/login/spam', 
     data: formData, 
     success: function (data) { 
      if (data == 'value') { 
       //Do stuff 
      } 
     } 
    }); 

不过,我可能是完全错误的关于这个....你的设置可能会非常好。我要你做的就是直接在成功/完成的功能是

alert(data); 
alert(textStatus); //if you still use it 

这会告诉你,如果你正在从你的Ajax查询作出恰当的回应。

今晚我会检查几次,明天我会帮忙。告诉我,我所说的任何事情都有助于什么

+0

嘿,我真的很感谢你的详细回复。拉斐尔戈麦斯菲格雷多实际上正确地解决了问题,并解决了问题。 – Gavin