Hướng dẫn php get all classes in directory - php lấy tất cả các lớp trong thư mục

Cập nhật: Vì câu trả lời này trở nên hơi phổ biến, tôi đã tạo ra một gói Packagist để đơn giản hóa mọi thứ. Về cơ bản, nó chứa những gì tôi đã mô tả ở đây, mà không cần phải tự mình thêm lớp hoặc định cấu hình

autoload->{'psr-4'};
    }

    private static function getNamespaceDirectory($namespace)
    {
        $composerNamespaces = self::getDefinedNamespaces();

        $namespaceFragments = explode('\\', $namespace);
        $undefinedNamespaceFragments = [];

        while($namespaceFragments) {
            $possibleNamespace = implode('\\', $namespaceFragments) . '\\';

            if(array_key_exists($possibleNamespace, $composerNamespaces)){
                return realpath(self::appRoot . $composerNamespaces[$possibleNamespace] . implode('/', $undefinedNamespaceFragments));
            }

            array_unshift($undefinedNamespaceFragments, array_pop($namespaceFragments));            
        }

        return false;
    }
}
8 theo cách thủ công. Cuối cùng nó có thể hỗ trợ nhiều hơn chỉ PSR-4.: Since this answer became somewhat popular, I've created a packagist package to simplify things. It contains basically what I've described here, without the need to add the class yourself or configure the
autoload->{'psr-4'};
    }

    private static function getNamespaceDirectory($namespace)
    {
        $composerNamespaces = self::getDefinedNamespaces();

        $namespaceFragments = explode('\\', $namespace);
        $undefinedNamespaceFragments = [];

        while($namespaceFragments) {
            $possibleNamespace = implode('\\', $namespaceFragments) . '\\';

            if(array_key_exists($possibleNamespace, $composerNamespaces)){
                return realpath(self::appRoot . $composerNamespaces[$possibleNamespace] . implode('/', $undefinedNamespaceFragments));
            }

            array_unshift($undefinedNamespaceFragments, array_pop($namespaceFragments));            
        }

        return false;
    }
}
8 manually. It may eventually support more than just PSR-4.

Gói đó có thể được tìm thấy ở đây: Haydenpierce/Class-Finder.

$ composer require haydenpierce/class-finder

Xem thêm thông tin trong tệp readme.


Tôi không hài lòng với bất kỳ giải pháp nào ở đây nên cuối cùng tôi đã xây dựng lớp học của mình để xử lý việc này. Giải pháp này yêu cầu bạn là:This solution requires that you are:

  • Sử dụng nhà soạn nhạc
  • Sử dụng PSR-4

Tóm lại, lớp này cố gắng tìm ra nơi các lớp thực sự sống trên hệ thống tập tin của bạn dựa trên các không gian tên mà bạn đã xác định trong

autoload->{'psr-4'};
    }

    private static function getNamespaceDirectory($namespace)
    {
        $composerNamespaces = self::getDefinedNamespaces();

        $namespaceFragments = explode('\\', $namespace);
        $undefinedNamespaceFragments = [];

        while($namespaceFragments) {
            $possibleNamespace = implode('\\', $namespaceFragments) . '\\';

            if(array_key_exists($possibleNamespace, $composerNamespaces)){
                return realpath(self::appRoot . $composerNamespaces[$possibleNamespace] . implode('/', $undefinedNamespaceFragments));
            }

            array_unshift($undefinedNamespaceFragments, array_pop($namespaceFragments));            
        }

        return false;
    }
}
9. Chẳng hạn, các lớp được xác định trong không gian tên
$path = __DIR__;
$fqcns = array();

$allFiles = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path));
$phpFiles = new RegexIterator($allFiles, '/\.php$/');
foreach ($phpFiles as $phpFile) {
    $content = file_get_contents($phpFile->getRealPath());
    $tokens = token_get_all($content);
    $namespace = '';
    for ($index = 0; isset($tokens[$index]); $index++) {
        if (!isset($tokens[$index][0])) {
            continue;
        }
        if (
            T_NAMESPACE === $tokens[$index][0]
            && T_WHITESPACE === $tokens[$index + 1][0]
            && T_STRING === $tokens[$index + 2][0]
        ) {
            $namespace = $tokens[$index + 2][1];
            // Skip "namespace" keyword, whitespaces, and actual namespace
            $index += 2;
        }
        if (
            T_CLASS === $tokens[$index][0]
            && T_WHITESPACE === $tokens[$index + 1][0]
            && T_STRING === $tokens[$index + 2][0]
        ) {
            $fqcns[] = $namespace.'\\'.$tokens[$index + 2][1];
            // Skip "class" keyword, whitespaces, and actual classname
            $index += 2;

            # break if you have one class per file (psr-4 compliant)
            # otherwise you'll need to handle class constants (Foo::class)
            break;
        }
    }
}
0 được tìm thấy trong
$path = __DIR__;
$fqcns = array();

$allFiles = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path));
$phpFiles = new RegexIterator($allFiles, '/\.php$/');
foreach ($phpFiles as $phpFile) {
    $content = file_get_contents($phpFile->getRealPath());
    $tokens = token_get_all($content);
    $namespace = '';
    for ($index = 0; isset($tokens[$index]); $index++) {
        if (!isset($tokens[$index][0])) {
            continue;
        }
        if (
            T_NAMESPACE === $tokens[$index][0]
            && T_WHITESPACE === $tokens[$index + 1][0]
            && T_STRING === $tokens[$index + 2][0]
        ) {
            $namespace = $tokens[$index + 2][1];
            // Skip "namespace" keyword, whitespaces, and actual namespace
            $index += 2;
        }
        if (
            T_CLASS === $tokens[$index][0]
            && T_WHITESPACE === $tokens[$index + 1][0]
            && T_STRING === $tokens[$index + 2][0]
        ) {
            $fqcns[] = $namespace.'\\'.$tokens[$index + 2][1];
            // Skip "class" keyword, whitespaces, and actual classname
            $index += 2;

            # break if you have one class per file (psr-4 compliant)
            # otherwise you'll need to handle class constants (Foo::class)
            break;
        }
    }
}
1. Điều này có thể được tin cậy vì ánh xạ cấu trúc thư mục thành không gian tên được yêu cầu bởi PSR-4:

