【问题标题】:files get uploaded just before they get cancelled [closed]文件在被取消之前上传[关闭]
【发布时间】:2012-10-12 19:05:49
【问题描述】:

这里遇到了一个小情况,我试图取消文件的上传。我所做的是,如果用户单击“取消”按钮,那么它将简单地删除 iframe,以便它不会转到将文件上传到服务器并将数据插入数据库的页面。

现在,如果用户在快速的时间内单击“取消”按钮,这可以正常工作,但我意识到的问题是,如果用户很晚单击“取消”按钮,它有时不会删除 iframe时间意味着文件刚刚在用户单击“取消”按钮之前上传。

所以我的问题是,如果文件确实在用户单击“取消”按钮之前以某种方式上传,它会删除数据库中的数据并从服务器中删除文件吗?

图片上传表格如下:

<form action="imageupload.php" method="post" enctype="multipart/form-data" target="upload_target_image" onsubmit="return imageClickHandler(this);" class="imageuploadform" >
  <p class="imagef1_upload_process" align="center">
    Loading...<br/>
    <img src="Images/loader.gif" />
  </p>
  <p class="imagef1_upload_form" align="center">
    <br/>
    <span class="imagemsg"></span>
    <label>Image File: <input name="fileImage" type="file" class="fileImage" /></label><br/>
    <br/>
    <label class="imagelbl"><input type="submit" name="submitImageBtn" class="sbtnimage" value="Upload" /></label>
  </p>
  <p class="imagef1_cancel" align="center">
    <input type="reset" name="imageCancel" class="imageCancel" value="Cancel" />
  </p>
  <iframe class="upload_target_image" name="upload_target_image" src="#" style="width:0px;height:0px;border:0px;solid;#fff;"></iframe>
</form> 

下面是控制“取消”按钮的jquery函数:

$(imageuploadform).find(".imageCancel").on("click", function(event) {
    $('.upload_target_image').get(0).contentwindow
    $("iframe[name='upload_target_image']").attr("src", "javascript:'<html></html>'");
    return stopImageUpload(2);
});

以下是上传文件并将数据插入数据库的 php 代码。上面的表格发布到这个php页面“imageupload.php”:

<body>
<?php

include('connect.php');

session_start();

$result = 0;


//uploads file
move_uploaded_file($_FILES["fileImage"]["tmp_name"],
"ImageFiles/" . $_FILES["fileImage"]["name"]);
$result = 1;

//set up the INSERT SQL query command to insert the name of the image file into the "Image" Table
$imagesql = "INSERT INTO Image (ImageFile) 
VALUES (?)";

//prepare the above SQL statement
if (!$insert = $mysqli->prepare($imagesql)) {
  // Handle errors with prepare operation here
}

//bind the parameters (these are the values that will be inserted) 
$insert->bind_param("s",$img);

//Assign the variable of the name of the file uploaded
$img = 'ImageFiles/'.$_FILES['fileImage']['name'];

//execute INSERT query
$insert->execute();

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

//close INSERT query
$insert->close();

//Retrieve the ImageId of the last uploded file
$lastID = $mysqli->insert_id; 

//Insert into Image_Question Table (be using last retrieved Image id in order to do this)
$imagequestionsql = "INSERT INTO Image_Question (ImageId, SessionId, QuestionId)  
VALUES (?, ?, ?)"; 

//prepare the above SQL statement
if (!$insertimagequestion = $mysqli->prepare($imagequestionsql)) { 
  // Handle errors with prepare operation here 
  echo "Prepare statement err imagequestion"; 
} 

//Retrieve the question number
$qnum = (int)$_POST['numimage'];

//bind the parameters (these are the values that will be inserted) 
$insertimagequestion->bind_param("isi",$lastID, 'Exam', $qnum); 

//execute INSERT query
$insertimagequestion->execute(); 

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

//close INSERT query
$insertimagequestion->close();

?>

<!--Javascript which will output the message depending on the status of the upload (successful, failed or cancelled)-->

<script>
    window.top.stopImageUpload(<?php echo $result; ?>, '<?php echo $_FILES['fileImage']['name'] ?>');
</script>
</body>

更新:

下面是php代码“cancelimage.php”,我想从服务器中删除取消的文件并从数据库中删除记录。它已设置但尚未完成,有人可以完成它以便我可以使用 $_SESSION 检索文件的名称和它的 id 吗?

<?php

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

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


//remove file from server
unlink("ImageFiles/...."); //need to retrieve file name here where the ... line is

//DELETE query statement where it will delete cancelled file from both Image and Image Question Table
$imagedeletesql = " DELETE img, img_q 
FROM Image AS img 
LEFT JOIN Image_Question AS img_q 
ON img_q.ImageId = img.ImageId 
WHERE img.ImageFile = ?"; 

