我有以下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']))
));