Tên không gian con liền kề tên sau "Tiền tố không gian tên" tương ứng với một thư mục con trong "thư mục cơ sở", trong đó các bộ phân cách không gian tên đại diện cho các dấu phân cách thư mục. Tên thư mục con phải phù hợp với trường hợp của tên không gian tên con.

Bạn có thể cần phải điều chỉnh

$path = __DIR__;
$fqcns = array();

$allFiles = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path));
$phpFiles = new RegexIterator($allFiles, '/\.php$/');
foreach ($phpFiles as $phpFile) {
    $content = file_get_contents($phpFile->getRealPath());
    $tokens = token_get_all($content);
    $namespace = '';
    for ($index = 0; isset($tokens[$index]); $index++) {
        if (!isset($tokens[$index][0])) {
            continue;
        }
        if (
            T_NAMESPACE === $tokens[$index][0]
            && T_WHITESPACE === $tokens[$index + 1][0]
            && T_STRING === $tokens[$index + 2][0]
        ) {
            $namespace = $tokens[$index + 2][1];
            // Skip "namespace" keyword, whitespaces, and actual namespace
            $index += 2;
        }
        if (
            T_CLASS === $tokens[$index][0]
            && T_WHITESPACE === $tokens[$index + 1][0]
            && T_STRING === $tokens[$index + 2][0]
        ) {
            $fqcns[] = $namespace.'\\'.$tokens[$index + 2][1];
            // Skip "class" keyword, whitespaces, and actual classname
            $index += 2;

            # break if you have one class per file (psr-4 compliant)
            # otherwise you'll need to handle class constants (Foo::class)
            break;
        }
    }
}
2 để trỏ đến thư mục có chứa
autoload->{'psr-4'};
    }

    private static function getNamespaceDirectory($namespace)
    {
        $composerNamespaces = self::getDefinedNamespaces();

        $namespaceFragments = explode('\\', $namespace);
        $undefinedNamespaceFragments = [];

        while($namespaceFragments) {
            $possibleNamespace = implode('\\', $namespaceFragments) . '\\';

            if(array_key_exists($possibleNamespace, $composerNamespaces)){
                return realpath(self::appRoot . $composerNamespaces[$possibleNamespace] . implode('/', $undefinedNamespaceFragments));
            }

            array_unshift($undefinedNamespaceFragments, array_pop($namespaceFragments));            
        }

        return false;
    }
}
9.

autoload->{'psr-4'};
    }

    private static function getNamespaceDirectory($namespace)
    {
        $composerNamespaces = self::getDefinedNamespaces();

        $namespaceFragments = explode('\\', $namespace);
        $undefinedNamespaceFragments = [];

        while($namespaceFragments) {
            $possibleNamespace = implode('\\', $namespaceFragments) . '\\';

            if(array_key_exists($possibleNamespace, $composerNamespaces)){
                return realpath(self::appRoot . $composerNamespaces[$possibleNamespace] . implode('/', $undefinedNamespaceFragments));
            }

            array_unshift($undefinedNamespaceFragments, array_pop($namespaceFragments));            
        }

        return false;
    }
}

Hướng dẫn php get all classes in directory - php lấy tất cả các lớp trong thư mục

Fabien sa

8.7373 huy hiệu vàng37 Huy hiệu bạc43 Huy hiệu đồng3 gold badges37 silver badges43 bronze badges

Đã trả lời ngày 25 tháng 10 năm 2016 lúc 0:41Oct 25, 2016 at 0:41

13

Cách tiếp cận chung sẽ là để có được tất cả các tên lớp đủ điều kiện (lớp có không gian tên đầy đủ) trong dự án của bạn, sau đó lọc theo không gian tên mong muốn.

PHP cung cấp một số chức năng gốc để có được các lớp đó (get_declared_classes, v.v.), nhưng họ sẽ không thể tìm thấy các lớp chưa được tải (bao gồm / yêu cầu), do đó nó sẽ không hoạt động như mong đợi với trình tải tự động (như trình soạn thảo cho thí dụ). Đây là một vấn đề lớn vì việc sử dụng các trình tải tự động là rất phổ biến.

Vì vậy, phương sách cuối cùng của bạn là tự mình tìm tất cả các tệp PHP và phân tích chúng để trích xuất không gian tên và lớp học của họ:

$path = __DIR__;
$fqcns = array();

$allFiles = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path));
$phpFiles = new RegexIterator($allFiles, '/\.php$/');
foreach ($phpFiles as $phpFile) {
    $content = file_get_contents($phpFile->getRealPath());
    $tokens = token_get_all($content);
    $namespace = '';
    for ($index = 0; isset($tokens[$index]); $index++) {
        if (!isset($tokens[$index][0])) {
            continue;
        }
        if (
            T_NAMESPACE === $tokens[$index][0]
            && T_WHITESPACE === $tokens[$index + 1][0]
            && T_STRING === $tokens[$index + 2][0]
        ) {
            $namespace = $tokens[$index + 2][1];
            // Skip "namespace" keyword, whitespaces, and actual namespace
            $index += 2;
        }
        if (
            T_CLASS === $tokens[$index][0]
            && T_WHITESPACE === $tokens[$index + 1][0]
            && T_STRING === $tokens[$index + 2][0]
        ) {
            $fqcns[] = $namespace.'\\'.$tokens[$index + 2][1];
            // Skip "class" keyword, whitespaces, and actual classname
            $index += 2;

            # break if you have one class per file (psr-4 compliant)
            # otherwise you'll need to handle class constants (Foo::class)
            break;
        }
    }
}

