【问题标题】:Need help changing code for successful file upload, and cancel file upload需要帮助更改文件上传成功的代码,并取消文件上传
【发布时间】:2012-10-07 10:17:23
【问题描述】:

我在尝试取消上传时遇到了取消按钮的问题,我需要一些帮助来可能会稍微改变我的代码设计。

问题:

在“audioupload.php”脚本运行之前,“canceaudio.php”页面没有所需的信息。这是一个马车和马的情况。如果客户端在 HTTP 请求期间单击取消按钮,“audioupload.php”脚本(在服务器端)永远不会被执行。然而,jQuery 中的客户端活动仍然会运行。

我想要实现的解决方案:

客户端填写表单并提交,生成一个 POST 请求,并附带文件。 POST 请求可能需要几秒钟才能完成,具体取决于文件大小、连接速度等。

只有在所有文件的 HTTP 上传完成后,PHP 才能获得控制权。服务器上的 PHP“动作”脚本通过 POST 方法请求获得控制。如果在上传过程中发生任何错误,$_FILES['error'] 将加载正确的代码。此时您可以检查 $_FILES 中的值、move_uploaded_file()、将文件名加载到 $_SESSION 数组等。

总而言之,如果人类客户端在 POST 请求正在进行时(或在开始上传之前)单击“取消按钮”,这会导致文件上传被取消,处理的 PHP“动作”脚本上传永远不会得到控制。服务器永远没有机会移动上传的文件并将变量加载到数据库或会话数组中。

我只需要帮助对问题进行编码即可找到解决方案。有人可以帮忙吗?以下是必要的代码:

音频上传.PHP

<?php
ini_set('display_errors',1); 
error_reporting(E_ALL);
// connect to the database
include('connect.php');

/* check connection */
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
die();
}

$result = 0;

if( file_exists("AudioFiles/".$_FILES['fileAudio']['name'])) {
$parts = explode(".",$_FILES['fileAudio']['name']);
$ext = array_pop($parts);
$base = implode(".",$parts);
$n = 2;

while( file_exists("AudioFiles/".$base."_".$n.".".$ext)) $n++;
$_FILES['fileAudio']['name'] = $base."_".$n.".".$ext;

move_uploaded_file($_FILES["fileAudio"]["tmp_name"],
"AudioFiles/" . $_FILES["fileAudio"]["name"]);
$result = 1;

}
else
{
move_uploaded_file($_FILES["fileAudio"]["tmp_name"],
"AudioFiles/" . $_FILES["fileAudio"]["name"]);
$result = 1;
}

$audiosql = "INSERT INTO Audio (AudioFile) 
VALUES (?)";

if (!$insert = $mysqli->prepare($audiosql)) {
// Handle errors with prepare operation here
}

//Dont pass data directly to bind_param store it in a variable
$insert->bind_param("s",$aud);

//Assign the variable
$aud = 'AudioFiles/'.$_FILES['fileAudio']['name'];

$insert->execute();

if ($insert->errno) {
// Handle query error here
}

$insert->close();

$lastAudioID = $mysqli->insert_id;   

$_SESSION['lastAudioID'] = $lastAudioID; 
$_SESSION['AudioFile'] = $_FILES["fileAudio"]["name"]; 

$audioquestionsql = "INSERT INTO Audio_Question (AudioId, QuestionId)  
VALUES (?, ?)"; 

if (!$insertaudioquestion = $mysqli->prepare($audioquestionsql)) { 
// Handle errors with prepare operation here 
echo "Prepare statement err audioquestion"; 
} 

$qnum = (int)$_POST['numaudio'];

$insertaudioquestion->bind_param("ii",$lastAudioID, $qnum); 

$insertaudioquestion->execute(); 

if ($insertaudioquestion->errno) { 
// Handle query error here 
} 

$insertaudioquestion->close(); 



?>

CANCELAUDIO.PHP

<?php

 // connect to the database
 include('connect.php');

  /* check connection */
  if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    die();
  }

  unlink("AudioFiles/" . $_SESSION['AudioFile']);  
 
$delete = $mysqli->prepare('DELETE FROM Audio WHERE AudioId = ?'); 
$delete->bind_param("i",$_SESSION['lastAudioID']); 
$delete->execute(); 

$deleteaud = $mysqli->prepare('DELETE FROM Audio_Question WHERE AudioId = ?'); 
$deleteaud->bind_param("i",$_SESSION['lastAudioID']); 
$deleteaud->execute(); 
   
  
?>

HTML 表单代码:

<form action='audioupload.php' method='post' enctype='multipart/form-data' target='upload_target_audio' onsubmit='return audioClickHandler(this);' class='audiouploadform' > 
    
Audio File: <input name='fileAudio' type='file' class='fileAudio' /></label><br/><br/><label class='audiolbl'> 
    
<input type='submit' name='submitAudioBtn' class='sbtnaudio' value='Upload' /></label>
    
<input type='hidden' class='numaudio' name='numaudio' value='" + GetFormAudioCount() + "' />
    
<input type='reset' name='audioCancel' class='audioCancel' value='Cancel' /></label>
    
<iframe class='upload_target_audio' name='upload_target_audio' src='#' style='width:300px;height:300px;border:0px;solid;#fff;'></iframe></form>

查询代码:

