@tokyodead

Ошибка Notice: Undefined variable: как исправить?

Пишу систему тестирования и выходит вот такая ошибка
60cf6ddf1d15d938343431.png
В первом тесте, ошибки нет, и всё выводится
60cf6e10a4e48336960864.png
Не знаю как исправить, я новичок в php, помогите, пожалуйста. Вот код.
<?php
session_start();

?>
<?php
ini_set("display_errors", 1);
error_reporting(-1);
require_once 'vendor/connection.php';
require_once 'function/functions.php';



if( isset($_POST['test']) ) {
  $test = (int)$_POST['test'];
  unset($_POST['test']);
  $result = get_correct_answers($test);
  if( !is_array($result) ) exit('Ошибка!'); // Если такого теста(не массив) не существует, выведет ошибку
  //Данные теста
  $test_all_data = get_test_data($test);
  $test_all_data_result = get_test_data_result($test_all_data, $result);
  // print_r($test_all_data_result);
  echo print_result($test_all_data_result);
  die;
}

//Список тестов
$tests = get_tests();
if( isset($_GET['test']) ) {
  $test_id = (int)$_GET['test'];
  $test_data = get_test_data($test_id);
  print_arr($test_data);
  if( is_array($test_data) ) {
    $count_questions = count($test_data);
    $pagination = pagination($count_questions, $test_data);
  }
}
?>

<!DOCTYPE html>
<html lang="ru" dir="ltr">
<head>
<meta charset="utf-8">
<title>Система тестирования</title>
<link rel="stylesheet" href="/css/style.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css">
</head>
<body>
<div class="wrap">
  <?php if( $tests ): ?>
    <div class="mt-5">
      <p class="sess"><?= $_SESSION['user']['full_name']; ?></p>
      <h3>Варианты тестов</h3>
    </div> <!-- mt-5  -->
    <?php foreach ($tests as $test): ?>
      <p><a href="?test=<?=$test['id']?>" ><?=$test['test_name']?></a></p>
    <?php endforeach; ?>

    <br><hr><br>
  <div class="content">
    <?php if( isset($test_data) ): ?>
        <p>Всего вопросов: <?=$count_questions?></p>
        <?=$pagination?>
        <span class="none" id="test-id"><?=$test_id?></span>
    <div class="test-data">

      <?php foreach($test_data as $id_question => $item): //получаем каждый конкретный вопрос + ответы. ?>
        <div class="question" data-id="<?=$id_question?>" id="question-<?=$id_question?>">
          <?php foreach($item as $id_answer => $answer): //Проходимся по массиву вопрос ответы. ?>
              <?php if( !$id_answer ): //Выводим вопрос ?>
                <p class="q"><?=$answer?></p>
              <?php else: //Выводим варианты ответов ?>
                <p class="a">
                  <input type="radio" id="answer-<?=$id_answer?>" name="question-<?=$id_question?>" value="<?=$id_answer?>">
                  <label for="answer-<?=$id_answer?>"><?=$answer?></label>
                </p>
              <?php endif;  //$id_answer ?>
          <?php endforeach ?>
        </div><!-- .question -->
      <?php endforeach; //test_data ?>

    </div> <!-- .test_data  -->
    <div class="buttons">
      <button class="btn btn-success mb-5" id="btn">Закончить тест</button>
    </div>

  <?php else: //isset(test_data) ?>
    Выберите тест
  <?php endif; //isset(test_data) ?>

  </div> <!-- .content  -->
  <?php else: //$tests ?>
    <h3>Нет тестов</h3>
  <?php endif; //$tests ?>
</div> <!-- .wrap -->

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="/js/scripts.js"></script>

</body>
</html>
вот функции
<code lang="php">
<?php

//Посмотреть массив
function print_arr($arr) {
  echo '<pre>' . print_r($arr, true) . '</pre>';
}


// Получить список тестов
function get_tests() {
  global $connection;
  $query = "SELECT * FROM test WHERE enable = '1'";
  $res = mysqli_query($connection, $query);
  $data = array();
  while($row = mysqli_fetch_assoc($res)) {
    $data[] = $row;
  }
  return $data;
}

//Получение данных теста

function get_test_data($test_id) {
  if( !$test_id ) return;
  global $connection;
  $query = "SELECT q.question, q.parent_test, a.id, a.answer, a.parent_question
  FROM questions q
  LEFT JOIN answers a
    ON q.id = a.parent_question
  LEFT JOIN test
    ON test.id = q.parent_test
      WHERE q.parent_test = $test_id AND test.enable = '1'"; // test enable значени '1' значит что тест активный.

  $res = mysqli_query($connection, $query);
  $data = null;
  while($row = mysqli_fetch_assoc($res)) {
    if( !$row['parent_question'] ) return false; // Если у вопроса нет вариантов ответа, вернёт false, для теста которого нет вернёт NULL
    $data[$row['parent_question']][0] = $row['question'];
    $data[$row['parent_question']][$row['id']] = $row['answer'];
  }
  return $data;
}

