проверьте, существует ли абстрактный класс - PullRequest
1 голос
/ 11 марта 2012

Я пишу класс, чтобы проверить все мои зависимости. Одной из этих зависимостей являются унаследованные классы.

//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' не найден

У меня есть обработка ошибок для моих общих классов. Но для этого теста мне нужно иметь возможность тестировать расширенные классы, не зная их имени.

Ответы [ 6 ]

2 голосов
/ 11 марта 2012

Это похоже на попытку найти ответ на неправильный вопрос и / или изобретать велосипед.PHP выполнит вашу проверку, когда выдает фатальную ошибку.

Если вы хотите посмотреть на это таким образом, ваш код на самом деле уже работает.Вы получаете фатальную ошибку, поэтому родительский класс не существует, поэтому вам нужно исправить свой код.Установив, что родительский класс отсутствует, что еще вы собираетесь делать?Вам все еще нужно это исправить.

Я пытаюсь сказать, что если вам удалось избавиться от фатальной ошибки, это никуда вас не приведет - ваш код по-прежнему неисправен и, вероятно, где-то рухнет.дальше по линии.Конечно, вы можете повторить «у вас есть проблема» для пользователя, но это то, что PHP уже делает.

1 голос
/ 11 марта 2012

Используя предложение 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 звучит интересно, но излишне, я думаю, когда одна функция будет работать нормально.

1 голос
/ 11 марта 2012

Вы можете проверить любое определение класса, которое уже находится в памяти, абстрактное или нет:

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 , который позволит вам собрать информацию о классах и их интерфейсах, файл которых вы знаете только. Он был написан Мануэлем Пихлером, у которого есть больше информации о его блоге .

0 голосов
/ 11 марта 2012
if(!class_exists("A")){
    //do something
    print "Missing class A";
}
0 голосов
/ 11 марта 2012

Может быть, это может помочь:

  $testClass = new ReflectionClass('TestClass');
  var_dump( $testClass->isAbstract() );

Первая строка выдаст исключение, если сам класс не найден, а вторая проверит, является ли класс абстрактным.

Или посмотрите это в руководстве .

Если вы ищете, чтобы все файлы, содержащие классы, были включены, тогда неправильный заголовок вопроса , и вам следует прочитать о spl_autoload_register().

0 голосов
/ 11 марта 2012

Вы можете использовать __ autoload для загрузки зависимостей на любом уровне наследования без ошибок.

...