需要帮助更改代码以成功上传文件,并取消文件上传

时间:2012-10-07 10:17:24

标签: php jquery mysql ajax pdo

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

问题:

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

我想要实现的解决方案:

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

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

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

我只需要帮助编写问题以便能够达到解决方案。有人可以帮忙吗?以下是必要的代码:

AUDIOUPLOAD.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>

JQUERY CODE:

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;
}

3 个答案:

答案 0 :(得分:2)

首先,您可以尝试访问有关会话上传进度的此链接,这应该会告诉您如何在不中断会话的情况下停止上传进度:)

PHP: Session Upload Progress

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

这是一个链接 - &gt; PHP: MySQL_close

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

PS。我不完全确定这会起作用......只是逻辑思考:P ...

答案 1 :(得分: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.upload_progress.name INI设置设置为POST的同名变量时,上传进度将在$ _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

答案 2 :(得分:0)

好的,我会从我的理解中尝试一些东西。

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

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

  2. 当浏览器完成文件上传/表单提交时,服务器仍在处理数据的时间很短,但尚未对您做出响应。在这种情况下,上传的文件可能会保存也可能不会保存(我们不知道)。您需要致电cancelaudio.php页面将其从硬盘中删除。

  3. 2个案例中只有一个是真的,但你可以同时做这两个行动,因为没有一个会与另一个案件发生冲突。

    第一个案例的答案就在这里(因为您使用<iframe>提交表单):Is it possible to cancel file upload that uses hidden iframe?

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