我正在编写一个类来检查所有依赖项。 其中一个依赖项是继承类。
//File: A.php (For this example, file doesn't exist)
abstract class A{
}
//File: B.php
class B extends A{
}
//File: index.php
$files = scandir("/var/www");
foreach( $files as $class ) {
// Whole script fails here because file A.php doesn't exist.
// Need a graceful check to let the developer know a file is missing.
if( !class_exists($class) ) return false;
// Do other dependency checks.
}
我无法确定如何测试父类是否存在, 没有致命错误
未找到“A”类
我的常见课程有错误处理。 但是对于这个测试用例,我需要能够在不知道名字的情况下测试扩展类。
答案 0 :(得分:2)
这似乎有点像试图找到错误问题的答案,和/或重新发明轮子。当它抛出致命错误时,PHP会为您进行检查。
如果你想以这种方式看待它,你的代码实际上已经有效了。您收到致命错误,因此父类不存在,因此您需要修复代码。确定缺少父类后,您还要做什么?你还需要解决它。
我想说的是,如果你设法摆脱致命的错误,它不会让你到处 - 你的代码仍然有问题,并可能在某个地方崩溃。当然,你可以向用户回应“你有问题”,但这就是PHP已经做的事情。
答案 1 :(得分:1)
您可以测试已经在内存中的任何类定义,无论是否为抽象:
abstract class Foo
{
}
$classes = array('Foo', 'Bar');
foreach ($classes as $class) {
$exists = class_exists($class, FALSE);
printf("Class %s exists%s.\n", $class, $exists ? '' : ' not');
}
输出:
Class Foo exists.
Class Bar exists not.
请参阅class_exists
,该手册为您提供了如何使用该功能控制自动加载的详细信息,它在PHP版本之间进行了更改。
这仅适用于“已加载”类。如果你需要知道光盘上的文件,你需要进行静态代码分析并“自己”读出类定义,因为PHP到目前为止还没有加载文件。
为此,有一个名为staticReflection的项目,它允许您收集有关您只知道文件的类及其接口的信息。它由Manuel Pichler撰写,他提供了有关his Blog的更多信息。
答案 2 :(得分:1)
使用 pomeh 的建议,我创建了一个在同一行搜索“class”和“extends”的函数。它需要一些优化,但它可以工作,所以可以在以后工作。
function is_inherited($filePath) {
$classFileArray = file($filePath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
foreach($classFileArray as $line) {
if( strpos($line, "class") === false ) continue;
if( strpos($line, "extends") === false ) continue;
$extendName = explode('extends', $line);
$extendName = explode( ' ', $extendName[1]);
return $extendName[1];
}
return false;
}
由 hakre 建议的图书馆听起来很有意思,但我认为当一个功能正常工作时会有些过分。
答案 3 :(得分:0)
您可以使用__autoload在任何继承级别加载依赖项而不会出错。
答案 4 :(得分:0)
也许这可能会有所帮助:
$testClass = new ReflectionClass('TestClass');
var_dump( $testClass->isAbstract() );
如果找不到类本身,第一行将抛出异常,如果类是抽象的,则第二行将检查异常。
或者在manual中查找。
如果您正在寻找包含类的所有文件,那么问题标题是错误的,您应该阅读spl_autoload_register()
。
答案 5 :(得分:0)
if(!class_exists("A")){
//do something
print "Missing class A";
}