function startAudioUpload(audiouploadform){
  $(audiouploadform).find('.audiof1_upload_process').css('visibility','visible');
  $(audiouploadform).find('.audiof1_cancel').css('visibility','visible');
  $(audiouploadform).find('.audiof1_upload_form').css('visibility','hidden');
  sourceAudioForm = audiouploadform;
  
          $(audiouploadform).find(".audioCancel").on("click", function(event) {
              $('.upload_target_audio').get(0).contentwindow
              $("iframe[name='upload_target_audio']").attr("src", "cancelaudio.php");
          return stopAudioUpload(2);
    });
  
      return true;
}

【问题讨论】:

  • 我认为这是一些学校作业,因为我刚刚帮助了你的一位(大概)同学on the same issue。事件虽然你的方法似乎有点不同,但你仍然可以从 solution 中得到一些想法。
  • 这是一个完全不同的问题
  • 即使你做了所有的解释,我也不明白你想要什么。 :s 当客户点击“取消”时你想做什么? “jQuery 中的客户端活动仍然会运行”是什么意思(这对您来说是什么问题)?
  • 您可以尝试使用http://www.plupload.com/ 或其他类似的上传器
  • 通过以下链接,类似问题讨论stackoverflow.com/questions/4558067/…

标签: php jquery mysql ajax pdo


【解决方案1】:

首先您可以尝试访问有关会话上传进度的链接,这应该向您展示如何在不终止会话的情况下停止上传进度:)

PHP: Session Upload Progress

您可以尝试终止 MySQL 连接然后重新打开它,我认为这是停止连接的一种方法...我假设您将代码与取消按钮结合使用(例如 onclick->blah blah编码等等)你可以取消连接,然后在连接终止后返回它?

这是一个链接 -> PHP: MySQL_close

在此之后只需编写一行简单的代码即可开始运行操作脚本(指向您需要运行的函数),这应该允许您继续运行脚本并且不会丢失您需要的会话。

ps。我不完全确定这会奏效...只是逻辑思考:P...

【讨论】:

    【解决方案2】:

    好的,我会根据我的理解尝试一些东西。

    用户使用表单提交文件。这可能需要一些时间,所以当用户点击“取消”时,可能有两种情况:

    1. 浏览器仍在发送表单(及其数据,即文件内容),尚未完成上传。在这种情况下,您所要做的就是取消表单提交。请求浏览器停止它。 这样,audioupload.php 将永远不会执行,并且您无需通过调用 cancelaudio.php 将其删除。

    2. 当浏览器完成文件上传/表单提交时,服务器仍在处理数据并且尚未响应您的短暂时间范围内。在这种情况下,上传的文件可能会或可能不会保存(我们不知道)。您需要调用您的cancelaudio.php 页面将其从硬盘中删除。

    这两种情况中只有一种是正确的,但您可以同时执行这两种操作,因为不会与另一种发生冲突。

    第一种情况的答案在这里(因为您使用&lt;iframe&gt; 提交表单):Is it possible to cancel file upload that uses hidden iframe?

    第二种情况的答案是总是对cancelaudio.php进行Ajax调用,以防文件已被处理和保存但我们没有收到通知(嗯,时间很短,但它仍然可以发生)。

    【讨论】:

      【解决方案3】:

      用 jquery 试试这个:

      $(".audioCancel").live("click", function(){
            var file = $(".fileAudio").val();
            var canc = "Cancel";
           $.post("CANCELAUDIO.PHP", {file:file,canc:canc}, function(result){
               alert(result);
               window.location.reload();     
           });
      
      });
      

      然后在你的 php 中添加这个:

      $file = $_POST["file"];
      $canc = $_POST["canc"];
      if($canc){
          unlink("AudioFiles/" . $canc);  
      }else{
          unlink("AudioFiles/" . $_SESSION['AudioFile']);  
      }
      

      也试试这个:

      启用 session.upload_progress.enabled INI 选项后,PHP 将能够跟踪正在上传的单个文件的上传进度。此信息对于实际的上传请求本身并不是特别有用,但在文件上传期间,应用程序可以将 POST 请求发送到单独的端点(例如通过 XHR)以检查状态。

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

      <?php
      $key = ini_get("session.upload_progress.prefix") . $_POST[ini_get("session.upload_progress.name")];
      var_dump($_SESSION[$key]);
      ?>
      

      还可以通过将 $_SESSION[$key]["cancel_upload"] 键设置为 TRUE 来取消当前正在进行的文件上传。当在同一个请求中上传多个文件时,这只会取消当前正在进行的文件上传和待处理的文件上传,但不会删除成功完成的上传。当像这样取消上传时,$_FILES 数组中的错误键将设置为 UPLOAD_ERR_EXTENSION。

      http://php.net/manual/en/session.upload-progress.php

      【讨论】:

      • 嗨,我明天会测试这个,我一直在做其他事情,但我会测试这个,明天再回复你:)
      • 您好,进行了快速测试,但它不允许我取消上传,如果我单击“取消”按钮,它会忽略它并继续并完成上传。您的 jquery 代码绝对正确吗?有没有办法可以操纵我的 jquery 代码来查看警报的内容?
      猜你喜欢
      • 2011-10-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-14
      • 1970-01-01
      • 2013-07-06
      • 2016-05-12
      相关资源
      最近更新 更多