我有以下Angular网站,该网站显示Angular可以更新页面,而PHP在后台通过AJAX执行某些过程。

但是,现在如何获取我的PHP流程,例如for循环以传回$x的值,以便我可以显示$x随其递增的变化?

index.php

<!doctype html>
<html lang="en">
    <head>
      <meta charset="utf-8">
      <title>ajaxtest</title>
      <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script>
    </head>
    <body ng-app="mainApp">
        <div ng-controller="mainController">
            <div>Angular is counting: {{counter}}</div>
            <button ng-click="processFiles()">processFiles</button>
            <div>{{message}}</div>
        </div>

        <script>
        var mainApp = angular.module('mainApp',[]);
        function mainController($scope, $interval, $http) {

            var theTimer = $interval(function () {
                $scope.counter++;
            }, 1000);

            $scope.counter = 0;
            $scope.message = 'click the button to have PHP do something in the background while Angular should continue to count';

            $scope.processFiles = function() {
                $scope.message = 'processing...';
                $http.get('http://localhost/webs/ajaxtest/data.php', {
                    params: {
                        taskIdCode: 'getLoadingStatus'
                    }
                }).success(function (data) {
                    $scope.message = data['status'];
                });
            }
        }
        </script>
    </body>
</html>


data.php
    

        $taskIdCode = filter_input(INPUT_GET, 'taskIdCode', FILTER_UNSAFE_RAW);
        $methodName = 'task_' . $taskIdCode;
        $this->$methodName();
    }
    public function task_getLoadingStatus() {
        for($x = 1; $x <= 4; $x++) {
            sleep(1);
        }
        $data['status'] = 'finished';
        echo json_encode($data);
    }
}
$taskRunner = new TaskRunner();

最佳答案

正如Ricardo所说,一种选择是通过调用处理的相同通道来反馈状态消息-这在AJAX请求上在技术上是可行的,但需要大量修改Web服务器和任何中间组件来刷新内容回到Javascript,并在JavaScript中处理部分响应的复杂性。这是websocket旨在解决的问题。通过HTTP请求处理long running process并不是一个好习惯。

对这种方法的进一步考虑是,HTTP及其基础结构是围绕服务器对请求迅速响应的概念设计的。

如果您不走这条路,那么您需要通过其他渠道提供数据-显而易见的解决方案是AJAX Web服务,它将以当前状态迅速响应。

但是由于这与调用无关,因此需要一种机制来引用正在监视的特定过程。如果您已经有一个会话,则可以使用会话ID或会话本身作为密钥-但是,如果该会话与多个这样的进程相关联,则将无法使用。此外,通过javascript公开会话ID对安全性具有重要意义。

或者,您可以在javascript中创建一个(希望唯一)键,并将该键注入到流程调用中。

            var taskKeyValue=generate_unique_id();
            var keepChecking;

            // first invoke processing.....

            $scope.processFiles = function() {
            $scope.message = 'processing...';
            $http.get('http://localhost/webs/ajaxtest/data.php', {
                params: {
                    taskKey: taskKeyValue
                }
            }).success(function (data) {
                $scope.message = data['status'];
                clearInterval(keepChecking);
            });

            // then while this is outstanding
            var checkFiles = function() {
            $http.get('http://localhost/webs/ajaxtest/pollStatus.php', {
                params: {
                    taskKey: taskKeyValue
                }
            }).success(function (data) {
                $scope.message = data['status'];
            });
            keepChecking=set_interval(checkFiles, 2000);


然后在您现有的php代码中...。

 function doing_slow_thing() {
    for($x = 1; $x <= 40; $x++) {
        file_put_contents('/tmp/' . basename($_GET['taskKey']), $x);
        sleep(1);
    }
    $data['status'] = 'finished';
    echo json_encode($data);
 }


并在pollStatus.php中:

<?php
    print json_encode(
          array('status'
             =>file_get_contents('/tmp/' . basename($_GET['taskKey']))
          ));

07-25 23:00
查看更多