Nếu bạn theo tiêu chuẩn PSR 0 hoặc PSR 4 (cây thư mục của bạn phản ánh không gian tên của bạn), bạn không phải lọc bất cứ điều gì: Chỉ cần đưa ra đường dẫn tương ứng với không gian tên bạn muốn.

Nếu bạn không phải là người hâm mộ sao chép/dán đoạn mã trên, bạn chỉ cần cài đặt thư viện này: https://github.com/gnugat/nomo-paco. Nếu bạn sử dụng PHP> = 5.5, bạn cũng có thể sử dụng thư viện sau: https://github.com/hanneskod/classtools.

Đã trả lời ngày 12 tháng 12 năm 2014 lúc 9:30Dec 12, 2014 at 9:30

Hướng dẫn php get all classes in directory - php lấy tất cả các lớp trong thư mục

3

Khá nhiều câu trả lời thú vị ở trên, một số thực sự phức tạp đặc biệt cho nhiệm vụ được đề xuất.

Để thêm một hương vị khác vào các khả năng, ở đây là một chức năng không được tối ưu hóa nhanh chóng và dễ dàng để thực hiện những gì bạn yêu cầu bằng cách sử dụng các kỹ thuật cơ bản nhất và các tuyên bố phổ biến mà tôi có thể nghĩ đến:

function classes_in_namespace($namespace) {
      $namespace .= '\\';
      $myClasses  = array_filter(get_declared_classes(), function($item) use ($namespace) { return substr($item, 0, strlen($namespace)) === $namespace; });
      $theClasses = [];
      foreach ($myClasses AS $class):
            $theParts = explode('\\', $class);
            $theClasses[] = end($theParts);
      endforeach;
      return $theClasses;
}

Sử dụng đơn giản như:

$MyClasses = classes_in_namespace('namespace\sub\deep');

var_dump($MyClasses);

Tôi đã viết chức năng này để cho rằng bạn không thêm "chém kéo dài" (

$path = __DIR__;
$fqcns = array();

$allFiles = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path));
$phpFiles = new RegexIterator($allFiles, '/\.php$/');
foreach ($phpFiles as $phpFile) {
    $content = file_get_contents($phpFile->getRealPath());
    $tokens = token_get_all($content);
    $namespace = '';
    for ($index = 0; isset($tokens[$index]); $index++) {
        if (!isset($tokens[$index][0])) {
            continue;
        }
        if (
            T_NAMESPACE === $tokens[$index][0]
            && T_WHITESPACE === $tokens[$index + 1][0]
            && T_STRING === $tokens[$index + 2][0]
        ) {
            $namespace = $tokens[$index + 2][1];
            // Skip "namespace" keyword, whitespaces, and actual namespace
            $index += 2;
        }
        if (
            T_CLASS === $tokens[$index][0]
            && T_WHITESPACE === $tokens[$index + 1][0]
            && T_STRING === $tokens[$index + 2][0]
        ) {
            $fqcns[] = $namespace.'\\'.$tokens[$index + 2][1];
            // Skip "class" keyword, whitespaces, and actual classname
            $index += 2;

            # break if you have one class per file (psr-4 compliant)
            # otherwise you'll need to handle class constants (Foo::class)
            break;
        }
    }
}
4) vào không gian tên, vì vậy bạn sẽ không phải nhân đôi nó để thoát khỏi nó. ;)not adding the last "trailing slash" (
$path = __DIR__;
$fqcns = array();

$allFiles = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path));
$phpFiles = new RegexIterator($allFiles, '/\.php$/');
foreach ($phpFiles as $phpFile) {
    $content = file_get_contents($phpFile->getRealPath());
    $tokens = token_get_all($content);
    $namespace = '';
    for ($index = 0; isset($tokens[$index]); $index++) {
        if (!isset($tokens[$index][0])) {
            continue;
        }
        if (
            T_NAMESPACE === $tokens[$index][0]
            && T_WHITESPACE === $tokens[$index + 1][0]
            && T_STRING === $tokens[$index + 2][0]
        ) {
            $namespace = $tokens[$index + 2][1];
            // Skip "namespace" keyword, whitespaces, and actual namespace
            $index += 2;
        }
        if (
            T_CLASS === $tokens[$index][0]
            && T_WHITESPACE === $tokens[$index + 1][0]
            && T_STRING === $tokens[$index + 2][0]
        ) {
            $fqcns[] = $namespace.'\\'.$tokens[$index + 2][1];
            // Skip "class" keyword, whitespaces, and actual classname
            $index += 2;

            # break if you have one class per file (psr-4 compliant)
            # otherwise you'll need to handle class constants (Foo::class)
            break;
        }
    }
}
4) on the namespace, so you won't have to double it to escape it. ;)

Xin lưu ý chức năng này chỉ là một ví dụ và có nhiều lỗ hổng. Dựa trên ví dụ trên, nếu bạn sử dụng '

$path = __DIR__;
$fqcns = array();

$allFiles = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path));
$phpFiles = new RegexIterator($allFiles, '/\.php$/');
foreach ($phpFiles as $phpFile) {
    $content = file_get_contents($phpFile->getRealPath());
    $tokens = token_get_all($content);
    $namespace = '';
    for ($index = 0; isset($tokens[$index]); $index++) {
        if (!isset($tokens[$index][0])) {
            continue;
        }
        if (
            T_NAMESPACE === $tokens[$index][0]
            && T_WHITESPACE === $tokens[$index + 1][0]
            && T_STRING === $tokens[$index + 2][0]
        ) {
            $namespace = $tokens[$index + 2][1];
            // Skip "namespace" keyword, whitespaces, and actual namespace
            $index += 2;
        }
        if (
            T_CLASS === $tokens[$index][0]
            && T_WHITESPACE === $tokens[$index + 1][0]
            && T_STRING === $tokens[$index + 2][0]
        ) {
            $fqcns[] = $namespace.'\\'.$tokens[$index + 2][1];
            // Skip "class" keyword, whitespaces, and actual classname
            $index += 2;

            # break if you have one class per file (psr-4 compliant)
            # otherwise you'll need to handle class constants (Foo::class)
            break;
        }
    }
}
5' và '
$path = __DIR__;
$fqcns = array();

