Вопрос

Я хочу создать функцию, которая получает один аргумент, содержащий путь к файлу PHP, а затем анализирует данный файл и возвращает что-то вроде этого:

class NameOfTheClass
   function Method1($arg1, $arg2, $arg2)
   private function Method2($arg1, $arg2, $arg2)
   public function Method2($arg1, $arg2, $arg2)

abstract class AnotherClass
   function Method1($arg1, $arg2, $arg2)
   private function Method2($arg1, $arg2, $arg2)
   public function Method2($arg1, $arg2, $arg2)

function SomeFunction($arg1, $arg2, $arg3)

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

Моей первой мыслью было использовать для этого регулярные выражения, однако они плохо себя ведут с комментариями, т.е.:/* эта функция возвращает(max(salary)) */ и становится довольно сложной, если я хочу правильно поддерживать области.

Другим возможным решением было использование следующих встроенных функций PHP:

get_declared_classes
get_declared_interfaces
get_defined_functions
get_class_methods

Однако эти функции не позволяют мне видеть файл, в котором определены классы/методы/функции, и поэтому это не очень полезно.

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

Это было полезно?

Решение

Если вы используете PHP 5, API отражения это ваш инструмент.

Пример:

$class = new ReflectionClass("NameOfTheClass");
$methods = $class->getMethods();
foreach($methods as $m) {
    print $m->name;
    $m->isPrivate() ? print "Private" : print "";
    $m->isPublic() ? print "Public" : print "";
    $params = $m->getParameters();
    foreach($params as $p) {
        print $p->getName();
        }
}

Другие советы

Я предлагаю следующую процедуру:

<Ол>
  • хранит текущий вывод get_declared_classes , get_declared_interfaces и get_defined_functions (если вам действительно нужно их поддерживать)
  • включить файл
  • сравните get_declared_classes , get_declared_interfaces и g et_defined_functions с теми, которые вы сохранили, чтобы увидеть, что нового
  • использовать отражение, чтобы проанализировать их
  • перейдите к шагу 2 для следующего файла
  • Как вы сами выяснили, регулярные выражения — совершенно неподходящий инструмент для этой работы, здесь ^^

    И, как вы сказали, предложенные вами встроенные функции тоже не так уж и полезны - единственное, что может быть полезно, это то, что они позволяют вам узнать, какой класс существует...Но они также вернут встроенные классы :-(

    Использование расширения Tokenizer кажется мне немного излишним/сложным;На самом деле, я бы, наверное, не пошел по этому пути:слишком "низкоуровневый", я полагаю.


    Вместо этого я бы взглянул на PHP API отражения :он существует именно для обратного проектирования классов, интерфейсов, функций...

    Итак, я полагаю, что это вполне подходит для того, что вы пытаетесь сделать.


    Редактировать :вот краткий пример:

    Во-первых, давайте попробуем отразить класс:

    include dirname(__FILE__) . '/temp-2.php';
    $rC = new ReflectionClass('MyFirstClass');
    

    Теперь вы можете узнать, в каком файле он был объявлен и какие методы в нем есть:

    var_dump($rC->getFileName());
    var_dump($rC->getMethods());
    

    Что даст вам:

    string '/home/squale/developpement/tests/temp/temp-2.php' (length=48)
    
    array
      0 => &
        object(ReflectionMethod)[2]
          public 'name' => string '__construct' (length=11)
          public 'class' => string 'MyFirstClass' (length=12)
      1 => &
        object(ReflectionMethod)[3]
          public 'name' => string 'glop' (length=4)
          public 'class' => string 'MyFirstClass' (length=12)
    


    А теперь, чтобы получить информацию о каждом методе:

    foreach ($rC->getMethods() as $rM) {
        var_dump($rM, $rM->getParameters());
        echo '-----';
    }
    

    Ты получишь :

    object(ReflectionMethod)[3]
      public 'name' => string '__construct' (length=11)
      public 'class' => string 'MyFirstClass' (length=12)
    
    array
      0 => &
        object(ReflectionParameter)[4]
          public 'name' => string 'arg1' (length=4)
      1 => &
        object(ReflectionParameter)[5]
          public 'name' => string 'arg2' (length=4)
    
    -----
    
    object(ReflectionMethod)[2]
      public 'name' => string 'glop' (length=4)
      public 'class' => string 'MyFirstClass' (length=12)
    
    array
      0 => &
        object(ReflectionParameter)[5]
          public 'name' => string 'a' (length=1)
    


    Оттуда вы сможете покопать еще немного;и придем к тому, что вы сначала спросили ;-)


    В качестве примечания:есть одна вещь, о которой я понятия не имею:"как узнать, какие классы/методы объявлены в данном файле" :-(

    Если у кого-то есть идеи, буду рад!

    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top