代码之家  ›  专栏  ›  技术社区  ›  Alix Axel

在PHP中解析类、函数和参数

  •  5
  • Alix Axel  · 技术社区  · 15 年前

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

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

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

    4 回复  |  直到 9 年前
        1
  •  8
  •   Davide Gualano    15 年前

    如果您使用的是PHP5, 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();
            }
    }
    
        2
  •  1
  •   André Hoffmann    15 年前

    我建议采用以下程序:

    1. 存储的当前输出 get_declared_classes , get_declared_interfaces get_defined_functions (如果你真的需要支持他们)
    2. 包括文件
    3. 比较 获取已声明的类 , 获取已声明的接口 和G et_defined_functions 用你储存的那些看看有什么新的
    4. 使用反射来分析它们
    5. 转到下一个文件的步骤2
        3
  •  1
  •   Pascal MARTIN    15 年前

    就像你自己发现的那样,Regex并不是合适的工具^^

    而且,正如您所说,您提议的内置函数也没有那么有帮助——唯一可能有帮助的是它们允许您知道存在哪个类……但它们也会返回内置类:-(

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


    从那里,你应该能再挖一点,然后达到你第一次问的目的;-)


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

    如果有人有主意,欢迎!

        4
  •  0
  •   MattBelanger    15 年前

    我不能帮你解决你的特定问题,因为我也从来没有用过记号赋予器。

    你没有提到你用这个做什么,但是像phpdoc这样的东西会做你需要的吗?