2017-02-20 6 views
0

내 질문이 친구가 DataViewer와 코드가 비슷한 다음에 특성을 생성 Data Viewer with Laravel 5.3 and Vue.js이 코드는 어떻게 그리고 왜 작동합니까?

을 기반으로합니다

trait DataViewer 
{ 
    // $query should be a Query Builder 
    public function scopePaginateAndOrder($query) 
    { 
     // Validation ... 

     // Where, Pagination, Order etc ... 
     return $query->where('foo', 'like', 'bar'); 
    } 
} 

이제 검색 기능을 추가 할 수있는 설득력 모델에서이 특성을 사용할 수 있습니다.

class Customer extends Model 
{ 
    use DataViewer; 
} 

모든 보통의 물건, 특별한 아무것도 ... 하지만 그때 나는 아직 PHP에서 볼 did't 일부 "마법"이있다. 컨트롤러에서

그는

$model = App\Customer::paginateAndOrder(); 

마지막 코드 같은 것을 내가 이해할 수없는 여러 측면을 가지고 않습니다 않습니다.

  1. 왜 내가 ::을 사용하여 정적 메소드 방식이 아닌 정적 메서드를 호출 할 수 있습니까?
  2. 이유 이름에서 범위을 생략 할 수 있습니까?
  3. 쿼리 작성기 개체를 매개 변수로 전달할 필요는 없습니다. 그러면 특성이 페이지 매김/순서를 원하는 모델에 "알"는 방법은 무엇입니까?

도움의 도움을 주셔서 감사합니다!

+0

'나는 매개 변수로 쿼리 작성기 개체를 전달할 필요가 없습니다. '및'$ 쿼리는 쿼리 작성자 여야합니다.'는 나쁜 습관입니다 (해야 /해야// ...). 왜 함수는 다음과 같이 보이지 않습니다 :'public function scopePaginateAndOrder (QueryBuilder $ query = null)'? '1'에서는 PHP에서'Strict standards : Non-static method'라는 메모/경고를 던지 겠지만, meothod가 호출됩니다. '2.'는 무엇을 의미합니까? – JustOnUnderMillions

+0

그리고 덧붙여서 : 일단 'scopePaginateAndOrder'에 대해서 이야기하고 나서'paginateAndOrder'에 관해서는 diff가 2 개있을 것입니다. 라는 메서드는 동일하지 않습니다. 따라서 scopePaginateAndOrder()를 호출 할 때 'scope'를 생략 할 수 없습니다. 다른 뭔가가 당신의 논리에서 잘못되어 가고 있습니다. – JustOnUnderMillions

+0

좋아, 힌트를 쓰지 않는 매개 변수는 실제로 나쁜 습관이다. 나는 위의 링크 된 비디오에서 복사하여 붙여 넣기 만했다. 그리고 네, 나는 scopePaginateAndOrder() 대신에 paginateAndOrder()를 사용해야합니다. 그렇지 않으면 예외가 발생합니다 – Qobus

답변

1

Laravel은 PHP의 마법 방법 중 일부를 사용합니다 (이 경우 __call()__callStatic). 정적 방법 중 하나 존재하거나 (있는 경우)를 호출하는 클래스의 __callStatic() 방법에 위임됩니다 액세스하지 않음을 호출하는 경우 callStatic

http://php.net/manual/en/language.oop5.overloading.php#object.callstatic

. 사실 __call()과 인스턴스 메소드도 마찬가지입니다. 당신이 Illuminate\Database\Eloquent\Model를 보면

당신은 찾을 수 있습니다 : 위의에서

/** 
* Handle dynamic method calls into the model. 
* 
* @param string $method 
* @param array $parameters 
* @return mixed 
*/ 
public function __call($method, $parameters) 
{ 
    if (in_array($method, ['increment', 'decrement'])) { 
     return call_user_func_array([$this, $method], $parameters); 
    } 

    $query = $this->newQuery(); 

    return call_user_func_array([$query, $method], $parameters); 
} 

/** 
* Handle dynamic static method calls into the method. 
* 
* @param string $method 
* @param array $parameters 
* @return mixed 
*/ 
public static function __callStatic($method, $parameters) 
{ 
    $instance = new static; 

    return call_user_func_array([$instance, $method], $parameters); 
} 

, __callStatic는 다음 모델의 new 인스턴스를 생성하고 시도하고 그 인스턴스의 메소드를 호출 불려 갔을 경우, 그래서 App\Customer::paginateAndOrder()에 전화하면 paginateAndOrder()을 인스턴스 메서드로 호출합니다.

(포함되지 않음 incrementdecrement) __call() 메서드는 모델에서 시도하여 해당 메서드를 Illuminate\Database\Eloquent\Builder에 호출합니다. Builder 다음 그 안에 다음과 같은있다 그것의 자신의 __call() 방법이 있습니다

if (method_exists($this->model, $scope = 'scope' . ucfirst($method))) { 
    return $this->callScope([$this->model, $scope], $parameters); 
} 

callScope

다음 바로 실제 scopePaginateAndOrder 전화를하고를 통해 Builder를 전달합니다.

희망이 도움이됩니다.

1

이것은 Laravel의 마법입니다. php이 아닙니다.

Laravel 내가 :: 사용하여 정적 메소드의 방식이 아닌 정적 메소드를 호출 할 수 있습니다 왜 magic functions

  1. 으로 알려진 것을 사용한다? 당신이 각각 존재하지 않는 비 정적 정적 함수를 호출 할 때 내가 여기 __call()__callStatic() 만 나열이가이 함수가 호출됩니다

..의 슈퍼 클래스입니다 Illuminate\Database\Eloquent\Model에 따라서

모든 모델에서이 작업을 수행하므로 link을 확인하십시오.

  1. 왜 메소드 이름에서 범위를 생략 할 수 있습니까? '

간단히 말해서 Laravel은 기능을 나타내는 함수 이름의 접두어를 생략 할 수 있습니다. 예. 귀하의 경우에 scope 접두어가 붙어 있습니다. 접두어가 발견 될 때까지 특정 접두어를 계속 추가합니다. 자세히 살펴 보려면 code을 읽으십시오.

  1. 매개 변수로 쿼리 작성기 개체를 전달할 필요가 없습니다.그래서 어떻게 특성은 어떤 모델에 내가 주문/페이지를 매기 싶다 "알고있다"않습니다
나는이 Laravel IoC 컨테이너와 dependcy 주입에 기인 생각

..

참고 : Q3는 더 많은 연구를 필요로 주입시기는 &입니다.