总结:我的在线网站有一个秒表,该秒表使用 Javascript 在我的 header.php 上运行。当用户完成测验并单击“提交”按钮时,秒表的数据(用户完成测验所用的总秒数)应保存在我的 PhpMyAdmin 数据库中。
因此,在我的 header.php 中,我的
<head> ... </head>
标签内有以下代码。当用户转移到页面 https://mathspeedtest.com/questions/ 时,此代码将启动秒表。当用户单击提交按钮时,秒表将停止,然后秒表的数据(totalSeconds)应该传输到我的php代码片段中。我的 php 代码片段应该将totalSeconds 保存在我的PhpMyAdmin 数据库中。但事实并非如此。我的秒表数据没有保存在我的数据库中。
在我的 header.php 中:
<head>
<script>
//STOPWATCH JAVASCRIPT CODE
var stopwatchInterval; // Variable to store the interval ID
var startTime; // Variable to store the start time
var totalSeconds = 0; // Variable to store the total number of seconds
window.onload = function() {
if (window.location.href.indexOf('/questions/') > -1) {
startTime = new Date().getTime();
var stopwatchDiv = document.createElement('div');
stopwatchDiv.id = 'stopwatch';
stopwatchDiv.style.position = 'fixed';
stopwatchDiv.style.top = '40px';
stopwatchDiv.style.right = '20px';
stopwatchDiv.style.background = '#ffffff';
stopwatchDiv.style.padding = '20px';
stopwatchDiv.style.borderRadius = '10px';
stopwatchDiv.style.zIndex = '9999';
stopwatchDiv.style.fontSize = '24px'; // Increase font size for better visibility
stopwatchDiv.innerText = '00:00:00';
document.body.appendChild(stopwatchDiv);
stopwatchInterval = setInterval(function() {
var currentTime = new Date().getTime();
var timeDifference = currentTime - startTime;
var totalMilliseconds = Math.floor(timeDifference); // Calculate the total number of milliseconds
totalSeconds = timeDifference / 1000; // Calculate the total number of seconds
var hours = Math.floor((timeDifference % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var minutes = Math.floor((timeDifference % (1000 * 60 * 60)) / (1000 * 60));
var seconds = Math.floor((timeDifference % (1000 * 60)) / 1000);
var milliseconds = totalMilliseconds % 1000; // Extract milliseconds from the total milliseconds
var formattedMilliseconds = milliseconds.toString().padStart(3, '0').slice(0, 2); // Format milliseconds to 2 significant digits
var formattedTime = (hours < 10 ? "0" + hours : hours) + ":" +
(minutes < 10 ? "0" + minutes : minutes) + ":" +
(seconds < 10 ? "0" + seconds : seconds) + "." +
formattedMilliseconds; // Include formatted milliseconds in the time string
document.getElementById('stopwatch').innerText = formattedTime;
}, 1); // Change the interval to 1 millisecond
}
// Save the totalSeconds in the database
var submitButton = document.querySelector('input[name="submit_answer"]');
if (submitButton) {
submitButton.addEventListener('click', function() {
clearInterval(stopwatchInterval); // Stop the stopwatch interval when the submit button is clicked
console.log("Total seconds: " + totalSeconds); // Log the total number of seconds in the console
// send the total seconds to my php code snippet
var ajaxurl = '<?php echo admin_url('admin-ajax.php'); ?>'; // Get the correct URL path to admin-ajax.php
var xhr = new XMLHttpRequest();
xhr.open('POST', ajaxurl, true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send('action=save_total_seconds&total_seconds=' + totalSeconds);
});
};
};
</script>
</head>
/////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////// /////////////////////////
我的短代码 PHP 代码片段位于我的 https://mathspeedtest.com/questions/ 页面:
仅关注代码的粗体部分。其他一切都很好。
$total_seconds = $_POST['total_seconds']; // 确保清理输入
$data = array('time_taken' => $total_seconds);
$where = array('user_name' => $user_name);
$wpdb->更新($table_name,$data,$where);
<?php
get_header();
// Check if the form has been submitted
if (isset($_POST['submit_answer'])) {
$totalScore = 0; // Initialize total score
$userAnswers = $_POST['answerIn']; // Get the user's answers from the submitted form
$user_name = $_SESSION['user_name']; // Retrieve the username from the session
for ($i = 1; $i <= 20; $i++) {
$answerKey = 'answer' . $i;
if ($userAnswers[$i] == $_SESSION[$answerKey]) {
$totalScore++;
}
}
global $wpdb; // Access the global $wpdb object
$table_name = $wpdb->prefix . 'users_test_info'; // Prefix the table name with the WordPress prefix
// Check if the user already exists in the database
$user_exists = $wpdb->get_var($wpdb->prepare("SELECT user_name FROM $table_name WHERE user_name = %s", $user_name));
if ($user_exists) {
// If the user exists, update their test score
$data = array('test_score' => $totalScore);
$where = array('user_name' => $user_name);
$wpdb->update($table_name, $data, $where);
} else {
// If the user doesn't exist, insert a new record
$data = array(
'user_name' => $user_name,
'test_score' => $totalScore
);
$wpdb->insert($table_name, $data);
}
// Retrieve the current user_id
$current_user_id = $wpdb->get_var($wpdb->prepare("SELECT user_id FROM $table_name WHERE user_name = %s", $user_name));
$_SESSION['current_user_id'] = $current_user_id;
$questions_table = $wpdb->prefix . 'users_questions_info'; // Prefix the table name with the WordPress prefix
// Check if the user exists in the questions table
$user_exists = $wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM $questions_table WHERE user_id = %d", $current_user_id));
$questions_data = array();
for ($i = 1; $i <= 20; $i++) {
$question_key = 'Q' . $i;
$user_answer_key = 'Q' . $i . 'UserAns';
$correct_answer_key = 'Q' . $i . 'CorrectAns';
$TestingNum1 = strval($_SESSION['questions'][$i - 1]['number1']);
$TestingNum2 = strval($_SESSION['questions'][$i - 1]['number2']);
$questions_data[$question_key] = "What is $TestingNum1 + $TestingNum2 ?";
$questions_data[$user_answer_key] = $userAnswers[$i];
$questions_data[$correct_answer_key] = $_SESSION['answer' . $i];
}
if ($user_exists) {
// User exists, update the existing row, including questions
$where = array('user_id' => $current_user_id);
$wpdb->update($questions_table, $questions_data, $where);
} else {
// User doesn't exist, insert a new row
$questions_data['user_id'] = $current_user_id;
$wpdb->insert($questions_table, $questions_data);
}
sleep(3);// wait 3 seconds incase the database is slow or to allow time for data to transfer
$total_seconds = $_POST['total_seconds']; // Make sure to sanitize the input
$data = array('time_taken' => $total_seconds);
$where = array('user_name' => $user_name);
$wpdb->update($table_name, $data, $where);
// Direct the user to a different webpage
wp_redirect(admin_url('/results-page/'));
exit;
} else {
// Generating 20 random numbers and calculating answers
$_SESSION['questions'] = array();
$userAnswers = array();
for ($i = 1; $i <= 20; $i++) {
$number1 = rand(1, 10); // Generate a random number between 1 and 10
$number2 = rand(1, 10); // Generate another random number between 1 and 10
$answer = $number1 + $number2;
$_SESSION['questions'][] = array(
'number1' => $number1,
'number2' => $number2
);
$answerKey = 'answer' . $i;
$_SESSION[$answerKey] = $answer;
$userAnswers[$i] = '';
}
}
?>
<form method="POST">
<?php for ($i = 1; $i <= 20; $i++) : ?>
<p>Question <?php echo $i; ?>: What is <?php echo $_SESSION['questions'][$i - 1]['number1']; ?> + <?php echo $_SESSION['questions'][$i - 1]['number2']; ?>?</p>
<input type="text" name="answerIn[<?php echo $i; ?>]" placeholder="Enter your answer" required><br>
<?php endfor; ?>
<div class="centered-container-ForSubmitBtn">
<input type="submit" name="submit_answer" value="Submit" style="border: 1px solid;">
</div>
</form>
<?php
get_footer();
?>
我尝试通过从秒表打印出总秒数的值来进行调试:
<?php
$total_seconds = $_POST['total_seconds']; // Make sure to sanitize the input
var_dump($total_seconds);
?>
如果工作正常,我应该获得 $total_seconds 的值(即 49.425),仅作为示例。
注:第35行是
$total_seconds = $_POST['total_seconds'];
您似乎正在尝试管理两个不同的请求(XMLHttpRequest和来自浏览器的表单提交),就好像它们是单个请求一样。 事实上,XMLHttpRequest将生成第一个请求,并且在表单提交之后立即生成另一个请求。
从您的代码中,我假设XMLHttpRequest的端点与表单提交相同。然后第二个调用(form Submit)可能会取消第一个调用(XMLHttpRequest)。 即使这种情况没有发生,由 XMLHttpRequest 调用的请求也只会发送 action 和 total_seconds 变量,因此当执行 PHP 脚本时,它找不到任何 submit_answer 变量和
if (isset($_POST['submit_answer'])) {
将跳到 else
分支和代码:
sleep(3);// wait 3 seconds incase the database is slow or to allow time for data to transfer
$total_seconds = $_POST['total_seconds']; // Make sure to sanitize the input
$data = array('time_taken' => $total_seconds);
$where = array('user_name' => $user_name);
$wpdb->update($table_name, $data, $where);
不会被执行(sleep(3)无论如何都是不必要的)。
请记住,任何人都可以篡改数据,无论是通过 XMLHttpRequest 还是通过 form Submit 发送,我建议您采用这种方法:
管理此功能的 JS 代码部分将导致:
// Save the totalSeconds in the database
const submitButton = document.querySelector('input[name="submit_answer"]');
if (submitButton) {
submitButton.addEventListener('click', function() {
clearInterval(stopwatchInterval); // Stop the stopwatch interval when the submit button is clicked
console.log("Total seconds: " + totalSeconds); // Log the total number of seconds in the console
// ADDED CODE
const input = document.createElement("input");
input.setAttribute("type", "hidden");
input.setAttribute("name", "total_seconds");
input.setAttribute("value", totalSeconds);
this.form.appendChild(input);
/* REMOVED CODE
// send the total seconds to my php code snippet
var ajaxurl = '<?php echo admin_url('admin-ajax.php'); ?>'; // Get the correct URL path to admin-ajax.php
var xhr = new XMLHttpRequest();
xhr.open('POST', ajaxurl, true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send('action=save_total_seconds&total_seconds=' + totalSeconds);
*/
});
}
无论如何,请从 PHP 中删除
sleep(3)