【问题标题】:Parsing Classes, Functions and Arguments in PHP在 PHP 中解析类、函数和参数
【发布时间】:2009-09-12 11:56:36
【问题描述】:

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

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

我的第一个技巧是使用正则表达式来执行此操作,但是这些表达式在 cmets 中表现得非常糟糕,即:/* 这个函数返回(max(salary))*/ 如果我想正确支持范围,它会变得非常复杂。

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

get_declared_classes
get_declared_interfaces
get_defined_functions
get_class_methods

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

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

【问题讨论】:

  • 我无法帮助您解决您的特定问题,因为我也从未使用过 Tokenizer。你没有提到你用这个做什么,但是像 phpDoc 这样的东西能满足你的需要吗?
  • 我需要的基本上是一个精简的 phpDoc 版本,没有 phpDoc 的麻烦,基本上我只想了解任何给定文件的所有可用方法和参数 - 这将超过对我来说足够了。

标签: php parsing tokenize code-analysis


【解决方案1】:

如果您使用的是 PHP 5,Reflection 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_defined_functions() 来获取您定义的所有函数,而不是使用 ReflectionFunction 类 (php.net/manual/en/class.reflectionfunction.php) 来分析它们。
【解决方案2】:

我建议以下程序:

  1. 存储get_declared_classesget_declared_interfacesget_defined_functions的当前输出(如果你真的需要支持的话)
  2. 包含文件
  3. get_declared_classesget_declared_interfaces 和 get_defined_functions 与您存储的比较,看看有什么新变化
  4. 使用反射来分析它们
  5. 转到下一个文件的第 2 步

【讨论】:

    【解决方案3】:

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

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

    使用 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)
    


    从那里,您应该可以挖掘更多;并达到你第一次问的问题;-)


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

    如果有人有想法,欢迎提出!

    【讨论】:

    • 谢谢,看来反射 API 是解决我的问题的有力候选者。你知道我在哪里可以看到与我的问题类似的实现示例吗?另外,Reflection API 是否允许我区分找到的方法/类在哪些文件中?
    • 嗨!我已经编辑了我的答案以提供一些示例 :-) 希望这会有所帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-11
    • 1970-01-01
    • 2018-09-04
    • 1970-01-01
    • 2020-08-19
    相关资源
    最近更新 更多