我无法将数据从 JavaScript 发送到 PHP 代码,因此我可以将其保存在数据库(Wordpress 网站)中

问题描述 投票:0回答:1

总结:我的在线网站有一个秒表,该秒表使用 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'];

javascript php ajax database
1个回答
0
投票

您似乎正在尝试管理两个不同的请求(XMLHttpRequest和来自浏览器的表单提交),就好像它们是单个请求一样。 事实上,XMLHttpRequest将生成第一个请求,并且在表单提交之后立即生成另一个请求。

从您的代码中,我假设XMLHttpRequest的端点与表单提交相同。然后第二个调用(form Submit)可能会取消第一个调用(XMLHttpRequest)。 即使这种情况没有发生,由 XMLHttpRequest 调用的请求也只会发送 actiontotal_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 发送,我建议您采用这种方法:

  • 删除 XMLHttpRequest
  • 动态创建一个包含经过时间的隐藏字段

管理此功能的 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)

© www.soinside.com 2019 - 2024. All rights reserved.