PHP: how to get a list of classes that implement certain interface?

后端 未结 4 1234
無奈伤痛
無奈伤痛 2020-12-04 23:37

I\'ve got an interface

interface IModule {
    public function Install();
}

and some classes that implement this interface

         


        
相关标签:
4条回答
  • 2020-12-05 00:18

    To check who implements a particular interface, you can write a function like below:

    <?php
    /**
     * Get classes which implement a given interface 
     * @param string $interface_name Name of the interface
     * @return array Array of names of classes. Empty array means input is a valid interface which no class is implementing. NULL means input is not even a valid interface name.
     */
    function whoImplements($interface_name) {
        if (interface_exists($interface_name)) {
            return array_filter(get_declared_classes(), create_function('$className', "return in_array(\"$interface_name\", class_implements(\"\$className\"));"));
        }
        else {
            return null;
        }
    }
    

    Output of an example call var_export(whoImplements('ArrayAccess')); will be as follows:

    [sandbox]$ php whoimplementswhat.php
    Array
    (
        [29] => CachingIterator
        [30] => RecursiveCachingIterator
        [38] => ArrayObject
        [39] => ArrayIterator
        [40] => RecursiveArrayIterator
        [48] => SplDoublyLinkedList
        [49] => SplQueue
        [50] => SplStack
        [55] => SplFixedArray
        [56] => SplObjectStorage
        [111] => Phar
        [112] => PharData
    )
    

    This way, you don't use loops and you can run your code on lower versions of PHP. Function array_filter loops internally, but inside PHP execution engine (hence more performant than loops written in PHP code).

    0 讨论(0)
  • 2020-12-05 00:21

    You dont need Reflection for this. You can simply use

    • class_implements — Return the interfaces which are implemented by the given class

    Usage

    in_array('InterfaceName', class_implements('className'));
    

    Example 1 - Echo all classes implementing the Iterator Interface

    foreach (get_declared_classes() as $className) {
        if (in_array('Iterator', class_implements($className))) {
            echo $className, PHP_EOL;
        }
    }
    

    Example 2 - Return array of all classes implementing the Iterator Interface

    print_r(
        array_filter(
            get_declared_classes(), 
            function ($className) {
                return in_array('Iterator', class_implements($className));
            }
        )
    );
    

    The second example requires PHP5.3 due to the callback being an anonymous function.

    0 讨论(0)
  • 2020-12-05 00:36

    You can use PHP's ReflectionClass::implementsInterface and get_declared_classes functions to accomplish this:

    $classes = get_declared_classes();
    $implementsIModule = array();
    foreach($classes as $klass) {
       $reflect = new ReflectionClass($klass);
       if($reflect->implementsInterface('IModule')) 
          $implementsIModule[] = $klass;
    }
    
    0 讨论(0)
  • 2020-12-05 00:40

    Generic solution:

    function getImplementingClasses( $interfaceName ) {
        return array_filter(
            get_declared_classes(),
            function( $className ) use ( $interfaceName ) {
                return in_array( $interfaceName, class_implements( $className ) );
            }
        );
    }
    
    0 讨论(0)
提交回复
热议问题