技術日記
PHPでクラスに特定のメソッドがあるかどうかを調べる方法Edit

っつーか普通に、

$foo = new Foo();
if (is_callable(array($foo, 'bar')) {echo "Foo::bar() exists"}

っていけるかなーと思っていたんだけど、問題は__callを使ったときにどうなるのか。試してみたところ、__callが存在するだけで、あらゆるメソッドが存在することになってしまうらしい(っつー言い方は不正確だな。callableかどうかを返す関数なんだから。正確には「あらゆるメソッドが呼べることになってしまう」ね)

class Foo
{
function __call($methodName, $args)
{
throw new Exception()
}
}

とかでも、Foo::bar()だろうがFoo::baz()だろうがis_callableはtrueを返してしまう。

試しにis_callableの第3引数を使って、

$methodName = null;
is_callable(array($foo, 'bar'), true, $methodName);

とかしてみたら、存在しないときには$methodNameで識別できるんじゃないかと期待してみたんだけど、期待も空しくFoo::barが返ってきてしまった。

Reflection APIを使って、

$reflection = new ReflectionClass('Foo');
$reflection->hasMedhot('bar');

とすればいけるんだけど、この程度のことにReflection APIを使うのはなんだか大げさなような気がしてならない。今のところそれしか方法が見つからないから、使うんだけど。

追記

以上の文章は、method_exists()を使えば簡単にできることなのに、その関数の存在をすっかり忘れて試行錯誤した記述です。メソッドの存在確認をしたい場合は、

method_exists($foo, 'bar')

を、そのメソッド名での呼び出しが可能かどうか(__callも含めて)が知りたい場合は、

is_callable($foo, 'bar')

を使うのが正解でした。

ご指摘ありがとうございました>wtnabe様。

Published At2007-04-12 00:00Updated At2019-12-31 00:00