php获得可见性

时间:2011-01-17 12:09:11

标签: php visibility access-modifiers

是否可以在php中获取类中方法和属性的可见性?

我希望能够做到这样的事情:

function __call($method, $args)
{
    if(is_callable(array($this,$method))
    {
        if(get_visibility(array($this,$method)) == 'private')
            //dosomething
        elseif(get_visibility(array($this,$method)) == 'protected')
            //dosomething
        else
            //dosomething
    } 
} 

3 个答案:

答案 0 :(得分:7)

is_callable会考虑可见性,但由于您是在课堂内使用它,因此总是会评估为TRUE

要获得方法可见性,您必须use the Reflection API and check the method's modifiers

PHP手册中的摘要示例:

class Testing
{
    final public static function foo()
    {
        return;
    }
}

// this would go into your __call method
$foo = new ReflectionMethod('Testing', 'foo');
echo implode(
    Reflection::getModifierNames(
        $foo->getModifiers()
    )
); // outputs finalpublicstatic

同样适用于properties

然而,由于反映课程的复杂性,这可能会很慢。您应该对其进行基准测试,看它是否会对您的应用程序造成太大影响。

答案 1 :(得分:6)

您可能需要考虑使用PHP的Reflection API。但是,我还应该问你为什么你想要这样做,因为Reflection通常只会在开始时有点hacky的情况下使用。但是有可能,所以这里有:

<?php

class Foo {
    /**
     *
     * @var ReflectionClass
     */
    protected $reflection;
    protected function bar( ) {

    }

    private function baz( ) {

    }

    public function __call( $method, $args ) {
        if( ( $reflMethod = $this->method( $method ) ) !== false ) {
            if( $reflMethod->isPrivate( ) ) {
                echo "That's private.<br />\n";
            }
            elseif( $reflMethod->isProtected( ) ) {
                echo "That's protected.<br />\n";
            }
        }
    }

    protected function method( $name ) {
        if( !isset( $this->methods[$name] ) ) {
            if( $this->reflect( )->hasMethod( $name ) ) {
                $this->methods[$name] = $this->reflect( )->getMethod( $name );
            }
            else {
                $this->methods[$name] = false;
            }
        }
        return $this->methods[$name];
    }

    protected function reflect( ) {
        if( !isset( $this->reflection ) ) {
            $this->reflection = new ReflectionClass( $this );
        }
        return $this->reflection;
    }
}

$foo = new Foo( );
$foo->baz( );
$foo->bar( );

答案 2 :(得分:-1)

这个答案有点晚了,但我觉得get_class_methods()method_exists()结合使用还有一些附加价值:

<?php
class Foo {
    // ...
    public function getVisibility($method) {
        if ( method_exists($this, $method) && in_array($method, get_class_methods($this)) ) {
            return 'protected or public';
        } else {
            return 'private';
        }
    }
}