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

A라는 컨트롤러에서 B라는 컨트롤러의 check 라는 함수를 쓰고 싶습니다.

 

어떻게 하면 쓸 수 있을까요??

    CommentAdd your comment...

    5 answers

    1.  
      1
      0
      -1

      Check라는 함수의 용도가 무엇인지 몰라, 정확한 답변을 드릴 수 없지만,

      다른 Controller의 함수를 호출하는 데는 몇가지 방법이 있습니다.

      http://stackoverflow.com/questions/30365169/access-controller-method-from-another-controller-in-laravel-5에 있는 상황에 맞게 내용을 정리해 보았습니다.

       

      1. \App::call() 사용

      개인적으로 다른 Controller의 함수를 직접 호출하는 것은 선호하지 않지만, 부득이하게 사용하셔야한다면, 

      \App::call('<application name space>\Http\Controllers\BController@check');

       

      또는 

      app('<application name space>\Http\Controllers\BController')->check();

       

      2. B controller 상속

      일반적인 OOP(Object Oriented Programming)에서 사용하는 상속을 쓰시는 것도 한 방법입니다.

      class AController extends BController {
          function b () {
             return check();
          }
      }

      이 경우에 BController의 필요없는 함수도 같이 상속받게 됩니다.

       

      3. Abstract Controller

      Check() 함수를 포함하는 상위 클래스를 생성하고, AController 와 BController에서 상속받으시면 됩니다.

       

      4. trait를 생성

      trait Checkable {
         public function check() {
         }
      }
       
      class AController {
         use Checkable;
      }
       
      class BController {
         use Checkable;
      }
      1. 헤이준

        저는 DbController 를 만들어서 안에 insert 함수를 생성했습니다.

         

        이 insert 함수를 IndexController 에서 사용하고 싶습니다.

        저는 올려주신 방법 중 4번 trait 를 하고 싶은데 어느 부분을 수정하면 될까요??

        namespace App\Http\Controllers;
        
        use DB;
        use Illuminate\Http\Request;
        
        class DbController extends Controller {
         
        	public function insert($table, $data) {
        
            	$query = DB::table($table)->insert([$data]);
        
            	return $query;
        
          	}
         
        }
      2. Junewon Park

        이 경우에는 trait보다는 Repository 클래스나 별도의 Business Logic을 담당하는 클래스를 생성하시는 것이 좋을듯합니다.

        Trait은 클래스하고 비슷하지만, 간단한 함수를 묶어서 개발자가 재사용하기 편하도록 고안된 문법입니다. 그래서 Trait은 님이 구현하고자 하는 insert() function을 수행하기에는 제한이 많습니다.

        부득이하게 Controller Level의 클래스에 DB관련 함수를 넣고 싶으시다면, 3번에서 처럼 현재 구현해 놓으신 DbController 클래스를 다른 Controller 클래스에서 상속하시는 것이 좋을 듯합니다.

      3. 김주원

        질문하신 내용은 Junewon Park님이 말씀하신대로 리포지토리 패턴입니다. 리포지토리를 쓰는 순간 폴백이라든가, 관심사의 분리, 중복 제거 측면에서 훨씬 좋은 코드가 되지만, 반면 가독성이 떨어지고 복잡도가 높아집니다. 서비스가 크다면 당연히 고려할만합니다. 닭 잡는데 소잡는 칼 쓰지 말았으면 하구요, 적어도 커머스 서비스 정도 만드실 때 고려해 보시면 좋겠어요. 그리고 리포지토리 패턴은 웹 검색해서 목적에 맞는 지 확인하세요. 아래 코드는 가장 간단한 리포지토리 Pseudo Code 입니다 (역시 테스트는 안 해 봤습니다).

         

        <?php
        
        abstract class BaseRepository
        {
        	protected $model;
        
        	public function __construct()
        	{
        		$this->model = $this->model();
        	}
        
        	abstract public function model();
        
        	public function insert(array $data)
        	{
        		// $data 유효성 검사 또는 Normalization 필요
        		return this->model->create($data);
        	}
        
        	public function update(array $data)
        	{
        		return $this->model->update($data);
        	}
        
        	// ...
        }
        
        class FooRepository extends BaseRepository
        {
        	public function model()
        	{
        		return new Foo;
        	}
        
        	public function findById(int $id)
        	{
        		$this->model->findOrFail($id);
        	}
        
        	// ...
        }
        
        class FooController extends ...
        {
        	protected $repo;
        
        	public function __construct(FooRepository $repo)
        	{
        		$this->repo = $repo;
        	}
        
        	public function createFoo(\Illuminate\Http\Request $request)
        	{
        		return $this->repo->insert($request->all());
        	}
        
        	// ...
        }
      4. 헤이준

        리포지토리 패턴보다 3번을 추천하셔서 3번을 사용하려 합니다.

        근데 제가 잘 한건지 확인 부탁드리겠습니다.


        DbController

        namespace App\Http\Controllers;
        
        use DB;
        use Illuminate\Http\Request;
        
        abstract class DbController extends Controller {
         
        	public function insert($table, $data) {
        
            	$query = DB::table($table)->insert([$data]);
        
            	return $query;
        
          	}
         
        }

         

        IndexController

        namespace App\Http\Controllers;
        
        use DB;
        use App\Http\Controllers\Controller;
        use App\Http\Controllers\DbController;
        use Illuminate\Http\Request;
        
        class IndexController extends DbController {
        
          public function index() {
        
            $result = insert('test', array('text' => "hi"));
        
            return view('index', ['result' => $result]);
        
          }
        
        }
        
        

         

        객체지향적 부분이 어려워서 난항을 겪고 있는데

        정말 상세하게 알려주셔서 감사합니다.

      5. Junewon Park

        객체지향은 개념은 모든 언어에서 다들 비슷하고, 문법에서만 차이가 있습니다.

         

        아래 부분만 수정을 해주시면 될듯합니다.

        // From
            $result = insert('test', array('text' => "hi"));
        
        // To 
            $result = $this->insert('test', array('text' => "hi"));

        PHP에서는 insert()만 사용했을 경우, 일반함수를 찾기때문에 정의가 안 되어 있는 것으로 오류메시지를 반환 할 겁니다.

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


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


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

          모든 컨트롤러가 써야 하는 메서드라면 \App\Http\Controllers\Controller 에 check() 메서드를 넣으시면 되고요. 그렇지 않고, 일부 컨트롤러만 check() 메서드를 사용한다면 Trait를 이용하시면 깔끔합니다.

           

          // 네임스페이스는 전부 생략합니다.
           
          trait Checkable 
          {
          	public function check()
          	{
          		// 로직은 여기에...
          	}
          }
           
          class FooController extends ...
          {
          	use Checkable;
           
          	public function foo()
          	{
          		$this->check();
          	}
          }
           
          class BarController extends ...
          {
          	use Checkable;
          
          	public function bar()
          
          	{
          		$this->check();
          	}
          }
          1. 헤이준

            A 라는 컨트롤러 파일에서  trait 를 넣고 B라는 컨트롤러 파일에서

            class 아래에 use trait 헀던 이름 을 쓰면 되는건가요??

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