10

私は、クロージャを導入した PHP 5.3 を使用しています。アプリ (およびフレームワーク) 全体でクロージャーを使用できるようになったので、 is_callable を使用してハンドラーの種類を確認します$callback

の場合$callback is_callable、私は十分に知っており、その関数/メソッド/クロージャを使用しています。呼び出し可能ではなく、文字列の場合は、おそらく$thisクラス内のメソッドの名前です。存在する場合と存在しない場合があります。PHPに任せると、致命的なエラーが「スロー」されます(私はそれが好きです)。

しかし、ミックスインを使用したいので、魔法のメソッドが必要__callです。__call実際の関数呼び出しの前にロジックを含めることができるため、非常にクールです。しかし...__call呼び出されたメソッドが存在しない場合はどうなりますか? 確かに、例外をスローすることはできますが、それは後でわかります。

問題は、 の有用性ですis_callable。これは、 を実装した後__call、すべてにフォールバックがあるため ( である )、すべてが true を返すため__callです。

動的メソッドと便利な両方を持つ方法はありis_callableますか?

私が見たいのは、呼び出された__is_callableときに PHP が「参照」する、ある種のキャッシュ可能な魔法のメソッドですis_callable(array($object, $method))

php.net では、これについて私と同じように頭を悩ませている人を見つけることができません。これはいけません!使ったらもう__call使えis_callableない!?

私は何か意味がありますか?

PS。私は調べましmethod_existsたが、それは十分ではありません (すべてのクロージャーとグローバル関数を除外できたとしても) パブリックと同様にプライベートおよび保護されたメソッドに対して true を返すためです。

編集ミックスインをチェックする「より良い」is_callableを
作成しましたが、かなり高価だと思います。

4

1 に答える 1

4

最初のアイデア: メソッドが に存在するかどうかを確認するのはget_class_methods()どうですか? この関数はスコープの問題を処理します。

2番目のアイデア:探している関数がクラスに存在しない場合、method_existsクラスにマジックメソッドが含まれているかどうかを( を使用して)確認することもできます__call。そうでない場合は、明らかに存在しない関数の呼び出しは違法です。クラスに__callメソッドが含まれている場合、呼び出し元は自分が何をしているのかを知っている可能性があります。

これらは私の考えです。この種のことでは Python の方が優れていると思います。

于 2011-05-09T17:07:51.327 に答える