2017-10-25 8 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を拡張する)のは、私がアプリケーションと呼ばれるドライバを持っているとしましょう。私はこのApp_users __constructorにUsers_modelをロードしたい

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}"); 
     } 
    } 
} 

(可能ですが、親:: $のCIはアクセスできませんが、私は管理)。

このドライバの方法ORモデルのメソッドかどうかを呼び出すために__callメソッドを使用しているとき、私は直面しています問題があります。残念なことに、その魔法は私のために働いたことはありませんでした。可能であればどうすればいいですか?そうでない場合、回避策はありますか?

ありがとうございます。

+0

__callの実装を教えてください。 – DFriend

+0

@DFriend私はコードを編集して実装しました。(入力ミスを避けてください) –

答えて

1

まず第一に、あなたは条件が満たされることはありませんので、条件

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

が無意味である場合には、第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 Driversを使用して諦めました。 )...これは2年以上私が探していたものです!あなたとStackoverflowのおかげで一日で解決された<3 –

+0

私に教えてください@DFriend ..子供が兄弟の方法にアクセスできる方法はありますか? –

+0

私は上記のコメントに対処するために私の答えにいくつかを追加しました。 – DFriend

関連する問題