【问题标题】:check script status in PHP using ajax使用ajax检查PHP中的脚本状态
【发布时间】:2014-12-02 13:21:35
【问题描述】:

我的应用程序中有一个文件上传页面。我需要在文件上传时显示“正在上传”,然后在文件正在处理时显示“正在处理”。然后在脚本完成后,我的页面被重定向到某个 url。

我尝试在脚本中使用 PHP SESSIONS。如下代码:

$_SESSION['uploaded']=0;
if (!empty($_FILES)) {
    $tempFile = $_FILES['file']['tmp_name'];
    $targetPath = dirname( __FILE__ ) . $ds. $storeFolder . $ds;
    $_FILES['file']['name']=date('Ymdhis').$_FILES['file']['name'];
    $targetFile =  $targetPath. $_FILES['file']['name'];
    if(move_uploaded_file($tempFile,$targetFile)){
            $_SESSION['uploaded']=1;
            //some processing here which takes some 4-5second to complete
    }
}

文件上传完成后,我更新会话。我通过在javascript中调用以下函数每秒检查一次会话:

    function countdown(seconds){
                console.log(<?php echo $_SESSION['uploaded']; ?>);
                if(<?php echo $_SESSION['uploaded']; ?>==0){
                    setTimeout(function() {                        
                        //uploading
                        seconds--;
                        countdown(seconds);
                    }, 1000);                     
                }
                else{
                    //processing
                }
            }

从谷歌搜索了很长时间后,我才知道在单个脚本中 SESSION 被锁定,直到脚本执行完成。然后我使用了session_write_close();,但它也不起作用。我总是得到 0 的会话值。

请帮助我以最简单的方式找出解决方案。谢谢。

更新

也无法使其与 Ajax 请求一起使用。所以进一步尝试使用MySQL表。

调用上传脚本时我所做的是create table。然后使用以下代码在其中插入status=0 的值:

$session=session_id();
$stmt=$conn->prepare("DROP TABLE IF EXISTS $session");    
$stmt->execute();
$stmt=$conn->prepare("CREATE TABLE $session (id INT(11), status INT(11))");    
$stmt->execute();
$stmt=$conn->prepare("INSERT INTO $session VALUES(1,0)");
$stmt->execute();

然后在上传完成后,我将状态更新为 1 并对文件进行处理。 然后在成功完成脚本后,我使用session_id() 重定向到结果页面并删除表。

但我的 Ajax 脚本每秒检查一次状态,直到 upload.php 脚本结束才响应。我尝试在每次查询后关闭连接,但徒劳无功。 getstatus.php 上的代码

<?php
    session_start();
    $session=session_id();
    require_once('connect.php');
    $stmt=$conn->prepare("SELECT * FROM $session WHERE id=1");
    $stmt->execute();
    $res=$stmt->fetch(PDO::FETCH_ASSOC);
    echo $res['status'];
?>

目前无法找到解决方案。非常感谢您的帮助。谢谢。

【问题讨论】:

标签: javascript php jquery session


【解决方案1】:

您可以使用静态文件检查上传状态,而不是每秒在服务器端调用一个 PHP 进程。

为客户端生成上传表单时:

  1. 为可访问的目录创建一个临时目录 客户。
  2. 将“上传”写入临时文件
  3. 将文件名存储在会话中。 (注意:用户可能会打开多个上传表单。将文件名存储在数组中)
  4. 将文件名作为隐藏字段发送给客户端。

用户提交表单后在服务器端:

  1. 检查客户端发送的文件名是否与会话中存储的文件名匹配。
  2. 将“处理”写入状态文件
  3. 在您的上传脚本结束时,将“完成”写入状态文件

在客户端,用户提交表单后,通过对状态文件进行ajax请求检查上传状态。

备注

使用 .htaccess 禁用状态文件的缓存。如果这不是选项,您可以使用 php 状态脚本实现相同的行为,并将上传状态保存到会话变量而不是状态文件。

为了确保所有生成的文件都被删除,注册一个销毁处理程序来删除会话中生成的文件:http://php.net/manual/en/function.session-set-save-handler.php

【讨论】:

  • 感谢您的意见。我已经用另一种方法解决了。
【解决方案2】:

&lt;?php echo $_SESSION['uploaded']; ?&gt; 被 PHP 预处理一次,就在这个 javascript 被发送到客户端之前。也就是说,客户端上的 javascript 看起来像:

function countdown(seconds){
            console.log(0);
            if(0==0){
                setTimeout(function() {                        
                    //uploading
                    seconds--;
                    countdown(seconds);
                }, 1000);                     
            }
            else{
                //processing
            }
        }

您应该找到其他方式(ajax?)在客户端更新信息。

【讨论】:

  • 我就是这么问的。这是在服务器端更新值并在客户端访问它的最佳方式。
  • 一切都已经在服务器端准备好了。现在您想在超时时对服务器执行 ajax 调用。检查这个jQuery example,它应该可以解决问题。
  • 尝试实现ajax解决方案。
  • 它不工作。它也有同样的问题会话变量只有在脚本完成后才更新。
【解决方案3】:

评论太长了。

我不确定您会如何使用 PHP 提供进度信息。我试过一次,失败了。

Socket.io 在 Node.js 中很棒,还有一个 PHP server emitter。我可能会试一试。它应该提供近乎即时的通信,而无需等待脚本完成。

或者我会检查 Jquery 上传,它有一个 PHP 服务器脚本。支持进度条Jquery Upload。要么直接实现它,要么查看源代码以了解如何显示进度信息。我尝试快速查看,但无法确定他们是如何轻松完成的。

【讨论】:

    【解决方案4】:

    如果可以在服务器上使用,为什么要使用 DATABASE?

    为了节省带宽和数据库流量,您可以将进程分成 2 个文件

    1. 创建upload.php来服务上传过程

      $_SESSION['uploaded']=0;
        if (!empty($_FILES)) {
        $tempFile = $_FILES['file']['tmp_name'];
        $targetPath = dirname( __FILE__ ) . $ds. $storeFolder . $ds;
        $_FILES['file']['name']=date('Ymdhis').$_FILES['file']['name'];
        $targetFile = $targetPath. $_FILES['file']['name'];
            if(move_uploaded_file($tempFile,$targetFile)){
               // Save path to session var
                $_SESSION['uploaded']=$targetFile;
              //You can tell client if the uploading process were done and show 'Processing ...' 
                 // Place some code
              exit;
            }
      
      }
      
    2. 接下来,创建一个名为 progress.php

      的文件
      // check
      if(!empty($_SESSION['uploaded'])){
          // Do your processing code here
      
        // Remove session
        unset($_SESSION['uploaded']);
        // Then send response to client after your processing were done
        echo 'Done';
        exit;
      }
      

      您可以在标记客户端时使用 jquery 重定向客户端。祝你好运

    【讨论】:

      猜你喜欢
      • 2010-09-05
      • 2013-07-14
      • 2020-11-23
      • 2013-12-14
      • 2013-01-05
      • 2013-09-09
      • 1970-01-01
      • 2016-12-29
      • 1970-01-01
      相关资源
      最近更新 更多