//prepare delete query
if (!$delete = $mysqli->prepare($imagedeletesql)) {
// Handle errors with prepare operation here
}

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

//execute DELETE query
$delete->execute();

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

//close query
$delete->close();

?>

您能否在您的答案中提供一个示例代码,以便于我。谢谢

【问题讨论】:

    标签: php jquery ajax mysqli


    【解决方案1】:

    好的,就像我之前的回答中所说的,您可以使用$_SESSION 来存储$lastID$ImageFile

    例如,在$lastID = $mysqli-&gt;insert_id; 之后插入以下内容:

    $_SESSION['lastID'] = $lastID;
    $_SESSION['ImageFile'] = $_FILES["fileImage"]["name"];
    

    这将在会话中存储lastIDImageFile

    cancelimage.php 中输入以下内容:

    unlink("ImageFiles/" . $_SESSION['ImageFile']); 
    
    $delete = $mysqli->prepare('DELETE FROM Image WHERE id = ?');
    $delete->bind_param("i",$_SESSION['lastID']);
    $delete->execute();
    

    现在向取消按钮添加一个操作,将 iframe 的源更新为cancelimage.php

    但是有一个风险,因为如果用户之前上传了一个文件,上传一个新文件但文件没有通过(因此没有设置会话变量),那么之前的文件将被删除。

    【讨论】:

    • 谢谢,我会看看能不能把它还给你,然后对结果发表评论。如果用户之前上传文件,不要担心前一个文件被删除的可能性,因为我没有将它包含在我的问题代码中,但在我的代码中我说如果文件已经存在于服务器中,则执行计数并添加一个数字。例如,如果我已经有 tulips.png 并且我再次上传相同的文件,该文件将变为 tulips_2.png,然后再次上传它的 tulips_3.png 等等。
    • 嘿,谢谢伙计们,效果很好:)
    【解决方案2】:

    既然您使用 PDO,您可以使用:

    $insert->rollBack();
    

    回滚最近的插入。并找到上传的文件并使用:

    unlink('test.html');
    

    查看这些链接以获取有关 rollBackunlink 的更多信息

    【讨论】:

    • 嗨,我唯一的问题是我只想在用户点击“取消”按钮时进行回滚,如果用户没有点击取消按钮,那么显然文件被上传,但如果他们点击取消按钮,那么我希望它执行取消链接。你知道怎么做吗?
    • 我会将文件名存储到会话变量 $_SESSION["nameofupload"] 中,然后我会异步转到另一个 php 页面 undo.php,然后查找我需要的会话 cookie 并取消。
    • 你把它放到取消按钮的Click事件中
    • @Relentless 所以我必须执行类似$_SESSION[filenameupload] = $_FILES["fileImage"]["name"]); 的操作,然后在 undo.php 页面中执行 unlink($_SESSION[filenameupload]),最后在取消按钮功能中的 jquery 代码中,我是否导航到 undo.php页面购买包括此代码jQuery.ajax("undo.php");
    • 几乎 - 在会话中输入文件名,我认为 $_FILES["file"]["name"] 取决于您输入的名称。现在你知道文件名是什么,你可以从另一个 php 页面删除
    【解决方案3】:

    如果iframe 被删除并且没有调用通知上传哪个文件的回调,那么很难知道要删除哪个文件。

    虽然您可以将最后上传文件的$lastID$ImageFile 存储在$_SESSION 中,并请求在数据库中查找文件的其他页面删除记录,然后从磁盘中删除文件.

    我可以提供一些示例代码,但我的建议是您修改当前代码,使其更具可读性并修复缩进..

    另一种解决方案是使用以下函数显式中止上传:

    function abortUpload(){
        var iframeObj = $("iframe[name='upload_target_image']").get(0);
        if (iframeObj.contentWindow.document.execCommand){ 
            // IE
            iframeObj.contentWindow.document.execCommand('Stop');
        }else{
            // other browsers
            iframeObj.contentWindow.stop();
        }
    }
    

    【讨论】:

    • 我尝试了您之前向我展示的 about upload 方法,但效果不佳,这就是我使用 remove iframe 方法的原因。我将清理并缩进上面的当前代码,以使您和其他人更容易阅读。我还将提供一些代码来执行 unlink() 并从数据库中删除记录。您是否能够操纵代码以匹配您使用 $_SESSION 的理论?
    • 代码被清理,缩进并包含删除查询和取消链接语句,您能看到代码并查看需要更改的地方并提供您的版本以如何修复它?
    猜你喜欢
    • 2019-03-09
    • 2013-05-29
    • 2017-11-14
    • 2016-08-23
    • 2010-12-21
    • 1970-01-01
    • 1970-01-01
    • 2015-02-11
    • 1970-01-01
    相关资源
    最近更新 更多