7

我想创建一个函数,它接收一个包含 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)

此函数应返回给定文件中存在的所有类、方法和函数以及所有定义的标识符(抽象、公共、私有、受保护、静态、扩展、接口......)。

我的第一个难题是使用正则表达式来执行此操作,但是这些对注释的表现非常糟糕,即: /* this function returns(max(salary)) */ 如果我想正确支持范围,它会变得非常复杂。

另一种可能的解决方案是使用以下内置 PHP 函数:

get_declared_classes
get_declared_interfaces
get_defined_functions
get_class_methods

但是,这些函数不允许我查看定义类/方法/函数的文件,因此它不是很有用。

我相信 Tokenizer 扩展是我的问题的解决方案,但是我以前从未使用过这个扩展。

4

3 回答 3

10

如果您使用的是 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();
        }
}
于 2009-09-12T12:14:28.813 回答
2

就像你自己发现的那样,正则表达式不是适合这项工作的工具,在这里^^

而且,就像你说的,你提出的内置函数也没有那么有用——唯一可能有用的是它们让你知道存在哪个类......但它们也会返回内置类:-(

使用 Tokenizer 扩展对我来说似乎有点矫枉过正/很难;实际上,我可能不会那样做:我想这太“低级”了。


相反,我会看一下 PHP 的Reflection 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)


从那里,您应该可以挖掘更多;并达到您首先提出的要求;-)


作为旁注:我不知道的一件事是:“如何找到在给定文件中声明的类/方法”:-(

如果有人有想法,将受到欢迎!

于 2009-09-12T12:03:26.787 回答
2

我建议以下程序:

  1. 存储,的当前输出get_declared_classes和(如果你真的需要支持它们)get_declared_interfacesget_defined_functions
  2. 包括文件
  3. 比较get_declared_classes,get_declared_interfaces和 get_defined_functions与您存储的那些以查看新功能
  4. 使用反射来分析它们
  5. 转到下一个文件的第 2 步
于 2009-09-12T12:19:41.627 回答