有点好奇,但是我想用我用这样的东西声明的类中创建一个数组
foreach(get_declared_classes() as $class)
$c[] = $class;
print_r($c);
唯一的问题是我得到的东西就像我加载的类一样:
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
是否有一个只加载用户特定类而不是系统加载类的函数?或者是一个限制foreach
列出这些类的条件语句?
答案 0 :(得分:13)
Reflection API可以检测类是否为内部类。 ReflectionClass::isInternal
检查类是否是内部的,而不是用户定义的:
$userDefinedClasses = array_filter(
get_declared_classes(),
function($className) {
return !call_user_func(
array(new ReflectionClass($className), 'isInternal')
);
}
);
上面的代码将检查并删除内部get_declared_classes
返回的每个类,只留下用户定义的类。这样,您就不需要像本页其他地方所建议的那样创建和维护内部类的数组。
答案 1 :(得分:12)
没有内置函数可以实现这一点,但您可以在声明任何内容之前get_declared_classes
将其存储在全局变量中,例如$predefinedClasses
。然后,您需要使用的地方:
print_r(array_diff(get_declared_classes(), $predefinedClasses));
答案 2 :(得分:5)
没有直接内置的可能性,但您可以执行以下操作:
get_declared_classes()
并将其存储到$php_classes
,再次致电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);
答案 3 :(得分:1)
以下是我的解决方案,它实际上可以正常工作并且不会影响性能。 这只为您提供了项目中定义的类,没有别的。 确保在加载所有类之后尽可能晚地运行它。
/**
* 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;
}
测试。
此示例假定项目具有以下路径:/srv/users/apps/my-project-name
echo '<pre>';
print_r( smk_get_classes_from_project( '/srv/users/apps/my-project-name' ) );
echo '</pre>';
答案 4 :(得分:0)
另一种可能的做法是:
$a= get_declared_classes();
// All user-defined classes
print_r(array_slice(get_declared_classes(), count($a)));
答案 5 :(得分:0)
@Gordon的答案非常好, @Dmitry的解决方案也很好,但是只有当您的课程位于不同的文件中并且包含了它们时,它才有效:
await this.connection.transaction(async transactionalEntityManager => {
try {
urDTOCreated = await this.myService1.createSomething(urDTO, transactionalEntityManager);
typeDTOCreated = await this.myService2.createSomethingElse(obj1, obj2, transactionalEntityManager);
}
catch (ex) {
Logger.log(ex);
throw new InternalServerErrorException("Error saving data to database");
}
但是,如果文件中除了包含的类之外还有其他类,并且如果您不想使用$predefinedClasses = get_declared_classes();
include('Myclass.php'); // This will show
class A {} // This will not show
print_r(array_diff(get_declared_classes(), $predefinedClasses));
,那么我会想到一个(疯狂的)想法:
Reflection