我正在製作一個測試計時器,它允許用戶根據總計時器或單個問題計時器進行測試。我需要這個定時器在完成時保存到數據庫,以確定它是否按時完成,或者如果時間用完就停止測試。問題是我需要這個恢復,如果用戶以任何方式退出。函數「register_shutdown_function()」和「pcntl_signal()」會捕獲正常的退出事件,但是我想知道是否有任何事情可以捕獲所有退出事件,甚至手動殺死瀏覽器(像任務管理器一樣)或藍屏錯誤,或斷電等。Cookie可以工作,但用戶從各個站點切換。我發現的唯一選擇是每10秒鐘節省一次(因爲每秒節省會消耗帶寬和PC資源)。有什麼建議?退出PHP保存計時器
回答
在這個例子中,我將做一個SQL表的格式:
id,session,expire
-----------------
1,d41d8cd98f00b204e9800998ecf8427e,1367727317
要建立這個表格的使用:
CREATE TABLE `quizzes` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`session` varchar(32),
`expire` int(11),
PRIMARY KEY (`id`),
UNIQUE KEY `uc_session` (`session`)
);
現在最有趣的部分。後端:
<?php
$expire_time=20; //twenty seconds
$precision=2; //how accurate the time is (lower = better, but more polls)
$db_host="127.0.0.1";
$db_user="root";
$db_pass="DATABASE_PASSWORD";
$db_db="DATABASE_NAME";
$precision_mill=$precision*1000;
$script=<<<ZZZ
<script>
function keepAlive() {
var xmlhttp;
if (window.XMLHttpRequest) {
xmlhttp=new XMLHttpRequest();
} else {
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState==4 && xmlhttp.status==200) {
if (xmlhttp.responseText=="expired") {
clearInterval(interval);
clearInterval(minusTime);
document.getElementById("timeleft").innerHTML = 0;
alert("Quiz Expired. Please start a new one.");
return;
}
document.getElementById("timeleft").innerHTML = xmlhttp.responseText;
}
}
xmlhttp.open("GET",document.URL+"?keepalive",true);
xmlhttp.send();
}
function keepTime() {
document.getElementById("timeleft").innerHTML-=1;
}
var interval=setInterval(keepAlive,$precision_mill);
var minusTime=setInterval(keepTime,1000);
</script>
ZZZ;
if (isset($_COOKIE['session'])) {
$mysqli=new Mysqli($db_host,$db_user,$db_pass,$db_db);
$session=$mysqli->real_escape_string($_COOKIE['session']);
$expire=$mysqli->query("SELECT `expire` FROM `quizzes` WHERE `session`='".$session."'");
$expire=$expire->fetch_assoc();
if (isset($expire['expire'])) {
$expire=$expire['expire'];
if (isset($_GET['keepalive'])) {
$expire-=$precision;
if ($expire<=0) {
$mysqli->query("DELETE FROM `quizzes` WHERE `session`='".$session."'");
setcookie("session","",time()-3600);
echo "expired";
$mysqli->close();
exit;
}
$mysqli->query("UPDATE `quizzes` SET `expire`=".$expire." WHERE `session`='".$session."'");
echo $expire;
exit;
}
?>
<!DOCTYPE html>
<html>
<head>
<?php
echo $script;
?>
</head>
<body>
<?php
echo 'Quiz resumed, you currently have <div style="display:inline" id="timeleft">'.$expire.'</div> second(s) left.';
?>
</body>
</html>
<?php
$mysqli->close();
exit;
} else {
echo "Quiz expired. Please start a new one.";
exit;
}
} else {
if ($_SERVER['REQUEST_METHOD']==='POST') {
$mysqli=new Mysqli($db_host,$db_user,$db_pass,$db_db);
$session=str_shuffle(md5(microtime()));
$mysqli->query("INSERT INTO `quizzes`(`session`,`expire`) VALUES('".$session."',".$expire_time.")");
setcookie("session",$session);
?>
<!DOCTYPE html>
<html>
<head>
<?php
echo $script;
?>
</head>
<body>
<?php
echo 'Quiz started, you currently have <div style="display:inline" id="timeleft">'.$expire_time.'</div> second(s) left.';
?>
</body>
</html>
<?php
$mysqli->close();
exit;
}
}
if (isset($_GET['keepalive'])) {
echo "expired";
exit;
}
?>
<!DOCTYPE html>
<html>
<head>
<title>Quiz</title>
</head>
<body>
<form method="post" action="">
<input type="Submit" value="Start Quiz">
</form>
</body>
</html>
當用戶點擊開始測驗時,會在數據庫中創建一個會話,以跟蹤他們第一次點擊開始的時間。然後,當時間過去後,允許最大時間,會話被刪除,測驗停止。
我添加了輪詢,所以如果用戶在任何時候關閉測驗,服務器將跟蹤他們停止的位置並允許它們恢復。
感謝您的回覆。假設一個特定的場景,假設(在你的第二個例子中)用戶在11秒鐘,並且有一個權力,如果第二天他用另一臺PC登錄,他將如何在12又是幾秒?您的會話允許信息保存開始時間,但是如果他啓動,中斷並稍後再開始? – 2013-05-05 21:45:41
您將需要使用ajax。但是,這不容易被利用嗎?如果用戶可以「假裝」停電,他們可以將測驗延長到任何他們需要的時間。 – 2013-05-05 22:57:49
我知道它很容易被利用,但這是用戶想要的。雖然每頁只有1個問題,但這樣有幫助。感謝ajax提示,我想沒有辦法在純PHP上做到這一點。 – 2013-05-06 01:53:15
- 1. 退出時保存ViewPart
- 2. 要保存退出時間
- 3. 退出時保存組合框
- 4. 如何使從python3退出計時器
- 5. 保持php會話在瀏覽器退出時不會失效
- 6. 設計退出
- 7. 保存在倒數計時器
- 8. 關閉時:MsgBox(「您想要保存?」)還是MsgBox(「您想退出不保存嗎?」)
- 9. 保存並退出ActiveX對象
- 10. 自動保存退出C#設置
- 11. PyCharm,退出後保存字體大小
- 12. 如何在pthread退出時保持進程退出?
- 13. 應用程序退出時運行計時器
- 14. didExitRegion計時器在同時退出期間重置
- 15. Visual Studio 2008總是在退出時保存SLN文件
- 16. 如何在退出時保存活動狀態? Android
- 17. 我退出時如何讓Eclipse保存項目樹的狀態?
- 18. 當用戶退出應用程序時保存核心數據?
- 19. 在應用程序退出時保存變量
- 20. Apple TV不在應用程序退出時保存localStorage
- 21. Rails服務器保持退出(SocketError)
- 22. 退出WinSCP後保留臨時文件
- 23. 用PHP保存JS輸出
- 24. 禁用javascript時無法退出設計
- 25. 退出cherrypy服務器時出錯
- 26. 如何確保NSUserDefaults設置在應用程序退出時保存到磁盤?
- 27. 運行時計數器退出代碼139,但gdb通過
- 28. Rails和設計 - 測試控制器登錄和退出時
- 29. 清除會話瀏覽器退出php
- 30. PHP:退出功能
你有沒有嘗試過使用數據庫的任何東西? – 2013-05-05 03:50:18
數據庫設置完成,如果相應使用,則會正確保存。如果以強制或突然退出應用程序(如我剛才提到的示例),問題不在於丟失計時器 – 2013-05-05 04:03:27