Attempt to read property on null 해결

Laravel에서 Attempt to read property on null이 나온 이야기



기사 내용



본 기사에서는 Laravel에서 자작의 인증 기능을 구현하고 있을 때, 본제의 에러가 나왔으므로, 그 해결 방법을 새롭게 하겠습니다.

개발 환경



Laravel 8.22.1
PHP: 8.0.1
MySQL: 8.0.23
MacOS: 11.1 ( Big Sur )

하고자 하는 일



보기에서 입력 양식과 데이터베이스에 companies 테이블을 만들고,
사용자로부터 입력된 값과 테이블에 저장되어 있는 데이터(컬럼:company_id)와 일치하는 것이 있으면 페이지를 천이시킨다.
일치하는 것이 없으면 간단한 오류 메시지를 반환합니다.

테이블



○○_create_companies_table.php
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateCompaniesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('companies', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('company_id')->unique();
            $table->string('name');
            $table->timestamps();
        });
    }

이번 인증에 이용한 것은 company_id 컬럼만의 간단한 것.

블레이드



login.blade.php (일부)
<div class="cpylogin-block">
  <form action="/company/login" method="post">
    <label for="company_id">会社/団体ID</label>
    <input type="text" name="company_id" value="{{ old('company_id') }}" placeholder="ID" required>
    <div class="btn-area">
      <button>ログイン</button>
    </div>
    {{ csrf_field() }}
  </form>

양식의 입력값도 1개만. input 태그의 name 속성을 company_id로 한다.
덧붙여서 login 블레이드는 컨트롤러의 기술보다, route/web.php 로부터 호출하고 있습니다.

컨트롤러



LoginController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Models\Company;

class CpyLoginController extends Controller
{
    //
    public function index(Request $request)
    {
        return view('pages.cpylogin');
    }

    public function post(Request $request)
    {
        // Companyモデルからcompany_idで情報を検出→オブジェクト化
        $company = Company::where('company_id', $request->company_id)->first();
        $msg = ['msg' => '入力されたIDは存在しません'];

        if ($request->company_id === $company->company_id) {
            return redirect()->route('usrlogin');
        }
        else {
            return view('pages.cpylogin', $msg);
        }
    }
}

· LoginController의 post 메소드로 인증 기능이 움직이도록 기술.
Auth를 사용하고 있지 않은데, 자주 있는 user 모델로의 로그인 기능이 아닌 것을 미리 파악해 주세요.

· if 문장에서 양식의 입력 태그에 입력 된 값이 company 모델의 company_id 열에 저장된 데이터와 일치하는 것이 있으면 usrlogin 뷰를 표시합니다.

실행





Attempt to read property "company_id"on null 와 에러가 된다.
일본어 번역하면, ““company_id” 프로퍼티를 null인데 읽으려고 하고 있다.”의 의미(조금 어긋나 있을지도).

원인



오류의 원인은 컨트롤러에서 company 모델을 호출하는 설명에있었습니다.

LoginController.php

--- 省略 ---

    public function post(Request $request)
    {
        // Companyモデルからcompany_idで情報を検出→オブジェクト化
        $company = Company::where('company_id', $request->company_id)->first();

--- 省略 ---

    }


\$company 변수의 정의를 잘못했습니다.
\$company 변수를\$request->company_id와 양식에 입력된 값과 연결하는 대신,
company 테이블에 존재하는 모든 데이터를 오브젝트화한 것으로 해야 했습니다.

해결책



그렇다고 해서\$company 변수의 정의를 아래와 같이 재작성하면 해결했습니다.

LoginController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Models\Company;

class CpyLoginController extends Controller
{
    //
    public function index(Request $request)
    {
        return view('pages.cpylogin');
    }

    public function post(Request $request)
    {
        $validate_rule = $request->validate([
            'company_id' => ['required']
        ]);

        // Companyモデルからcompany_idで情報を検出→オブジェクト化
        $company = Company::all()->first();
        $msg = ['msg' => '入力されたIDは存在しません'];

        if ($request->company_id === $company->company_id) {
            return redirect()->route('usrlogin');
        }
        else {
            return view('pages.cpylogin', $msg);
        }
    }
}

\$company 변수를 Company 모델에서 모두 꺼내 오브젝트화한 데이터로 정의하는 것으로 잘 되었습니다.

좋은 웹페이지 즐겨찾기