$allFiles = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path));
$phpFiles = new RegexIterator($allFiles, '/\.php$/');
foreach ($phpFiles as $phpFile) {
    $content = file_get_contents($phpFile->getRealPath());
    $tokens = token_get_all($content);
    $namespace = '';
    for ($index = 0; isset($tokens[$index]); $index++) {
        if (!isset($tokens[$index][0])) {
            continue;
        }
        if (
            T_NAMESPACE === $tokens[$index][0]
            && T_WHITESPACE === $tokens[$index + 1][0]
            && T_STRING === $tokens[$index + 2][0]
        ) {
            $namespace = $tokens[$index + 2][1];
            // Skip "namespace" keyword, whitespaces, and actual namespace
            $index += 2;
        }
        if (
            T_CLASS === $tokens[$index][0]
            && T_WHITESPACE === $tokens[$index + 1][0]
            && T_STRING === $tokens[$index + 2][0]
        ) {
            $fqcns[] = $namespace.'\\'.$tokens[$index + 2][1];
            // Skip "class" keyword, whitespaces, and actual classname
            $index += 2;

            # break if you have one class per file (psr-4 compliant)
            # otherwise you'll need to handle class constants (Foo::class)
            break;
        }
    }
}
6', hàm sẽ trả về tất cả các lớp được tìm thấy trong cả hai không gian tên (hành xử như thể nó là đệ quy). Tuy nhiên, sẽ rất đơn giản để điều chỉnh và mở rộng chức năng này nhiều hơn thế, chủ yếu yêu cầu một vài điều chỉnh trong khối
$path = __DIR__;
$fqcns = array();

$allFiles = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path));
$phpFiles = new RegexIterator($allFiles, '/\.php$/');
foreach ($phpFiles as $phpFile) {
    $content = file_get_contents($phpFile->getRealPath());
    $tokens = token_get_all($content);
    $namespace = '';
    for ($index = 0; isset($tokens[$index]); $index++) {
        if (!isset($tokens[$index][0])) {
            continue;
        }
        if (
            T_NAMESPACE === $tokens[$index][0]
            && T_WHITESPACE === $tokens[$index + 1][0]
            && T_STRING === $tokens[$index + 2][0]
        ) {
            $namespace = $tokens[$index + 2][1];
            // Skip "namespace" keyword, whitespaces, and actual namespace
            $index += 2;
        }
        if (
            T_CLASS === $tokens[$index][0]
            && T_WHITESPACE === $tokens[$index + 1][0]
            && T_STRING === $tokens[$index + 2][0]
        ) {
            $fqcns[] = $namespace.'\\'.$tokens[$index + 2][1];
            // Skip "class" keyword, whitespaces, and actual classname
            $index += 2;

            # break if you have one class per file (psr-4 compliant)
            # otherwise you'll need to handle class constants (Foo::class)
            break;
        }
    }
}
7.

Nó có thể không phải là đỉnh cao của Code-Art-Nouveau, nhưng ít nhất nó thực hiện những gì đã được đề xuất và phải đủ đơn giản để tự giải thích.

Tôi hy vọng nó giúp mở đường cho bạn để đạt được những gì bạn đang tìm kiếm.

Lưu ý: Php 5, 7 và 8 thân thiện.

Đã trả lời ngày 26 tháng 4 năm 2019 lúc 5:15Apr 26, 2019 at 5:15

Hướng dẫn php get all classes in directory - php lấy tất cả các lớp trong thư mục

7

Khá thú vị rằng dường như không có bất kỳ phương pháp phản ánh nào làm điều đó cho bạn. Tuy nhiên, tôi đã đưa ra một lớp học nhỏ có khả năng đọc thông tin không gian tên.

Để làm như vậy, bạn phải đi qua máng tất cả các lớp được xác định. Sau đó, chúng tôi lấy không gian tên của lớp đó và lưu trữ nó thành một mảng cùng với chính tên lớp.

 ClassOne
include 'ClassOne/ClassOne.php';

// ClassOne namespaces -> ClassTwo
include 'ClassTwo/ClassTwo.php';
include 'ClassTwo/ClassTwoNew.php';

// So now we have two namespaces defined 
// by ourselves (ClassOne -> contains 1 class, ClassTwo -> contains 2 classes)

class NameSpaceFinder {

    private $namespaceMap = [];
    private $defaultNamespace = 'global';

    public function __construct()
    {
        $this->traverseClasses();
    }

    private function getNameSpaceFromClass($class)
    {
        // Get the namespace of the given class via reflection.
        // The global namespace (for example PHP's predefined ones)
        // will be returned as a string defined as a property ($defaultNamespace)
        // own namespaces will be returned as the namespace itself

        $reflection = new \ReflectionClass($class);
        return $reflection->getNameSpaceName() === '' 
                ? $this->defaultNamespace
                : $reflection->getNameSpaceName();
    }

    public function traverseClasses()
    {
        // Get all declared classes
        $classes = get_declared_classes();

        foreach($classes AS $class)
        {
            // Store the namespace of each class in the namespace map
            $namespace = $this->getNameSpaceFromClass($class);
            $this->namespaceMap[$namespace][] = $class;
        }
    }

    public function getNameSpaces()
    {
        return array_keys($this->namespaceMap);
    }

    public function getClassesOfNameSpace($namespace)
    {
        if(!isset($this->namespaceMap[$namespace]))
            throw new \InvalidArgumentException('The Namespace '. $namespace . ' does not exist');

        return $this->namespaceMap[$namespace];
    }

}

$finder = new NameSpaceFinder();
var_dump($finder->getClassesOfNameSpace('ClassTwo'));

Đầu ra sẽ là:

$path = __DIR__;
$fqcns = array();

$allFiles = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path));
$phpFiles = new RegexIterator($allFiles, '/\.php$/');
foreach ($phpFiles as $phpFile) {
    $content = file_get_contents($phpFile->getRealPath());
    $tokens = token_get_all($content);
    $namespace = '';
    for ($index = 0; isset($tokens[$index]); $index++) {
        if (!isset($tokens[$index][0])) {
            continue;
        }
        if (
            T_NAMESPACE === $tokens[$index][0]
            && T_WHITESPACE === $tokens[$index + 1][0]
            && T_STRING === $tokens[$index + 2][0]
        ) {
            $namespace = $tokens[$index + 2][1];
            // Skip "namespace" keyword, whitespaces, and actual namespace
            $index += 2;
        }
        if (
            T_CLASS === $tokens[$index][0]
            && T_WHITESPACE === $tokens[$index + 1][0]
            && T_STRING === $tokens[$index + 2][0]
        ) {
            $fqcns[] = $namespace.'\\'.$tokens[$index + 2][1];
            // Skip "class" keyword, whitespaces, and actual classname
            $index += 2;

            # break if you have one class per file (psr-4 compliant)
            # otherwise you'll need to handle class constants (Foo::class)
            break;
        }
    }
}
8

Tất nhiên mọi thứ bên cạnh lớp không gian tên nếu được lắp ráp nhanh chóng và bẩn. Vì vậy, hãy thoải mái dọn dẹp mớ hỗn độn

$path = __DIR__;
$fqcns = array();

$allFiles = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path));
$phpFiles = new RegexIterator($allFiles, '/\.php$/');
foreach ($phpFiles as $phpFile) {
    $content = file_get_contents($phpFile->getRealPath());
    $tokens = token_get_all($content);
    $namespace = '';
    for ($index = 0; isset($tokens[$index]); $index++) {
        if (!isset($tokens[$index][0])) {
            continue;
        }
        if (
            T_NAMESPACE === $tokens[$index][0]
            && T_WHITESPACE === $tokens[$index + 1][0]
            && T_STRING === $tokens[$index + 2][0]
        ) {
            $namespace = $tokens[$index + 2][1];
            // Skip "namespace" keyword, whitespaces, and actual namespace
            $index += 2;
        }
        if (
            T_CLASS === $tokens[$index][0]
            && T_WHITESPACE === $tokens[$index + 1][0]
            && T_STRING === $tokens[$index + 2][0]
        ) {
            $fqcns[] = $namespace.'\\'.$tokens[$index + 2][1];
            // Skip "class" keyword, whitespaces, and actual classname
            $index += 2;

            # break if you have one class per file (psr-4 compliant)
            # otherwise you'll need to handle class constants (Foo::class)
            break;
        }
    }
}
9 bằng cách sử dụng tự động tải.

Đã trả lời ngày 31 tháng 3 năm 2014 lúc 13:05Mar 31, 2014 at 13:05

THPLTHPLthpl

5.7403 huy hiệu vàng28 Huy hiệu bạc43 Huy hiệu đồng3 gold badges28 silver badges43 bronze badges

1

Tôi nghĩ rằng rất nhiều người có thể có một vấn đề như thế này, vì vậy tôi đã dựa vào các câu trả lời từ @hpierce và @loïc-faugeron để giải quyết vấn đề này.

Với lớp được mô tả dưới đây, bạn có thể có tất cả các lớp trong một không gian tên hoặc họ tôn trọng một thuật ngữ nhất định.

getClassMap());
        }
    }

    public function getClasses()
    {
        $allClasses = [];

        if (false === empty(self::$classes)) {
            foreach (self::$classes as $class) {
                $allClasses[] = '\\' . $class;
            }
        }

        return $allClasses;
    }

    public function getClassesByNamespace($namespace)
    {
        if (0 !== strpos($namespace, '\\')) {
            $namespace = '\\' . $namespace;
        }

        $termUpper = strtoupper($namespace);
        return array_filter($this->getClasses(), function($class) use ($termUpper) {
            $className = strtoupper($class);
            if (
                0 === strpos($className, $termUpper) and
                false === strpos($className, strtoupper('Abstract')) and
                false === strpos($className, strtoupper('Interface'))
            ){
                return $class;
            }
            return false;
        });
    }

    public function getClassesWithTerm($term)
    {
        $termUpper = strtoupper($term);
        return array_filter($this->getClasses(), function($class) use ($termUpper) {
            $className = strtoupper($class);
            if (
                false !== strpos($className, $termUpper) and
                false === strpos($className, strtoupper('Abstract')) and
                false === strpos($className, strtoupper('Interface'))
            ){
                return $class;
            }
            return false;
        });
    }
}

Trong trường hợp này, bạn phải sử dụng nhà soạn nhạc để thực hiện tự động tải lớp. Sử dụng lớp học có sẵn trên đó, giải pháp được đơn giản hóa.

Đã trả lời ngày 19 tháng 10 năm 2017 lúc 19:22Oct 19, 2017 at 19:22

Hướng dẫn php get all classes in directory - php lấy tất cả các lớp trong thư mục

2

Sử dụng công cụ tìm

composer require symfony/finder

cách sử dụng

public function getAllNameSpaces($path)
{
    $filenames = $this->getFilenames($path);
    $namespaces = [];
    foreach ($filenames as $filename) {
        $namespaces[] = $this->getFullNamespace($filename) . '\\' . $this->getClassName($filename);
    }
    return $namespaces;
}

private function getClassName($filename)
{
    $directoriesAndFilename = explode('/', $filename);
    $filename = array_pop($directoriesAndFilename);
    $nameAndExtension = explode('.', $filename);
    $className = array_shift($nameAndExtension);
    return $className;
}

private function getFullNamespace($filename)
{
    $lines = file($filename);
    $array = preg_grep('/^namespace /', $lines);
    $namespaceLine = array_shift($array);
    $match = [];
    preg_match('/^namespace (.*);$/', $namespaceLine, $match);
    $fullNamespace = array_pop($match);

    return $fullNamespace;
}

private function getFilenames($path)
{
    $finderFiles = Finder::create()->files()->in($path)->name('*.php');
    $filenames = [];
    foreach ($finderFiles as $finderFile) {
        $filenames[] = $finderFile->getRealpath();
    }
    return $filenames;
}

Đã trả lời ngày 12 tháng 3 năm 2021 lúc 12:08Mar 12, 2021 at 12:08

Tôi sẽ đưa ra một ví dụ thực sự đang được sử dụng trong ứng dụng Laravel 5 của chúng tôi nhưng có thể được sử dụng ở hầu hết mọi nơi. Ví dụ trả về tên lớp với không gian tên có thể dễ dàng lấy ra, nếu không bắt buộc.

Truyền thuyết

  • {{1}} - Đường dẫn để xóa khỏi đường dẫn của tệp hiện tại để truy cập thư mục ứng dụng
  • {{2}} - Đường dẫn thư mục từ thư mục ứng dụng nơi các lớp đích tồn tại
  • {{3}} - Đường dẫn không gian tên

Mã số

$classPaths = glob(str_replace('{{1}}', '',__DIR__) .'{{2}}/*.php');
$classes = array();
$namespace = '{{3}}';
foreach ($classPaths as $classPath) {
    $segments = explode('/', $classPath);
    $segments = explode('\\', $segments[count($segments) - 1]);
    $classes[] = $namespace . $segments[count($segments) - 1];
}

Người Laravel có thể sử dụng

function classes_in_namespace($namespace) {
      $namespace .= '\\';
      $myClasses  = array_filter(get_declared_classes(), function($item) use ($namespace) { return substr($item, 0, strlen($namespace)) === $namespace; });
      $theClasses = [];
      foreach ($myClasses AS $class):
            $theParts = explode('\\', $class);
            $theClasses[] = end($theParts);
      endforeach;
      return $theClasses;
}
0 trên glob ().

Đã trả lời ngày 10 tháng 11 năm 2015 lúc 23:22Nov 10, 2015 at 23:22

Umair Ahmedumair AhmedUmair Ahmed

2.3661 Huy hiệu vàng18 Huy hiệu bạc40 Huy hiệu đồng1 gold badge18 silver badges40 bronze badges

Sau khi thử các giải pháp của nhà soạn nhạc ở trên, không hài lòng với thời gian để có được các lớp đệ quy bên trong một không gian tên, tối đa 3 giây nhưng trên một số máy phải mất 6-7 giây không thể chấp nhận được. Dưới đây lớp biểu thị các lớp trong ~ 0,05 trong cấu trúc thư mục độ sâu 3-4 bình thường.

autoload->{'psr-4'};
    }

    private static function getNamespaceDirectory($namespace)
    {
        $composerNamespaces = self::getDefinedNamespaces();

        $namespaceFragments = explode('\\', $namespace);
        $undefinedNamespaceFragments = [];

        while($namespaceFragments) {
            $possibleNamespace = implode('\\', $namespaceFragments) . '\\';

            if(array_key_exists($possibleNamespace, $composerNamespaces)){
                return realpath(self::appRoot . $composerNamespaces[$possibleNamespace] . implode('/', $undefinedNamespaceFragments));
            }

            array_unshift($undefinedNamespaceFragments, array_pop($namespaceFragments));            
        }

        return false;
    }
}
0

Usage:

autoload->{'psr-4'};
    }

    private static function getNamespaceDirectory($namespace)
    {
        $composerNamespaces = self::getDefinedNamespaces();

        $namespaceFragments = explode('\\', $namespace);
        $undefinedNamespaceFragments = [];

        while($namespaceFragments) {
            $possibleNamespace = implode('\\', $namespaceFragments) . '\\';

            if(array_key_exists($possibleNamespace, $composerNamespaces)){
                return realpath(self::appRoot . $composerNamespaces[$possibleNamespace] . implode('/', $undefinedNamespaceFragments));
            }

            array_unshift($undefinedNamespaceFragments, array_pop($namespaceFragments));            
        }

        return false;
    }
}
1

Result:

autoload->{'psr-4'};
    }

    private static function getNamespaceDirectory($namespace)
    {
        $composerNamespaces = self::getDefinedNamespaces();

        $namespaceFragments = explode('\\', $namespace);
        $undefinedNamespaceFragments = [];

        while($namespaceFragments) {
            $possibleNamespace = implode('\\', $namespaceFragments) . '\\';

            if(array_key_exists($possibleNamespace, $composerNamespaces)){
                return realpath(self::appRoot . $composerNamespaces[$possibleNamespace] . implode('/', $undefinedNamespaceFragments));
            }

            array_unshift($undefinedNamespaceFragments, array_pop($namespaceFragments));            
        }

        return false;
    }
}
2

Đã trả lời ngày 11 tháng 7 năm 2019 lúc 18:37Jul 11, 2019 at 18:37

1

Định vị các lớp học

Một lớp có thể được bản địa hóa trong hệ thống tệp bằng tên và không gian tên của nó, giống như trình tải tự động. Trong trường hợp bình thường, không gian tên nên cho đường dẫn tương đối đến các tệp lớp. Các đường dẫn bao gồm là điểm khởi đầu của các đường dẫn tương đối. Hàm

function classes_in_namespace($namespace) {
      $namespace .= '\\';
      $myClasses  = array_filter(get_declared_classes(), function($item) use ($namespace) { return substr($item, 0, strlen($namespace)) === $namespace; });
      $theClasses = [];
      foreach ($myClasses AS $class):
            $theParts = explode('\\', $class);
            $theClasses[] = end($theParts);
      endforeach;
      return $theClasses;
}
1 Trả về một danh sách bao gồm các đường dẫn trong một chuỗi. Mỗi đường dẫn bao gồm có thể được kiểm tra, cho dù có tồn tại một đường dẫn tương đối phù hợp với không gian tên. Nếu đường dẫn phù hợp được tìm thấy, bạn sẽ biết vị trí của các tệp lớp.

