使用get_declared_class()只输出我声明的类不是PHP自动执行的类

Eli*_*Eli 6 php

有点好奇,但是我想用我用这样的东西声明的类中创建一个数组

foreach(get_declared_classes() as $class)
    $c[] = $class;


print_r($c);
Run Code Online (Sandbox Code Playgroud)

唯一的问题是我得到了类似于我加载的类之类的东西:

stdClass
Exception
ErrorException
Closure
DateTime
DateTimeZone
DateInterval
DatePeriod
LibXMLError
LogicException
BadFunctionCallException
BadMethodCallException
DomainException
InvalidArgumentException
LengthException
OutOfRangeException
RuntimeException
OutOfBoundsException
OverflowException
RangeException
UnderflowException
UnexpectedValueException
RecursiveIteratorIterator
IteratorIterator
{...}
SQLiteResult
SQLiteUnbuffered
SQLiteException
SQLite3
SQLite3Stmt
SQLite3Result
XMLReader
XMLWriter
XSLTProcessor
ZipArchive
Run Code Online (Sandbox Code Playgroud)

有一个函数只加载用户特定的类而不是系统加载的类?或者可能是限制foreach列出这些类的条件语句?

Gor*_*don 15

Reflection API可以检测类是否为内部类.ReflectionClass::isInternal检查类是否是内部的,而不是用户定义的:

$userDefinedClasses = array_filter(
    get_declared_classes(),
    function($className) {
        return !call_user_func(
            array(new ReflectionClass($className), 'isInternal')
        );
    }
);
Run Code Online (Sandbox Code Playgroud)

上面的代码将检查并删除get_declared_classes内部返回的每个类,只留下用户定义的类.这样,您就不需要像本页其他地方所建议的那样创建和维护内部类的数组.


dmi*_*try 12

没有内置函数可以实现这一点,但是你可以get_declared_classes在声明任何东西并将其存储在全局变量之前$predefinedClasses.然后,您需要使用的地方:

print_r(array_diff(get_declared_classes(), $predefinedClasses));
Run Code Online (Sandbox Code Playgroud)


oez*_*ezi 5

没有直接内置的可能性,但是您可以执行以下操作:

  1. 在脚本的开头,调用get_declared_classes()并将其保存到一个变量中,例如$php_classes
  2. 加载完类后,get_declared_classes()再次调用并使用array_diff()过滤$php_classes-结果是您自己的类的列表。

    // start
    $php_classes = get_declared_classes();
    
    // ...
    // some code loading/declaring own classes
    // ...
    
    // later
    $my_classes = array_diff(get_declared_classes(), $php_classes);
    
    Run Code Online (Sandbox Code Playgroud)


And*_*rdu 2

这是我的解决方案,它确实有效并且不会影响性能。这只会为您提供项目中定义的类,而不会提供其他任何内容。确保在加载所有类后尽可能晚地运行它。

/**
 * Get all classes from a project.
 *
 * Return an array containing all classes defined in a project.
 *
 * @param string $project_path
 * @return array
 */
function smk_get_classes_from_project( $project_path ){
    // Placeholder for final output
    $classes = array();

    // Get all classes
    $dc = get_declared_classes();

    // Loop
    foreach ($dc as $class) {
        $reflect = new \ReflectionClass($class);

        // Get the path to the file where is defined this class.
        $filename = $reflect->getFileName();

        // Only user defined classes, exclude internal or classes added by PHP extensions.
        if( ! $reflect->isInternal() ){

            // Replace backslash with forward slash.
            $filename = str_replace(array('\\'), array('/'), $filename);
            $project_path = str_replace(array('\\'), array('/'), $project_path);

            // Remove the last slash. 
            // If last slash is present, some classes from root will not be included.
            // Probably there's an explication for this. I don't know...
            $project_path = rtrim( $project_path, '/' );

            // Add the class only if it is defined in `$project_path` dir.
            if( stripos( $filename, $project_path ) !== false ){
                $classes[] = $class;
            }

        }
    }

    return $classes;    
}
Run Code Online (Sandbox Code Playgroud)

测试一下。

此示例假设项目具有以下路径:/srv/users/apps/my-project-name

echo '<pre>';
print_r( smk_get_classes_from_project( '/srv/users/apps/my-project-name' ) );
echo '</pre>';
Run Code Online (Sandbox Code Playgroud)