Answer the question
In order to leave comments, you need to log in
Error Notice: Undefined variable: how to fix?
I'm writing a testing system and this error comes out
In the first test, there is no error, and everything is displayed
I don't know how to fix it, I'm new to php, please help. Here is the code.
<?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/[email protected]/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>
$(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!');
}
});
});
});
Answer the question
In order to leave comments, you need to log in
Such notices are issued when accessing undeclared variables. For example, $count_questions is only defined if $_GET['test'] is not empty and the test itself was found. To avoid this, you need to define an initial value somewhere at the beginning, for example, $count_questions = 0 before checking if (!isset($_GET['test'])). The same is true for the rest of the variables: either check for isset all the time, or set the initial values.
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question