Nhận tên lớp

Ngay khi đã biết vị trí của các tệp lớp, các lớp có thể được trích xuất từ ​​tên tệp, vì tên của tệp lớp phải bao gồm tên lớp theo sau là

function classes_in_namespace($namespace) {
      $namespace .= '\\';
      $myClasses  = array_filter(get_declared_classes(), function($item) use ($namespace) { return substr($item, 0, strlen($namespace)) === $namespace; });
      $theClasses = [];
      foreach ($myClasses AS $class):
            $theParts = explode('\\', $class);
            $theClasses[] = end($theParts);
      endforeach;
      return $theClasses;
}
2.

Mã mẫu

Dưới đây là mã mẫu để lấy tất cả tên lớp của không gian tên

function classes_in_namespace($namespace) {
      $namespace .= '\\';
      $myClasses  = array_filter(get_declared_classes(), function($item) use ($namespace) { return substr($item, 0, strlen($namespace)) === $namespace; });
      $theClasses = [];
      foreach ($myClasses AS $class):
            $theParts = explode('\\', $class);
            $theClasses[] = end($theParts);
      endforeach;
      return $theClasses;
}
3 dưới dạng mảng chuỗi:

autoload->{'psr-4'};
    }

    private static function getNamespaceDirectory($namespace)
    {
        $composerNamespaces = self::getDefinedNamespaces();

        $namespaceFragments = explode('\\', $namespace);
        $undefinedNamespaceFragments = [];

        while($namespaceFragments) {
            $possibleNamespace = implode('\\', $namespaceFragments) . '\\';

            if(array_key_exists($possibleNamespace, $composerNamespaces)){
                return realpath(self::appRoot . $composerNamespaces[$possibleNamespace] . implode('/', $undefinedNamespaceFragments));
            }

            array_unshift($undefinedNamespaceFragments, array_pop($namespaceFragments));            
        }

        return false;
    }
}
3

Đã trả lời ngày 29 tháng 11 năm 2014 lúc 22:19Nov 29, 2014 at 22:19

HenrikhenrikHenrik

2.6431 Huy hiệu vàng23 Huy hiệu bạc33 Huy hiệu đồng1 gold badge23 silver badges33 bronze badges

Lưu ý: Giải pháp này dường như hoạt động trực tiếp với Laravel. Đối với bên ngoài Laravel, bạn có thể cần sao chép và sửa đổi lớp ComposerClassMap từ nguồn đã cho. Tôi đã không thử.: This solution seems to work with Laravel directly. For outside Laravel, you might need to copy and modify the ComposerClassMap class from the given source. I didn't try.

Nếu bạn đã sử dụng trình soạn thảo để tự động tải tự động tuân thủ PSR-4, bạn có thể sử dụng phương thức này để có tất cả các lớp được tự động tải và lọc chúng (đó là ví dụ từ hệ thống mô-đun của tôi, được sao chép và dán trực tiếp từ đó):

autoload->{'psr-4'};
    }

    private static function getNamespaceDirectory($namespace)
    {
        $composerNamespaces = self::getDefinedNamespaces();

        $namespaceFragments = explode('\\', $namespace);
        $undefinedNamespaceFragments = [];

        while($namespaceFragments) {
            $possibleNamespace = implode('\\', $namespaceFragments) . '\\';

            if(array_key_exists($possibleNamespace, $composerNamespaces)){
                return realpath(self::appRoot . $composerNamespaces[$possibleNamespace] . implode('/', $undefinedNamespaceFragments));
            }

            array_unshift($undefinedNamespaceFragments, array_pop($namespaceFragments));            
        }

        return false;
    }
}
4

Nguồn của lớp

function classes_in_namespace($namespace) {
      $namespace .= '\\';
      $myClasses  = array_filter(get_declared_classes(), function($item) use ($namespace) { return substr($item, 0, strlen($namespace)) === $namespace; });
      $theClasses = [];
      foreach ($myClasses AS $class):
            $theParts = explode('\\', $class);
            $theClasses[] = end($theParts);
      endforeach;
      return $theClasses;
}
4: https://github.com/facade/ign/blob/master/src/support/composerclassmap.php

Đã trả lời ngày 25 tháng 11 năm 2019 lúc 13:47Nov 25, 2019 at 13:47

Hướng dẫn php get all classes in directory - php lấy tất cả các lớp trong thư mục

Taha Paksutaha PaksuTaha Paksu

15.1k1 Huy hiệu vàng47 Huy hiệu bạc76 Huy hiệu đồng1 gold badge47 silver badges76 bronze badges

2

function classes_in_namespace($namespace) {
      $namespace .= '\\';
      $myClasses  = array_filter(get_declared_classes(), function($item) use ($namespace) { return substr($item, 0, strlen($namespace)) === $namespace; });
      $theClasses = [];
      foreach ($myClasses AS $class):
            $theParts = explode('\\', $class);
            $theClasses[] = end($theParts);
      endforeach;
      return $theClasses;
}
5,
function classes_in_namespace($namespace) {
      $namespace .= '\\';
      $myClasses  = array_filter(get_declared_classes(), function($item) use ($namespace) { return substr($item, 0, strlen($namespace)) === $namespace; });
      $theClasses = [];
      foreach ($myClasses AS $class):
            $theParts = explode('\\', $class);
            $theClasses[] = end($theParts);
      endforeach;
      return $theClasses;
}
6 và
function classes_in_namespace($namespace) {
      $namespace .= '\\';
      $myClasses  = array_filter(get_declared_classes(), function($item) use ($namespace) { return substr($item, 0, strlen($namespace)) === $namespace; });
      $theClasses = [];
      foreach ($myClasses AS $class):
            $theParts = explode('\\', $class);
            $theClasses[] = end($theParts);
      endforeach;
      return $theClasses;
}
7 có thể được sử dụng để truy xuất tất cả các tên lớp