// Пагинация
function pagination($count_questions, $test_data) {
  $keys = array_keys($test_data);
  $pagination = '<div class="pagination">';
  for($i = 1; $i <= $count_questions; $i++) {
    $key = array_shift($keys);
    if( $i == 1 ) {
      $pagination .= '<a class="nav-active" href="#question-' . $key . '">' . $i . '</a>';
    }else{
      $pagination .= '<a href="#question-' . $key . '">' . $i . '</a>';
    }
  }
  $pagination .= '</div>';
  return $pagination;
}

//получение id вопрос/ответ
function get_correct_answers($test) {
  if( !$test ) return false;
  global $connection;
  $query = "SELECT q.id AS question_id, a.id AS answer_id
    FROM questions q
    LEFT JOIN answers a
      ON q.id = a.parent_question
    LEFT JOIN test
      ON test.id = q.parent_test
        WHERE q.parent_test = $test AND correct_answer = '1' AND test.enable = '1'";

  $res = mysqli_query($connection, $query);
  $data = null;
  while($row = mysqli_fetch_assoc($res)) {
    $data[$row['question_id']] = $row['answer_id'];
  }
  return $data;
}

function get_test_data_result($test_all_data, $result){
	// заполняем массив $test_all_data правильными ответами и данными о неотвеченных вопросах
	foreach($result as $q => $a){
		$test_all_data[$q]['correct_answer'] = $a;
		// добавим в массив данные о неотвеченных вопросах
		if( !isset($_POST[$q]) ){
			$test_all_data[$q]['incorrect_answer'] = 0;
		}
	}

	// добавим неверный ответ, если таковой был
	foreach($_POST as $q => $a){
		// удалим из POST "левые" значения вопросов
		if( !isset($test_all_data[$q]) ){
			unset($_POST[$q]);
			continue;
		}

		// если есть "левые" значения ответов
		if( !isset($test_all_data[$q][$a]) ){
			$test_all_data[$q]['incorrect_answer'] = 0;
			continue;
		}

		// добавим неверный ответ
		if( $test_all_data[$q]['correct_answer'] != $a ){
			$test_all_data[$q]['incorrect_answer'] = $a;
		}
	}
	return $test_all_data;
}

// print result
function print_result($test_all_data_result) {
  $all_count = count($test_all_data_result); // кол-во вопросов
  $correct_answer_count = 0; // кол-во верных ответов
  $incorrect_answer_count = 0; // кол-во неверных ответов
  $percent = 0; // Процент верных ответов

  // Подсчет результатов
  foreach($test_all_data_result as $item) {
    if( isset($item['incorrect_answer']) ) $incorrect_answer_count++;
  }
  $correct_answer_count = $all_count - $incorrect_answer_count;
  $percent = ceil($correct_answer_count / $all_count * 100);
  //Вывод результатов
  $print_res = '<div class="questions">';
  $print_res .= '<div class="count-res>"';
  $print_res .= "<p>Всего вопросов: <b>{$all_count}</b></p> ";
  $print_res .= "<p>Правильных ответов: <b>{$correct_answer_count}</b></p> ";
  $print_res .= "<p>Неверных ответов: <b>{$incorrect_answer_count}</b></p> ";
  $print_res .= "<p>% верных овтетов: <b>{$percent}</b></p> ";
  $print_res .= '</div>';
  $print_res .= '</div>';
  return $print_res;
}
?>

</code>

Вот JS
$(function() {
  $('.test-data').find('div:first').show();

  $('.pagination a').on('click', function() {
    if( $(this).attr('class') == 'nav-active' ) return false;

    var link = $(this).attr('href'); // Ссылка на текст вкладки для показа
    var prevActive = $('.pagination > a.nav-active').attr('href'); // Ссылка на текст пока что активной вкладки

    $('.pagination > a.nav-active').removeClass('nav-active'); // Удаляем класс активной ссылки
    $(this).addClass('nav-active'); // Добавляем класс активной вкладки

    // скрываем показываем вопросы

    $(prevActive).fadeOut(100, function() {
      $(link).fadeIn();
    })
    return false;
  });

  $('#btn').click(function() {
    var test = +$('#test-id').text();
    var res = {'test':test};


    $('.question').each(function() {
      var id = $(this).data('id');
      res[id] = $('input[name=question-' + id + ']:checked').val();
    });

    $.ajax({
			url: '/main.php',
			type: 'POST',
			data: res,
			success: function(html){
				$('.content').html(html);
			},
			error: function(){
				alert('Error!');
      }
    });
  });

});

Подскажите, как исправить, пожалуйста.
  • Вопрос задан
  • 1218 просмотров
Пригласить эксперта
Ответы на вопрос 1
XXXXPro
@XXXXPro
Fullstack Web developer
Такие notices выдаются при обращении к необъявленным переменным. Например, $count_questions определяется только в том случае, если $_GET['test'] не пустая и удалось найти сам тест. Чтобы этого не было, нужно где-то в начале определять начальное значение, например, $count_questions = 0 перед проверкой if (!isset($_GET['test'])). То же самое и с остальными переменными: либо всё время проверять на isset, либо задавать начальные значения.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы