2017-10-25 16 views
0

내 질문에 대한 답변을 많이 찾고 잠시 동안 에 Stackoverflow하지만 여기서는 다른 곳에서도 대답을 찾지 못했습니다.CodeIgniter 드라이버 : __call() 메서드

어쨌든 CodeIgniter의 드라이버를 여러 번 사용해 보았지만 __call 메서드 때문에 자주 종료되었습니다. 예를 들어 설명하겠습니다.

는이 전 라는 드라이버가 있다고 가정 해 봅시다
class App extends CI_Driver_Library 
{ 
    public $CI; 
    public $valid_drivers; 

    public function __constructor() 
    { 
     $this->CI &= get_instance(); 
     $this->valid_drivers = ['users']; // An example. 
    } 
} 

지금 내가 그렇게 같은 사용자 드라이버가 (즉, 물론 CI_Driver_Library을 확장).

class App_users extends CI_Driver 
{ 
    private $CI; 

    public function __construct() 
    { 
     $this->CI =& get_instance(); 
     $this->CI->load->model('users_model'); 
    } 

    public function __call($method, $params = []) 
    { 
     if (method_exists($this, $method) 
     { 
      return call_user_func_array(array($this, $method), $params); 
     } 
     elseif (method_exists($this->CI->users_model, $method)) 
     { 
      return call_user_func_array(array($this->CI->users_model, $method), $params); 
     } 
     else 
     { 
      throw new BadMethodCallException("No such method: {$method}"); 
     } 
    } 
} 

내가이 App_users __constructor에 에게 Users_model를로드 할 (수 있지만 부모 : $의 CI은 액세스 할 수 없습니다하지만 난 관리). 이 드라이버의 방법 여부 또는 모델의 메소드를 호출하는 __call에게 방법을 사용하는 경우

내가 직면하고 문제이다. 불행히도, 그 마법 방법은 절대로 나에게 도움이되지 못했습니다. 가능한 경우 어떻게 할 수 있습니까? 그렇지 않은 경우 해결 방법이 있습니까?

미리 감사드립니다. 조건을 만족하지 않습니다 때문에 조건

if (method_exists($this, $method)... 

무의미 경우 모든

+0

'__call'구현을 알려주십시오. – DFriend

+0

@DFriend 나는 코드를 편집하고 구현을 추가했습니다. (제발 오해하지 마세요.) –

답변

1

먼저, 당신은 첫 번째를 알고 있어야합니다. __call은 클래스 메소드를 찾을 수 없을 때 마술처럼 트리거됩니다. method_exists($this, $method)이 TRUE가 아닌 것으로 이미 확인되었습니다. TRUE이면 __call()이 트리거되지 않습니다.

첫 번째 if 블록을 제거하면이 결과가 발생합니다.

public function __call($method, $params = []) 
{ 
    if (method_exists($this->CI->users_model, $method)) 
    { 
     return call_user_func_array(array($this->CI->users_model, $method), $params); 
    } 
    else 
    { 
     throw new BadMethodCallException("No such method: {$method}"); 
    } 
} 

이렇게하면됩니다.

내가 물어야 할 필요가 없다면, 트리거해야 할 코드는 무엇입니까 __call? 코멘트에 회신

편집 :

이 .. 아이가 형제의 방법으로 액세스 할 수있는 방법이 있나요 제발 말해?

나의 첫 번째 반응은 그 필요성이 있다면 "드라이버"가 사용할 패턴이 아닐 수 있습니다. CI에서 구현 된 것처럼 드라이버는 상위 클래스와 잠재적 하위 클래스가있는 특별한 유형의 라이브러리입니다. 하위 클래스는 상위 클래스에 액세스 할 수 있지만 형제는 액세스 할 수 없습니다.

이 배열은 일반적으로 각 드라이버가 단일 유형의 장치 또는 특정 소프트웨어 서비스를 처리하도록 설계 되었기 때문에 그 목적이 있습니다.예를 들어, 데이터베이스와 관련하여, 각각의 드라이버는 특정 유형의 데이터베이스 서버 (즉, MySQL, SQLite) 및/또는 서버 유형에 대한 확장 (즉, mysql, mysqli)을 처리한다.

CI 라이브러리 CI_Cache에는 여러 가지 동적 캐싱 시스템 용 드라이버가 있습니다. 이러한 시스템은 상호 배타적 인 경향이 있습니다. 나는 memcachedredis을 동시에 실행하려고하면 심각한 두통을 일으킬 것이라고 생각합니다.

이 예제는 잘못된 소프트웨어 패턴을 선택하지 않았는지 궁금해하는 이유입니다. 적어도 형제 자매가 의사 소통을해야하는 이유는 separation of concerns 일 때 잘못된 사고를하는 경향이 있습니다.

모두 제가 말했듯이, 해결 방법은 자질구레 한 것을 처리하는 부모에게 메소드를 넣는 것입니다. 이 메소드는 다른 형제에서 적절한 메소드를 호출하는 한 형제에서 부모로 호출됩니다. 참고 : 나는이 아이디어를 테스트하지 않았다. __call이 문제를 처리 할 수는 있지만 명시 적 호출이 더 깨끗한 해결책이라고 생각됩니다.

도움이 될만한 몇 가지 CI 드라이버 자습서가 이미 여기에없는 경우입니다. Kevin Phillipscodebyjeff

+0

: '.. 모든 프로젝트에 대해 저는 CodeIgniter 드라이버를 사용하여 이것을 포기했습니다. 당신이 와서 내 인생을 행복하게 만들었습니다.) ... 이것은 내가 2 년 이상을 찾고 있었던 것이다! 당신과 Stackoverflow <3 –

+0

덕분에 하루에 해결 된 @DDFriend하시기 바랍니다 .. 아이가 형제의 방법에 액세스 할 수있는 방법이 있습니까? –

+0

위의 의견을 해결하기 위해 제 대답에 일부를 추가했습니다. – DFriend