DivMan,
вы же как-то тренировались с базами и знаете, что в разумной БД уникального идентификатора равного 0 не будет. Если опираясь на это, делать также и с применением массива, то упрощается проверка мусора/опасного.
Первичный индекс вашего массива данных этому соответствует. Правда в РНР можно поступать проще - задать только первому элементу индекс, остальные получат его по возрастанию автоматически, то есть:
$questions = [
1 => [
'question' => 'Сколько будет 2+2?',
'variants' => ['2', '4', '6', '4.0'],
'answers' => ['1', '3']
],
[
'question' => 'Сколько будет 6+6?',
'variants' => ['66', '6', '12'],
'answers' => ['2']
],
.....
А вот дальше все неверно. У вас есть записи в базе, которые имеют уникальные идентификаторы и названия. По этим данным вы строите список, что в качестве value будут содержать опции списка? Можно быть уверенным, что идентификаторы, которые не имеют нулевого значения.
А почем в массиве данных не так - [1=>'2', '4', '6', '4.0']?
Именование полей цифрами, это плохо, могут быть и косяки, вообще имена должны начинаться с буквы. Для построения формы по вашим данным требуется максимум два массива, причем вы определяет данные, и догадываться проверкой что они пришли это плохо, и виноват у вас в этом как раз лишний цикл. А должно быть
Первый цикл - обход массива $questions как ключ=>значение, вложенный цикл как значения берет из значения ключ 'question' и выводит метку поля, берет ключ 'variants' и выводит кнопки формы именуя их как, например, variants[первичный ключ массива $questions] а value индексы variants, которые начинаются с 1. Зачем тут третий цикл?
И проверка буде без всяких if(count($_GET)-1 < count($questions)), что вообще ни к чему, условием будет if(count($_GET) == count($questions)), а для этого не давайте имя кнопки отправки формы, она у вас одна в форме и серверу совсем не нужна. Достаточно проверить наличие ключа variants в массиве $_GET. А проверить правильно или нет, два цикла совсем не нужны, достаточно одного.