2017-03-18 2 views
1

method_existsのような特定のメソッドをクラスが定義しているかどうかを調べる関数がありますが、前述のメソッドが存在する場合はtrueを返すmethod_defined($obj, 'method_name');それは継承されないobjクラス自体で定義されます。これは、継承されていない新しいメソッド(これは親クラスのメソッドが定義されているかどうかを確認します。method_exists($obj, $method) && !method_exists(get_parent_class($obj), $method)など)と、再定義された継承メソッド再定義されていない継承されたメソッドの場合はfalseを返します(どちらか分かりません)。メソッドが継承、再定義、または新規であるかどうかを判断する方法

サンプルコード:

<?php 
class base 
{ 
    var $x = 'x'; 
    function doit() 
    { 
     return $this->x; 
    } 
} 

class a extends base 
{ 
    function doit() 
    { 
     return 'a'; 
    } 
} 

class b extends base 
{ 
    var $x = 'b'; 
} 

class c extends base 
{ 
} 

function method_defined($obj, $method) 
{ 
    return method_exists($obj, $method); // this is the question 
} 

function info($obj) 
{ 
    echo get_class($obj) . ": " . $obj->doit(); 
    echo " " . (int)method_exists($obj, 'doit'); 
    echo " " . (int)is_subclass_of($obj, 'base'); 
    echo " " . (int)method_defined($obj, 'doit') . "\n"; 
} 

info(new a); // a a 1 1 1 
info(new b); // b b 1 1 0 
info(new c); // c x 1 1 0 
info(new base); // base x 1 0 1 

私は他の同様の質問を見てきましたが、それらはすべてこのためにリフレクションクラスに戻り、そして、私はそれが非常に重いですので、全く可能であればそれを避けたいです。

ありがとうございます。

+0

あなたはそれが10年前に重いんでしたが、それはもはやケース –

+0

だしかし、あなたはリフレクションを避けたい場合は、[get_class_methods(見て....実際modermのPHPであるかunheavyリフレクションに驚くかもしれません)](http://www.php.net/manual/en/function.get-class-methods.php)、必要に応じて各親クラスに対して順番に継承ツリーをチェックしながら歩いていくと、もっと重くなりそうですリフレクションよりも –

+0

'get_class_methods'は問題文で述べたように、新しく定義されたメソッドに対してのみ機能します。再定義されたメソッドから継承することはできません。反射が重くないのは、唯一の方法で終わるかもしれないので、それほど良い方法です... – javiexin

答えて

0

最後に、これが私が解決策として使用したものです。それは反射を使用しますが、それは非常に簡単で効果的です。

function method_defined($ref, $method) 
{ 
    $class = (is_string($ref)) ? $ref : get_class($ref); 
    return (method_exists($class, $method)) && ($class === (new \ReflectionMethod($class, $method))->getDeclaringClass()->name); 
} 
関連する問題