PHP - 在脚本执行时无法检查会话

时间:2014-10-16 08:05:52

标签: javascript php jquery ajax session

我正在编写一个执行时间很长的php脚本,我希望能够告诉客户端脚本的进度。

我无法通过输出缓冲执行此操作,因为脚本是通过AJAX调用的(并且我希望保持这种方式)。

我偶然发现了一个解决方案,您将进度保存到$ _SESSION变量,并连续调用另一个PHP脚本以从$ _SESSION获取进度。

但是,在我的实现中,这些调用在主(长)进程完成之前不会执行。在Chrome开发者工具窗口中,通话显示为"待定"以及主要的AJAX呼叫,它们都会在主呼叫结束后立即返回进度。

enter image description here

这是主要的长脚本(测试代码):

<?php
@session_start();
for($i=0; $i<10; $i++)
{
    $_SESSION["progress"] = $i;
    sleep(2);
}

这是更新脚本<​​/ p>

<?php
if(isset($_SESSION["progress"]))
    echo $_SESSION["progress"];
else
    echo 0;

这是javascript

$("form#form-main").submit(function(e) {
    e.preventDefault();
    var $form = $(this);
    var timeout_id;

    $form.find("div#popup-overlay").show();

    $.ajax(
        {
            url: $form.attr("action"),
            type: $form.attr("method"),
            data: new FormData($form[0]),
            cache: false,
            contentType: false,
            processData: false,
            xhr: function()
            {
                //get the native XmlHttpRequest object
                var xhr = $.ajaxSettings.xhr();

                //update progress
                xhr.upload.onprogress = function(e)
                { 
                    if(e.lengthComputable)
                    {
                        var progress = Math.ceil(e.loaded / e.total * 100);

                        if(progress < 100)
                            $form.find("div#popup-content #status").text("UPLOADING " + progress + "%");
                        else
                        {   
                            //start getting process progress from server
                            timeout_id = setInterval(
                                function() 
                                {
                                    $.post(
                                        "CheckProgress.php",
                                        function(data)
                                        {
                                            $form.find("div#popup-content #status").text("PROCESSED " + data + " pages");
                                        }
                                    );
                                },
                                300
                            );
                        }
                    }
                };

                //return the customized object
                return xhr;
            },
            success: function(data)
            {
                $form.find("div#popup-content").html(data);
            }       
        }
    );
});

如何让javascript客户端检索进度?

2 个答案:

答案 0 :(得分:2)

根据这篇文章(Using same session ID within two PHP scripts at same time),您无法使用相同的会话ID同时执行php脚本。这称为会话锁定。

解决方案是仅启动写入会话,并在之后立即关闭它,使会话ID不使用CheckProgress。

新长脚本

for($i=0; $i<10; $i++)
{
    @session_start();
    $_SESSION["pages-processed"] = $i;
    session_write_close();
    sleep(2);
}

新的CheckProgress

@session_start();
if(isset($_SESSION["pages-processed"]))
    echo $_SESSION["pages-processed"];
else
    echo 0;

现在它就像一个魅力:)

答案 1 :(得分:-1)

使用

async=false;
你的ajax请求中的

在你的代码中你已经长时间循环了php,页面只会在执行后加载,所以你只能得到进度的最后一个值