Hướng dẫn php get all classes in directory - php lấy tất cả các lớp trong thư mục

Racil Hilan

24.1K12 Huy hiệu vàng48 Huy hiệu bạc52 Huy hiệu đồng12 gold badges48 silver badges52 bronze badges

Đã trả lời ngày 31 tháng 3 năm 2014 lúc 12:38Mar 31, 2014 at 12:38

Hướng dẫn php get all classes in directory - php lấy tất cả các lớp trong thư mục

Bạn có thể sử dụng

function classes_in_namespace($namespace) {
      $namespace .= '\\';
      $myClasses  = array_filter(get_declared_classes(), function($item) use ($namespace) { return substr($item, 0, strlen($namespace)) === $namespace; });
      $theClasses = [];
      foreach ($myClasses AS $class):
            $theParts = explode('\\', $class);
            $theClasses[] = end($theParts);
      endforeach;
      return $theClasses;
}
8 nhưng với một chút công việc.

autoload->{'psr-4'};
    }

    private static function getNamespaceDirectory($namespace)
    {
        $composerNamespaces = self::getDefinedNamespaces();

        $namespaceFragments = explode('\\', $namespace);
        $undefinedNamespaceFragments = [];

        while($namespaceFragments) {
            $possibleNamespace = implode('\\', $namespaceFragments) . '\\';

            if(array_key_exists($possibleNamespace, $composerNamespaces)){
                return realpath(self::appRoot . $composerNamespaces[$possibleNamespace] . implode('/', $undefinedNamespaceFragments));
            }

            array_unshift($undefinedNamespaceFragments, array_pop($namespaceFragments));            
        }

        return false;
    }
}
5

Vì vậy, trước tiên bạn nhận được tất cả các lớp được khai báo và sau đó kiểm tra xem chúng bắt đầu bằng không gian tên của bạn.

Lưu ý: Bạn sẽ nhận được mảng trong đó các phím không bắt đầu với 0. Để đạt được điều này, bạn có thể thử:

function classes_in_namespace($namespace) {
      $namespace .= '\\';
      $myClasses  = array_filter(get_declared_classes(), function($item) use ($namespace) { return substr($item, 0, strlen($namespace)) === $namespace; });
      $theClasses = [];
      foreach ($myClasses AS $class):
            $theParts = explode('\\', $class);
            $theClasses[] = end($theParts);
      endforeach;
      return $theClasses;
}
9.: you will get array where keys do not start with 0. To achive this, you can try:
function classes_in_namespace($namespace) {
      $namespace .= '\\';
      $myClasses  = array_filter(get_declared_classes(), function($item) use ($namespace) { return substr($item, 0, strlen($namespace)) === $namespace; });
      $theClasses = [];
      foreach ($myClasses AS $class):
            $theParts = explode('\\', $class);
            $theClasses[] = end($theParts);
      endforeach;
      return $theClasses;
}
9.

Đã trả lời ngày 9 tháng 10 năm 2017 lúc 13:07Oct 9, 2017 at 13:07

FreelightmanfreelightmanFreeLightman

2.1341 Huy hiệu vàng23 Huy hiệu bạc40 Huy hiệu đồng1 gold badge23 silver badges40 bronze badges

1

Cách dễ nhất là sử dụng chức năng AutoLoader

$MyClasses = classes_in_namespace('namespace\sub\deep');

var_dump($MyClasses);
0 của riêng bạn và bên trong nó lưu tên các lớp được tải. Điều đó có phù hợp với bạn không?

Nếu không, tôi nghĩ rằng bạn sẽ phải đối phó với một số phương pháp phản ánh.

Đã trả lời ngày 31 tháng 3 năm 2014 lúc 12:34Mar 31, 2014 at 12:34

UrizielurizielUriziel

1791 Huy hiệu bạc10 Huy hiệu đồng1 silver badge10 bronze badges

1

Tôi chỉ làm một cái gì đó tương tự, điều này tương đối đơn giản nhưng có thể được xây dựng.

autoload->{'psr-4'};
    }

    private static function getNamespaceDirectory($namespace)
    {
        $composerNamespaces = self::getDefinedNamespaces();

        $namespaceFragments = explode('\\', $namespace);
        $undefinedNamespaceFragments = [];

        while($namespaceFragments) {
            $possibleNamespace = implode('\\', $namespaceFragments) . '\\';

            if(array_key_exists($possibleNamespace, $composerNamespaces)){
                return realpath(self::appRoot . $composerNamespaces[$possibleNamespace] . implode('/', $undefinedNamespaceFragments));
            }

            array_unshift($undefinedNamespaceFragments, array_pop($namespaceFragments));            
        }

        return false;
    }
}
6

Đã trả lời ngày 24 tháng 4 năm 2019 lúc 18:25Apr 24, 2019 at 18:25

Mattmattmatt

Phù hiệu đồng 6277 bronze badges

Đối với Symfony, bạn có thể sử dụng thành phần Finder:

http://symfony.com/doc/current/components/finder.html

autoload->{'psr-4'};
    }

    private static function getNamespaceDirectory($namespace)
    {
        $composerNamespaces = self::getDefinedNamespaces();

        $namespaceFragments = explode('\\', $namespace);
        $undefinedNamespaceFragments = [];

        while($namespaceFragments) {
            $possibleNamespace = implode('\\', $namespaceFragments) . '\\';

            if(array_key_exists($possibleNamespace, $composerNamespaces)){
                return realpath(self::appRoot . $composerNamespaces[$possibleNamespace] . implode('/', $undefinedNamespaceFragments));
            }

            array_unshift($undefinedNamespaceFragments, array_pop($namespaceFragments));            
        }

        return false;
    }
}
7

Đã trả lời ngày 15 tháng 12 năm 2017 lúc 12:57Dec 15, 2017 at 12:57

Hướng dẫn php get all classes in directory - php lấy tất cả các lớp trong thư mục