如何防止脚本导致 PHP 的无限加载时间?
How do I prevent script from causing endless loadtime for PHP?
我一直在寻找一种方法来将变量 id
从 index.php 转移到(除其他外)update-check.php。最初这会导致无休止的加载时间——即页面在本地主机上永远等待。我将其缩小为 session_start();
导致此错误。如果我删除 session_start();
并将 'stories/'. $_SESSION['id'] .'.txt';
替换为实际的 id 变量(如 'stories/film.txt';
),则加载没有任何问题 – 除了我需要该变量的事实。
我还注意到我 有时 在控制台中得到 Failed to load resource: net::ERR_CACHE_MISS
。
我试图修补并找出为什么会发生这种情况以及如何解决它,但我的大脑受伤了,我希望在这种情况下有更多经验的人能够在此漏洞搜索中提供一些帮助(值得一提的是,我不习惯使用 PHP 或后端,作为设计师来自前端)。
编辑 - 所以问题不在于 PHP 而在于这个脚本
是否可以在保持功能的同时调整此脚本以使其发挥出色?
/**
* AJAX long-polling
*
* 1. sends a request to the server (without a timestamp parameter)
* 2. waits for an answer from server.php (which can take forever)
* 3. if server.php responds (whenever), put data_from_file into #response
* 4. and call the function again
*
* @param timestamp
*/
function getContent(timestamp)
{
var queryString = {'timestamp' : timestamp};
$.ajax(
{
type: 'GET',
url: 'update-check.php',
data: queryString,
success: function(data){
// put result data into "obj"
var obj = jQuery.parseJSON(data);
// put the data_from_file into #response
$('#response').html(obj.data_from_file);
// call the function again, this time with the timestamp we just got from server.php
getContent(obj.timestamp);
//timeout to avoid endless loading? didn't make a difference
timeout: 3000 // sets timeout to 3 seconds
}
}
);
}
// initialize jQuery
$(function() {
getContent();
});
更新-check.php
<?php
session_start();
/**
* Server-side file.
* This file is an infinitive loop. Seriously.
* It gets the file data.txt's last-changed timestamp, checks if this is larger than the timestamp of the
* AJAX-submitted timestamp (time of last ajax request), and if so, it sends back a JSON with the data from
* data.txt (and a timestamp). If not, it waits for one seconds and then start the next while step.
*
* Note: This returns a JSON, containing the content of data.txt and the timestamp of the last data.txt change.
* This timestamp is used by the client's JavaScript for the next request, so THIS server-side script here only
* serves new content after the last file change. Sounds weird, but try it out, you'll get into it really fast!
*/
// set php runtime to unlimited
set_time_limit(0);
/* $data_source_file = 'stories/film.txt'; */
$data_source_file = 'stories/'. $_SESSION['id'] .'.txt';
// main loop
while (true) {
// if ajax request has send a timestamp, then $last_ajax_call = timestamp, else $last_ajax_call = null
$last_ajax_call = isset($_GET['timestamp']) ? (int)$_GET['timestamp'] : null;
// PHP caches file data, like requesting the size of a file, by default. clearstatcache() clears that cache
clearstatcache();
// get timestamp of when file has been changed the last time
$last_change_in_data_file = filemtime($data_source_file);
// if no timestamp delivered via ajax or data.txt has been changed SINCE last ajax timestamp
if ($last_ajax_call == null || $last_change_in_data_file > $last_ajax_call) {
// get content of data.txt
$data = file_get_contents($data_source_file);
// put data.txt's content and timestamp of last data.txt change into array
$result = array(
'data_from_file' => $data,
'timestamp' => $last_change_in_data_file
);
// encode to JSON, render the result (for AJAX)
$json = json_encode($result);
echo $json;
// leave this loop step
break;
} else {
// wait for 1 sec (not very sexy as this blocks the PHP/Apache process, but that's how it goes)
sleep( 1 );
continue;
}
}
我最终使用 setcookie("currentID", $id, time()+3600);
而不是通过 AJAX 传递变量。可能不是推荐的遵循路径,但它可以很好地满足我的需要。
我一直在寻找一种方法来将变量 id
从 index.php 转移到(除其他外)update-check.php。最初这会导致无休止的加载时间——即页面在本地主机上永远等待。我将其缩小为 session_start();
导致此错误。如果我删除 session_start();
并将 'stories/'. $_SESSION['id'] .'.txt';
替换为实际的 id 变量(如 'stories/film.txt';
),则加载没有任何问题 – 除了我需要该变量的事实。
我还注意到我 有时 在控制台中得到 Failed to load resource: net::ERR_CACHE_MISS
。
我试图修补并找出为什么会发生这种情况以及如何解决它,但我的大脑受伤了,我希望在这种情况下有更多经验的人能够在此漏洞搜索中提供一些帮助(值得一提的是,我不习惯使用 PHP 或后端,作为设计师来自前端)。
编辑 - 所以问题不在于 PHP 而在于这个脚本 是否可以在保持功能的同时调整此脚本以使其发挥出色?
/**
* AJAX long-polling
*
* 1. sends a request to the server (without a timestamp parameter)
* 2. waits for an answer from server.php (which can take forever)
* 3. if server.php responds (whenever), put data_from_file into #response
* 4. and call the function again
*
* @param timestamp
*/
function getContent(timestamp)
{
var queryString = {'timestamp' : timestamp};
$.ajax(
{
type: 'GET',
url: 'update-check.php',
data: queryString,
success: function(data){
// put result data into "obj"
var obj = jQuery.parseJSON(data);
// put the data_from_file into #response
$('#response').html(obj.data_from_file);
// call the function again, this time with the timestamp we just got from server.php
getContent(obj.timestamp);
//timeout to avoid endless loading? didn't make a difference
timeout: 3000 // sets timeout to 3 seconds
}
}
);
}
// initialize jQuery
$(function() {
getContent();
});
更新-check.php
<?php
session_start();
/**
* Server-side file.
* This file is an infinitive loop. Seriously.
* It gets the file data.txt's last-changed timestamp, checks if this is larger than the timestamp of the
* AJAX-submitted timestamp (time of last ajax request), and if so, it sends back a JSON with the data from
* data.txt (and a timestamp). If not, it waits for one seconds and then start the next while step.
*
* Note: This returns a JSON, containing the content of data.txt and the timestamp of the last data.txt change.
* This timestamp is used by the client's JavaScript for the next request, so THIS server-side script here only
* serves new content after the last file change. Sounds weird, but try it out, you'll get into it really fast!
*/
// set php runtime to unlimited
set_time_limit(0);
/* $data_source_file = 'stories/film.txt'; */
$data_source_file = 'stories/'. $_SESSION['id'] .'.txt';
// main loop
while (true) {
// if ajax request has send a timestamp, then $last_ajax_call = timestamp, else $last_ajax_call = null
$last_ajax_call = isset($_GET['timestamp']) ? (int)$_GET['timestamp'] : null;
// PHP caches file data, like requesting the size of a file, by default. clearstatcache() clears that cache
clearstatcache();
// get timestamp of when file has been changed the last time
$last_change_in_data_file = filemtime($data_source_file);
// if no timestamp delivered via ajax or data.txt has been changed SINCE last ajax timestamp
if ($last_ajax_call == null || $last_change_in_data_file > $last_ajax_call) {
// get content of data.txt
$data = file_get_contents($data_source_file);
// put data.txt's content and timestamp of last data.txt change into array
$result = array(
'data_from_file' => $data,
'timestamp' => $last_change_in_data_file
);
// encode to JSON, render the result (for AJAX)
$json = json_encode($result);
echo $json;
// leave this loop step
break;
} else {
// wait for 1 sec (not very sexy as this blocks the PHP/Apache process, but that's how it goes)
sleep( 1 );
continue;
}
}
我最终使用 setcookie("currentID", $id, time()+3600);
而不是通过 AJAX 传递变量。可能不是推荐的遵循路径,但它可以很好地满足我的需要。