2010-10-22 34 views
21

Tôi đã có một giao diệnPHP: cách lấy danh sách các lớp triển khai giao diện nhất định?

interface IModule { 
    public function Install(); 
} 

và một số lớp học mà thực hiện giao diện này

class Module1 implements IModule { 
    public function Install() { 
     return true; 
    } 
} 

class Module2 implements IModule { 
    public function Install() { 
     return true; 
    } 
} 

... 

class ModuleN implements IModule { 
    public function Install() { 
     return true; 
    } 
} 

Làm thế nào để có được một danh sách tất cả các lớp học mà thực hiện giao diện này? Tôi muốn lấy danh sách này bằng PHP.

+2

Bạn có thể nên làm rõ liệu bạn có muốn nhận danh sách trong PHP hay chỉ muốn tạo ra một danh sách cho mục đích tài liệu, vv –

Trả lời

20

Bạn có thể sử dụng PHP ReflectionClass::implementsInterfaceget_declared_classes chức năng để thực hiện điều này:

$classes = get_declared_classes(); 
$implementsIModule = array(); 
foreach($classes as $klass) { 
    $reflect = new ReflectionClass($klass); 
    if($reflect->implementsInterface('IModule')) 
     $implementsIModule[] = $klass; 
} 
+5

Lưu ý: Điều này không hoạt động nếu bạn đang tải IModules thông qua '__autoload'. Nhưng +1. –

+0

7 năm cuối bình luận, nhưng đây là một ví dụ về cách bạn có thể sử dụng các tập tin trong Composers autoload để đảm bảo rằng một số tập tin cụ thể sẽ được nạp mỗi lần và có sẵn với get_declared_classes: http://stackoverflow.com/a/18671530/143279 – bleakgadfly

40

Bạn không cần Reflection cho việc này. Bạn chỉ có thể sử dụng

  • class_implements - Trả lại giao diện được thực hiện bởi lớp trao

Cách sử dụng

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

Ví dụ 1 - Echo mọi tầng lớp triển khai giao diện Iterator

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

Ví dụ 2 - mảng Return of tất cả các lớp thực hiện giao diện Iterator

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

Ví dụ thứ hai đòi hỏi PHP5.3 do gọi lại là một chức năng ẩn danh.

11

giải pháp Generic:

function getImplementingClasses($interfaceName) { 
    return array_filter(
     get_declared_classes(), 
     function($className) use ($interfaceName) { 
      return in_array($interfaceName, class_implements($className)); 
     } 
    ); 
} 
3

Để kiểm tra xem ai thực hiện một giao diện cụ thể, bạn có thể viết một hàm như dưới đây:

<?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; 
    } 
} 

Sản lượng cuộc gọi dụ var_export(whoImplements('ArrayAccess')); sẽ như sau:

[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 
) 

+0

Bằng cách này, bạn không sử dụng vòng lặp và bạn có thể chạy mã trên các phiên bản thấp hơn của PHP. –

+0

Bạn có bất kỳ ý tưởng tại sao tôi thấy một mảng trống, mặc dù tôi chắc chắn đang triển khai giao diện? – Smalbil

+0

@Netbulae Phải có điều gì đó sai. Đặt mã của bạn trong codepad và chia sẻ một liên kết. –

Các vấn đề liên quan