如何让PHP更新javascript的冗长进程状态?
我有下面的Angular站点,它显示Angular可以在PHP通过AJAX在后台执行某些进程时更新页面 但是,我现在如何才能让我的PHP进程,例如如何让PHP更新javascript的冗长进程状态?,javascript,php,angularjs,Javascript,Php,Angularjs,我有下面的Angular站点,它显示Angular可以在PHP通过AJAX在后台执行某些进程时更新页面 但是,我现在如何才能让我的PHP进程,例如for循环传回$x的值,以便在其递增时显示$x的后续值 index.php <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>ajaxtest</title>
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>
$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();
阿贾克斯试验
角度正在计数:{{counter}
处理文件
{{message}}
var mainApp=angular.module('mainApp',[]);
函数mainController($scope、$interval、$http){
var theTimer=$interval(函数(){
$scope.counter++;
}, 1000);
$scope.counter=0;
$scope.message='单击按钮让PHP在后台执行某些操作,而Angular应继续计数';
$scope.processFiles=函数(){
$scope.message='processing…';
$http.get('http://localhost/webs/ajaxtest/data.php', {
参数:{
taskIdCode:'getLoadingStatus'
}
}).成功(功能(数据){
$scope.message=数据['status'];
});
}
}
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();
$taskIdCode=filter\u input(input\u GET,'taskIdCode',filter\u UNSAFE\u RAW);
$methodName='task_u2;'$taskIdCode;
$this->$methodName();
}
公共函数任务_getLoadingStatus(){
对于($x=1;$x如果您不使用WebSocket(或某种类型的服务器推送功能),您将不得不求助于
我的建议如下:
var promise = null;
var poller = function() {
console.log("Query the server for the amount of progress done using another $http.get");
};
在执行$http.get
启动长操作之前的函数中:
$scope.processFiles = function() {
$scope.message = 'processing...';
//
// Initialize the interval pooling operation
//
var promise = $interval(poller, 1000);
$http.get('http://localhost/webs/ajaxtest/data.php', {
params: {
taskIdCode: 'getLoadingStatus'
}
}).success(function (data) {
//
// Terminate the interval so it does not run forever!
//
$interval.cancel(promise);
$scope.message = data['status'];
}).error(function() {
$interval.cancel(promise);
});
}
然后,在服务器端,您必须将进度存储在数据库中(或您可能拥有的任何等效内容),以供轮询操作检查。在睡眠之后,每个进度步骤都必须更新此状态
希望这些信息可以帮助您开始:)正如Ricardo所说,一种选择是通过调用处理的同一通道反馈状态消息-这在技术上是可以通过AJAX请求实现的,但需要对Web服务器和任何中间组件进行大量修补,以将内容刷新回Javascript,并在Javascript中复杂地处理p艺术响应。这是WebSocket要解决的问题。通过HTTP请求处理问题不是一个好的做法
对这种方法的进一步考虑是,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);
}
函数做慢的事情(){
对于($x=1;$x使用WebSocket或javascript长轮询实际上我的答案与你的答案有相同的目标。轮询函数将对另一个提供当前状态的脚本执行$http.get
。其目的不是推送部分响应或做一些不寻常的事情。我稍后将查看我的答案,看看我可以在哪里找到答案n改进:)此外,作为对您自己答案的改进,您应该使用AngularJS的$interval
服务。尽管它主要是setInterval
的包装器,但它更适合与AngularJS一起使用。@Piskvor:即使使用默认(阻塞)会话处理程序,您也可以关闭(并因此解锁)在代码中的任何时候都可以启动会话。请参阅会话\u写入\u关闭()