检查扩展类中是否存在方法,但父类是否存在

时间:2013-12-16 05:20:40

标签: php

使用method_exists,它会检查所有方法,包括父类。

示例:

class Toot {
    function Good() {}
}

class Tootsie extends Toot {
    function Bad() {}
}

function testMethodExists() {
    // true
    var_dump(method_exists('Toot', 'Good'));

    // false
    var_dump(method_exists('Toot', 'Bad'));

    // true
    var_dump(method_exists('Tootsie', 'Good'));

    // true
    var_dump(method_exists('Tootsie', 'Bad'));
}

如何检查方法是否仅存在于当前类而不是父类(即Tootsie)?

6 个答案:

答案 0 :(得分:6)

由于v.4.0.5 php有get_parent_class()方法,因此返回父类。所以你可以在没有重新选择的情况下处理它:

class A
{
    function a() { /* ... */}    
    function b() { /* ... */}    
}
class B extends A
{
    function b() { /* ... */}    
    function c() { /* ... */}    
}

function own_method($class_name, $method_name)
{    
    if (method_exists($class_name, $method_name))
    {
        $parent_class = get_parent_class($class_name);
        if ($parent_class !== false) return !method_exists($parent_class, $method_name);
        return true;
    }
    else return false;
}

var_dump(own_method('B', 'a')); // false
var_dump(own_method('B', 'b')); // false 
var_dump(own_method('B', 'c')); // true

答案 1 :(得分:1)

你可以使用反射

$refl = new ReflectionClass($class_name); 

if($refl->hasMethod($method_name)){
       //do your stuff here 
}

了解更多信息ReflectionClass

答案 2 :(得分:1)

如果您需要知道该方法是否存在于给定子级中而不管父级中是否存在,您可以这样做:

var testVar = [null, true, true, false, false];

//Paulpro's solution (not mine)
switch (testVar.indexOf( true )) {
  case 1:
    console.log('Im in the first group!');
    break;
  case 2:
    console.log('Im in the second group!');
    break;
  case 3:
    console.log('Im in the third group!');
    break;
}

答案 3 :(得分:0)

对我来说,问题是检查扩展类中是否存在方法,但父类中是否存在父类

以Elantcev Mikhail为例,看起来更像是这样: -

class A
{
        function a() { /* ... */}    
        function b() { /* ... */}    
        public function own_method( $method_name )
        {    
            if (method_exists($this, $method_name))
            {
                return true;
            }
            else return false;
        }
}
class B extends A
{
    function b() { /* ... */}    
    function c() { /* ... */}    
}

$b = new B;

var_dump($b->own_method('c')); // true

你为什么要这样做?

我有一个BaseModel类,我在其中为扩展模型中的属性设置了提示格式:

class BaseModel
{
    public function attributeHelp($attributeName)
    {
        if (method_exists($this, 'hints') && array_key_exists($attributeName, $this->hints()))
        {
            return '<i html for nicely formatted hint'
                . $this->hints()[$attributeName]
                . '"></i>';
        }
        return false;
    }
}

然后在我的数据模型中

class Customer extends BaseModel
{
    public function hints()
    {
        return [
           'customer_name' => 'please use your fullname ...',
           'some other attribute' => 'some other description'
        ];
    }
}

答案 4 :(得分:0)

基于上述@sleepless答案,但可以在根本不存在该方法的情况下工作:

function methodImplementedInClass($className, $methodName) {
    // If this class doesn't have the method at all, return false
    if (!method_exists($className, $methodName)) {
        return false;
    }
    // Now check if the method was implemented in this class or in some parent
    return (new ReflectionClass($className))->getMethod($methodName)->class == $className;
}

答案 5 :(得分:0)

这是我的解决方案,使用反射并检查反射方法中涉及的实际类。

<?php

class Base {
    public function BaseOnly() {
    }

    public function Extended() {
    }
}

class Child extends Base {
    public function ChildOnly() {
    }

    public function Extended() {
    }
}

function childMethodExists($baseClass, $childClass, $methodName) {
    if (!method_exists($childClass, $methodName)) {
        return false; // doesn't exist in the child class or base class
    }
    if (!method_exists($baseClass, $methodName)) {
        return true; // only exists on child class, as otherwise it would have returned above
    }
    // now to check if it is overloaded
    $baseMethod = new ReflectionMethod($baseClass, $methodName);
    $childMethod = new ReflectionMethod($childClass, $methodName);
    return $childMethod->class !== $baseMethod->class;
}

var_dump(childMethodExists(Base::class, Child::class, 'BaseOnly')); // false
var_dump(childMethodExists(Base::class, Child::class, 'ChildOnly')); // true
var_dump(childMethodExists(Base::class, Child::class, 'Neither')); // false
var_dump(childMethodExists(Base::class, Child::class, 'Extended')); // true