You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel表单提交未选选项时如何将题目得分设为0?

Laravel在线测验系统结果存储问题

问题概述

开发Laravel在线测验系统,数据库包含users、questions、results三张表:

  • questions表存储题目名称、4个选项及正确选项
  • results表以user_id和question_id为外键,通过obtained_marks字段记录用户每题得分

需求:若用户未选择某道题的任何选项,需将该题的obtained_marks设为0。

尝试在存储results数据时使用!isset($options[$i])判断未选情况,但逻辑未生效,且触发**Undefined offset for options[$i]**错误。


原代码

Result Controller 原代码

public function store(Request $request){
    DB::beginTransaction();

    $questions=Question::all();
    
    if(empty($request->option)){

            foreach($questions as $question){

                $result = DB::table('results')->insert([
                'user_id' => auth()->user()->id,
                'question_id' => $question->id,
                'obtained_marks' => 0
            ]);
            
                
            }

            if ($result){
            DB::commit();
            return redirect()->route('login');
        }
        }
            $options= array_values($request->option);

            
                for($i=0; $i<count($questions); $i++){
                    
                    $result = DB::table('results')->insert([
                    'user_id' => auth()->user()->id,
                    'question_id' => $questions[$i]->id,
                    'obtained_marks' => (!isset($options[$i]) || $options[$i] != $questions[$i]->right_answer) ? 0:1
            ]);
        
            }

            if ($result){
                DB::commit();
                return redirect()->route('login');
            }

        
    }

视图原代码

<div class="container">
    <div class="row justify-content-center">
        <div class="col-8 mx-auto">
            <br>
            <div class="card">
                <div class="card-header">
                    <h1>Welcome to Quiz</h1>
                </div>
                <form class="form" action="{{ route('store') }}" method="POST">
                    @csrf
                    <div class="card-body">
                        @foreach ($questions as $question)
                            <p>{{ $loop->iteration }}. {{ $question->question }}</p>
                            <br>
                            <div class="row justify-content-center">
                                <div class="col-lg-6">
                                    <input type="radio" name="option[{{ $question->id }}]" id="option1"
                                        value="a" />
                                    <label for="option1"><button class="options" disabled>a.
                                            {{ $question->a }}</button></label>
                                </div>
                                <div class="col-lg-6">
                                    <input type="radio" name="option[{{ $question->id }}]" id="option2"
                                        value="b" />
                                    <label for="option2"><button class="options" disabled>b.
                                            {{ $question->b }}</button></label>
                                </div>
                                <br>
                                <br>
                                <div class="col-lg-6">
                                    <input type="radio" name="option[{{ $question->id }}]" id="option3"
                                        value="c" />
                                    <label for="option3"><button class="options" disabled>c.
                                            {{ $question->c }}</button></label>
                                </div>
                                <div class="col-lg-6">
                                    <input type="radio" name="option[{{ $question->id }}]" id="option4"
                                        value="d" />
                                    <label for="option4"><button class="options" disabled>d.
                                            {{ $question->d }}</button></label>
                                </div>
                            </div>
                            <hr>
                        @endforeach
                    </div>
                    <div class="card-footer">
                        <button type="submit" class="btn btn-primary flex-item">Submit</button>
                        <button type="reset" class="btn btn-primary flex-item">Reset</button>
                        <br>
                    </div>
                </form>
            </div>
        </div>
    </div>
</div>
@endsection

错误原因

  1. 视图中单选框的name属性为option[{{ $question->id }}],提交后$request->option是以题目ID为键的数组,仅包含用户选中的题目答案,未选中的题目不会出现在该数组中
  2. 使用array_values($request->option)会将数组键重置为连续数字,但题目总数和用户选中的题目数量可能不一致,循环遍历所有题目时,$options[$i]会超出数组长度,触发Undefined offset错误
  3. 开头的empty($request->option)判断仅处理完全未选任何题目的场景,无法覆盖部分题目未选的情况

修复方案

直接遍历所有题目,通过题目ID精准匹配用户的答案,无需依赖数组索引,同时统一处理全未选和部分未选的场景:

修复后的Result Controller代码

public function store(Request $request){
    DB::beginTransaction();

    $questions = Question::all();
    // 若用户未选任何题目,默认赋值为空数组
    $userAnswers = $request->option ?? [];

    foreach($questions as $question){
        // 判断用户是否选中当前题目,且答案是否正确
        $isCorrect = isset($userAnswers[$question->id]) && $userAnswers[$question->id] === $question->right_answer;
        $obtainedMarks = $isCorrect ? 1 : 0;

        DB::table('results')->insert([
            'user_id' => auth()->user()->id,
            'question_id' => $question->id,
            'obtained_marks' => $obtainedMarks
        ]);
    }

    DB::commit();
    return redirect()->route('login');
}

修复说明

  • 移除冗余的全未选判断逻辑,用$userAnswers = $request->option ?? []统一处理所有情况
  • 遍历每个题目时,通过$question->id直接访问用户的答案,彻底避免数组索引不匹配的问题
  • 逻辑更简洁清晰:用户未选中题目或答案错误时,obtained_marks设为0;答案正确时设为1

内容的提问来源于stack exchange,提问作者Umar Naeem

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 09:20:43