3

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

问题:

在“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(); 



?>

取消音频.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;
}
4

3 回答 3

2

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

PHP:会话上传进度

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

这是一个链接-> PHP:MySQL_close

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

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

于 2012-10-29T11:48:18.267 回答
0

用 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)以检查状态。

当上传正在进行时,上传进度将在 $_SESSION 超全局中可用,并且在 POST 与 session.upload_progress.name INI 设置设置为相同名称的变量时。当 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

于 2012-10-26T19:15:15.127 回答
0

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

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

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

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

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

第一种情况的答案在这里(因为您使用的<iframe>是提交表单):是否可以取消使用隐藏 iframe 的文件上传?

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

于 2012-10-29T16:25:16.370 回答