질문을 삭제하지 말아주세요.!
 
1
0
-1

Todo 리스트 애플리케이션을 만들어 보려고하는데 컨트롤러에서 DB에 값 저장시 엘러퀀트ORM 방식?으로 해보려 합니다.

DB파사드나 쿼리빌더로는 insert가 잘 되었는데 아래처럼 모델 인스턴스를 참조하거나 모델파사드방식(::create가 모델 스태틱멤버인가요?) 사용시  아래와 같은 에러가 노출되네요. tinker로 App\Todo::get()하면 잘 되고 실제 모델파일도 잘 있습니다.

FatalThrowableError in TodoController.php line 19

Class 'App\Http\Controllers\Todo' not found

Todo 컨트롤러 코드

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use DB;

class TodoController extends Controller
{
    public function store(Request $request)
    {
          $title = $request->input('title');

          $todo = new Todo();
          $todo->title = $title;
          $todo->save();

          // Todo::create([
          //     'title'=>$title
          // ]);
    }
}

php기초 문법이 좀 부실하여 기본적인 부분을 놓치고 있는 것 같은데 왜 not found가 뜰까요?

도움 부탁드립니다 ㅜ


    CommentAdd your comment...

    4 answers

    1.  
      2
      1
      0

      네임스페이스를 학습하시면 됩니다.


      namespace 가 선언된 파일 내에서 \로 시작하지 않으면 상대경로 처럼 작동하고 \ 로 시작하면 절대경로처럼 사용하게 됩니다.

      현재파일의 네임스페이스가 아래와 같이 선언되어 있기 때문에

      namespace App\Http\Controllers;

      이 상태에서 Todo 클래스를 사용하면 App\Http\Controllers\Todo 를 찾게 됩니다.

      실제로 찾아서 사용해야 하는 클래스는 App\Todo 클래스이기 때문에 아래와 같이 사용하시면 정상 작동 할 것입니다.

      \App\Todo::create([
          'title'=>$title
       ]);


      Todo 클래스를 자주 사용해야하는 경우 use 구문을 사용하면 매번 풀네임스페이스를 써주지 않아도 되서 더 편리합니다.

      1. 장재원

        스코프?단위가 네임스페이스로 정해지는군요.

        네임스페이스 외부의 다른 모듈?(클래스)를 참조하려면 임포트(use)를 명시적으로 지정해줘야 하나보네요 ㅎㅎ

        감사합니다!

      CommentAdd your comment...
    2.  
      4
      3
      2
      해보진 않았지만, 상단에
      use \Todo;
      
      구문을 추가하면 될것 같습니다.

      PHP기초 문법이라기 보다는 라라벨의 파사드의 경험이 쌓이면 쉽게 이해하실수 있을것같습니다.


      Class 'App\Http\Controllers\Todo' not found


      1차적인 에러 원인은 동일한 네임스페이스인 'App\Http\Controllers'에 모델인 Todo 가 없으니 그렇습니다. (당연하죠?)

      파사드로 사용했을 경우에 어디에서든 네임스페이스 길게 쓰지 않고 사용할 수 있습니다. 사실은 최상단 루트 네임스페이스인데요.

      정확히 표현하자면 \Todo 가 됩니다.

      (#라라벨 파사드의 특징일 뿐 파사드의 주요한 목적이 네임스페이스를 줄이기위함은 아닙니다)


      이쯤해서 납득하지 못할것 같은 것은, 다른 코드에서 분명 use 구문이나 \Todo 처럼 쓰지않고 Todo::create() 했는데 왜 여기서만 문제가 되는건가? 라는것인데요.

      Controllers 라는 네임스페이스 내부에 있기 때문에 루트네임스페이스부터 쓰지 않을 경우에 현재 클래스와 동일한 네임스페이스로 간주되기 때문입니다. 같은 맥락으로 \App\My\A\B\C\D\E\MyClass 안에서 Todo를 동일하게 쓰면  \App\My\A\B\C\D\E\Todo 를 찾게 됩니다.

      (#이건 PHP의 네임스페이스의 특성이라고 볼수있습니다.)


      그러니, 라라벨 파사드를 다른 클래스에서 사용할 때에는 use 구문을 사용하거나, 언제 어디서나 \Todo::create() 처럼 \를 붙여서 전체경로로 인지하도록 하게 하는 것을 주의해야합니다.

      (#이것은 FQN 이라고 부릅니다)


      좀 더 이해하시려면 #으로 표시해둔 부분은 별도로 학습하시길 권장합니다.

      1. 이현석

        앗 답변 작성하는 중이었는데 선수 뺏겼네요 ㅎㅎㅎ

      CommentAdd your comment...
    3.  
      1
      0
      -1

      제 책에도 네임스페이스 항목이 있는데 온라인 문서 공유해 드립니다. (https://www.lesstif.com/pages/viewpage.action?pageId=24445772)

        CommentAdd your comment...
      1.  
        1
        0
        -1

        해당 모델을 참조하는 컨트롤러파일 상단에 

        use App\Todo;

        추가해주니 잘 동작은 하는데 use App; 만하면 동작하지 않네요.

        그러면 App하위의 필요한 모듈?은 다 선언해줘서 가져와야하는건가 싶은데 이렇게 작성하는게 맞는 방법인가요?

        php기초 문법을 좀 보려하는데 적절한 키워드를 알려주시면 감사하겠습니다!

        1. taelkim

          App\Todo가 실제 모델이 위치한 것인가보네요.

          이건 파사드를 사용하는게 아니라 실제 모델을 찾는것 같습니다.

          -

          App하위의 모든 모듈은 선언해서 가지고 오는것이 맞는가? => 그렇습니다.

          (자바와 같은 언어에서는 use App.* 처럼 선언하여 다가져오는 것이 가능합니다. 하지만 명시적이지 않아서 좋지 못한 습관으로 알려져 있습니다. php는 이러한 선언방식 자체를 허용하지 않습니다.)

          namespace , use statement 를 좀 더 학습하시면 도움이 될것 같습니다.


        2. 김주원

          taelkim PHP7 버전 부터 다음 문법이 가능합니다.

          use App\{Todo, User, Foo as F};

          장재원 조급하게 생각하지 마시고, 책이나 온라인 강의를 통해 차근차근 배우시기 바랍니다. 이 비디오 추천드립니다. https://laracasts.com/series/object-oriented-bootcamp-in-php

        3. 장재원

          도구를 빨리 손에쥐고 싶은 마음에 기초가 중요한지 알면서도 애자일?하게 일단 질러보는 중인데 역시 기초가 중요하네요 ㅎㅎ 이렇게 하면서 알려주시는 키워드들로 학습을 하도록 하겠습니다. 물론 어느정도 결과가 나오면 처음부터 php기초 한 번 다지려 합니다. (뇌를자극하는 php, 모던php 책활용) 잘 사용하지 않았던 언어라 키워드 접근에 서툰데 앞으로도 잘 부탁드립니다!

          조만간 모임에서도 뵐 수 있었음 좋겠네요 .

          김주원taelkim님 감사합니다.

        CommentAdd your comment...