【问题标题】:Function list of php filephp文件函数列表
【发布时间】:2011-01-12 23:04:08
【问题描述】:

如何获取在 php 文件中声明的函数列表

【问题讨论】:

    标签: php list function


    【解决方案1】:

    您可以使用get_defined_functions()获取当前定义的函数列表:

    $arr = get_defined_functions();
    var_dump($arr['user']);
    

    内部函数位于索引internal,而用户定义函数位于索引user

    请注意,这将输出在该调用之前声明的所有函数。这意味着如果您 include() 带有函数的文件,这些文件也会在列表中。除了确保在调用get_defined_functions() 之前没有include() 任何文件之外,没有办法分离每个文件的函数。


    如果您必须拥有每个文件的函数列表,则以下将尝试通过解析源来检索函数列表。

    function get_defined_functions_in_file($file) {
        $source = file_get_contents($file);
        $tokens = token_get_all($source);
    
        $functions = array();
        $nextStringIsFunc = false;
        $inClass = false;
        $bracesCount = 0;
    
        foreach($tokens as $token) {
            switch($token[0]) {
                case T_CLASS:
                    $inClass = true;
                    break;
                case T_FUNCTION:
                    if(!$inClass) $nextStringIsFunc = true;
                    break;
    
                case T_STRING:
                    if($nextStringIsFunc) {
                        $nextStringIsFunc = false;
                        $functions[] = $token[1];
                    }
                    break;
    
                // Anonymous functions
                case '(':
                case ';':
                    $nextStringIsFunc = false;
                    break;
    
                // Exclude Classes
                case '{':
                    if($inClass) $bracesCount++;
                    break;
    
                case '}':
                    if($inClass) {
                        $bracesCount--;
                        if($bracesCount === 0) $inClass = false;
                    }
                    break;
            }
        }
    
        return $functions;
    }
    

    使用风险自负。

    【讨论】:

    • get_defined_functions() 从所有文件中获取我声明的所有函数,而不是从一个文件中!
    • @zumrasha:查看我更新的答案,它将为您提供每个文件的可用功能列表。
    • 任何使用它的人都可能想将T_CURLY_OPEN添加到开关中以捕获"hello {$name}"等字符串
    【解决方案2】:

    您可以在包含文件之前和之后使用 get_defined_functions(),然后查看第二次添加到数组中的内容。由于它们似乎是按定义顺序排列的,因此您可以像这样使用索引:

      $functions = get_defined_functions();
      $last_index = array_pop(array_keys($functions['user']));
      // Include your file here.
      $functions = get_defined_functions();
      $new_functions = array_slice($functions['user'], $last_index);
    

    【讨论】:

      【解决方案3】:

      您可以使用get_defined_functions() 函数来获取当前脚本中定义的所有函数。

      见:http://www.php.net/manual/en/function.get-defined-functions.php

      如果你想获取另一个文件中定义的函数,你可以尝试像这样使用http://www.php.net/token_get_all

      $arr = token_get_all(file_get_contents('anotherfile.php'));
      

      然后您可以循环查找已定义符号的函数标记。令牌列表可以找到http://www.php.net/manual/en/tokens.php

      【讨论】:

      • get_defined_functions() 从所有文件中获取我声明的所有函数,而不是从一个文件中!
      • 已更新。您可能想使用token_get_all()。如果你使用includes和requires,其他文件中定义的函数也会在这个文件中定义。
      【解决方案4】:

      如果您不担心发现一些被注释掉的,这可能是最简单的方法:

      preg_match_all('/function (\w+)/', file_get_contents(__FILE__), $m);
      var_dump($m[1]);
      

      【讨论】:

      • 这不是“函数感知”技术,如果字符串 看起来 像函数声明,但实际上不是。
      【解决方案5】:

      我写了这个小函数来返回文件中的函数。

      https://gist.github.com/tonylegrone/8742453

      它返回一个包含所有函数名的简单数组。如果您在要扫描的特定文件中调用它,您可以使用以下内容:

      $functions = get_functions_in_file(__FILE__);

      【讨论】:

        【解决方案6】:

        我用array_diff解决了这个问题

        $funcs = get_defined_functions()["user"];
        
        require_once 'myFileWithNewFunctions.php'; // define function testFunc() {} here
        
        var_dump( array_values( array_diff(get_defined_functions()["user"], $funcs) ) )
        // output: array[ 0 => "test_func"]
        

        更新

        要获得“真正的”函数名称,试试这个

        foreach($funcsDiff AS $newFunc) {
           $func = new \ReflectionFunction($newFunc);
           echo $func->getName(); // testFunc
        }
        

        【讨论】:

          【解决方案7】:

          好吧,如果你需要这样做,我会告诉你:

          示例文件:Functions.php(我只是写了一些随机的东西并不能适用于所有东西)

          <?php
          
              // gewoon een ander php script. door het gebruiken van meerdere includes kun je gemakkelijk samen aan één app werken
          
              function johannes($fnaam, $mode, $array){
          
                  switch ($mode) {
                      case 0:
                          echo "
                                  <center>
                                  <br><br><br><br><br>
                                      he johannes!<br><br>
          
                                      klik hier voor random text:<br>
                                      <input type='submit' value='superknop' id='btn' action='randomding' level='0' loadloc='randomshit' />
                                      <p id='randomshit'></p>
                                  </center>
                               ";
                          break;
                      case 1:
                          echo "bouw formulier";
                          break;
                      case 2:
                          echo "verwerk formulier";
                          break;
                       default:
                          echo "[Error: geen mode gedefinieerd voor functie '$fnaam'!]";
                  }
              }
          
              function randomding($fnaam, $mode, $array){
          
                  $randomar = array('He pipo wat mot je!','bhebhehehehe bheeeee. rara wie ben ik?','poep meloen!','He johannes, wat doeeeeee je? <input type="text" name="doen" class="deze" placeholder="Wat doe je?" /> <input type="button" value="vertellen!" id="btn" action="watdoetjho" level="0" loadloc="hierzo" kinderen="deze"> <p id="hierzo"></p>','knopje de popje opje mopje','abcdefghijklmnopqrstuvwxyz, doe ook nog mee','Appien is een **p!!!!!! hahhahah<br><br><br><br> hahaha','Ik weet eiegelijk niks meer te verzinnen','echt ik weet nu niks meer','nou oke dan[[][(!*($@#&*$*^éäåðßð','he kijk een microboat: <br> <img src="https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcS_n8FH6xzf24kEc31liZF6ULHCn2IINFurlFZ_G0f0_F4sLTi74w" alt="microboat" />');
          
                  $tellen = count($randomar);
                  $tellen--;
          
                  $rand = rand(0, $tellen);
          
                  echo $randomar[$rand];
              }
          
              function watdoetjho($fnaam, $mode, $array){
          
                  $dit = $array['doen'];
                  echo "Johannes is: $dit";
          
              }
          
          ?>
          

          我们这里有 3 个函数:

          1. 约翰内斯
          2. 随机
          3. watdoetjho

          但我们也称这些函数为:

          1. 计数
          2. 兰德

          如果我们使用get_defined_functions,我们将获得脚本范围内的所有函数。是的,PHP 函数与用户声明的函数是分开的,但我们仍然希望来自特定文件。

          如果我们使用token_get_all,我们会收到大量需要先分离的数据。

          我找到了这些数字,我们需要在数组中建立一些连接以匹配用户函数。否则,我们将得到一个列表,其中包含所有调用的 php 函数。

          数字是:

          • 334(所有用户声明函数的列表)
          • 307(所有函数名的列表)

          如果我们过滤数组以获取所有 334 个元素,我们有这样的:

          334 -|- 函数 -|- 5

          但是我们需要函数名,并且所有数组元素都与第三个值相关。所以现在我们需要过滤所有匹配第三个值(5)和常数307的数组元素。

          这会给我们这样的东西:

          307 -|- 约翰内斯 -|- 5

          现在在 PHP 中它看起来像这样:

          <?php
              error_reporting(E_ALL ^ E_NOTICE); // Or we get these undefined index errors otherwise use other method to search array
          
              // Get the file and get all PHP language tokens out of it
              $arr = token_get_all(file_get_contents('Functions.php'));
          
              //var_dump($arr); // Take a look if you want
          
              //The array where we will store our functions
              $functions = array();
          
              // loop trough
              foreach($arr as $key => $value){
          
                      //filter all user declared functions
                  if($value[0] == 334){
                             //Take a look for debug sake
                      //echo $value[0] .' -|- '. $value[1] . ' -|- ' . $value[2] . '<br>';
          
                              //store third value to get relation
                              $chekid = $value[2];
                  }
          
                      //now list functions user declared (note: The last check is to ensure we only get the first peace of information about the function which is the function name, else we also list other function header information like preset values)
                  if($value[2] == $chekid && $value[0] == 307 && $value[2] != $old){
          
                              // just to see what happens
                              echo $value[0] .' -|- '. $value[1] . ' -|- ' . $value[2] . '<br>';
                              $functions[] = $value[1];
                              $old = $chekid; 
                  }
              }
          ?>
          

          这种情况下的结果是:

          307 -|- johannes -|- 5
          307 -|- randomding -|- 31
          307 -|- watdoetjho -|- 43
          

          【讨论】:

            【解决方案8】:

            要获取代码中已定义和使用的函数列表,通过小型有用的文件管理器,您可以使用下面的代码。享受吧!

            if ((!function_exists('check_password'))||(!check_password()) ) exit('Access denied.'); //...security!
            
            echo "<html><body>";
            if (!$f)    echo nl2br(htmlspecialchars('
                Useful parameters:
                $ext - allowed extensions, for example: ?ext=.php,css
                $extI - case-insensitivity, for example: ?extI=1&ext=.php,css
            '));
            
            if (($f)&&(is_readable($_SERVER['DOCUMENT_ROOT'].$f))&&(is_file($_SERVER['DOCUMENT_ROOT'].$f))) {
            
                echo "<h3>File <strong>$f</strong></h3>\n";
            
                if(function_exists('get_used_functions_in_code')) {
                    echo '<h3>Used:</h3>';
                    $is=get_used_functions_in_code(file_get_contents($_SERVER['DOCUMENT_ROOT'].$f));
                    sort($is);
                    $def=get_defined_functions();
                    $def['internal']=array_merge($def['internal'], array('__halt_compiler', 'abstract', 'and', 'array', 'as', 'break', 'callable', 'case', 'catch', 'class', 'clone', 'const', 'continue', 'declare', 'default', 'die', 'do', 'echo', 'else', 'elseif', 'empty', 'enddeclare', 'endfor', 'endforeach', 'endif', 'endswitch', 'endwhile', 'eval', 'exit', 'extends', 'final', 'finally', 'for', 'foreach', 'function', 'global', 'goto', 'if', 'implements', 'include', 'include_once', 'instanceof', 'insteadof', 'interface', 'isset', 'list', 'namespace', 'new', 'or', 'print', 'private', 'protected', 'public', 'require', 'require_once', 'return', 'static', 'switch', 'throw', 'trait', 'try', 'unset', 'use', 'var', 'while'));
                    foreach ($def['user'] as &$e) $e=strtolower($e); unset($e);
                    foreach ($is as &$e) if (!in_array(strtolower($e), $def['internal'], TRUE)) $e='<span style="color: red">'.$e.'</span>'; unset($e); //user-defined functions will be red
                    echo implode('<br />'.PHP_EOL,$is);
                }
                else echo "Error: missing function 'get_used_functions_in_code' !";
                if(function_exists('get_defined_functions_in_code')) {
                    echo '<br /><h3>Defined:</h3>';
                    $is=get_defined_functions_in_code(file_get_contents($_SERVER['DOCUMENT_ROOT'].$f));
                    sort($is);
                    echo implode('<br />',$is);
                }
                else echo "Error: missing function 'get_defined_functions_in_code' !";
            }
            
            /*
                File manager
            */
            else {
                if (!function_exists('select_icon')) {
                    function select_icon($name) {$name = pathinfo($name); return '['.$name["extension"].']';}
                }
            
                if($ext) $extensions=explode(',',strrev($ext));
                if(!$f) $f=dirname($_SERVER['PHP_SELF']);
                echo "<h3>Dir ".htmlspecialchars($f)."</h3><br />\n<table>";
                $name=scandir($_SERVER['DOCUMENT_ROOT'].$f);
            
                foreach($name as $name) {
                    if (!($fileOK=(!isset($extensions)))) {
                        foreach($extensions as $is) if (!$fileOK) $fileOK=((strpos(strrev($name),$is)===0)||($extI &&(stripos(strrev($name),$is)===0)));
                    }
                    $is=is_dir($fullName=$_SERVER['DOCUMENT_ROOT']."$f/$name");
                    if ($is || $fileOK) echo '<tr><td>'.select_icon($is ? 'x.folder' : $name).'&nbsp;</td><td>&nbsp;'.($is ? '[' : '').'<a href="?f='.rawurlencode("$f/$name").($extI ? "&extI=$extI" : '').($ext ? "&ext=$ext" : '').'">'.htmlspecialchars($name).'</a>'.($is ? ']' : '').'</td>';
                    if ($is) echo '<td>&nbsp;</td><td>&nbsp;</td>';
                    elseif ($fileOK) echo '<td style="text-align: right">&nbsp;'.number_format(filesize($fullName),0,"."," ").'&nbsp;</td><td>&nbsp;'.date ("Y.m.d (D) H:i",filemtime($fullName)).'</td>';
                    if ($is || $fileOK) echo '</tr>'.PHP_EOL;
                }
                echo "\n</table>\n";
            }
            
            echo "<br /><br />".date ("Y.m.d (D) H:i")."</body></html>";
            return;
            
            /********************************************************************/
            
            
            function get_used_functions_in_code($source) {
                $tokens = token_get_all($source);
                $functions = array();
                $thisStringIsFunc = 0;
            
                foreach($tokens as $token) {
                    if(($token[0]!=T_WHITESPACE)&&((!is_string($token))||($token[0]!='('))) unset($func);
                    if((is_array($token))&&(in_array($token[0],array(T_EVAL,T_EXIT,T_INCLUDE,T_INCLUDE_ONCE,T_LIST,T_REQUIRE,T_REQUIRE_ONCE,T_RETURN,T_UNSET)))) {$token[0]=T_STRING;$thisStringIsFunc=1;}
                    switch($token[0]) {
                        case T_FUNCTION: $thisStringIsFunc=-1;
                        break;
                        case T_STRING:
                            if($thisStringIsFunc>0) {
                                if (!in_array(strtoupper($token[1]),$functionsUp)) {$functions[]=$token[1];$functionsUp[]=strtoupper($token[1]);}
                                $thisStringIsFunc = 0;
                            } elseif ($thisStringIsFunc+1>0) {
                                $func = $token[1];
                            } else $thisStringIsFunc = 0;
            
                        break;
                        case '(':if($func) if(!in_array(strtoupper($func),$functionsUp)) {$functions[]=$func;$functionsUp[]=strtoupper($func);}
                    }
                }
            
                return $functions;
            }
            
            /********************************************/
            
            function get_defined_functions_in_code($source) {
                $tokens = token_get_all($source);
            
                    ... then Andrew code (get_defined_functions_in_file) (https://stackoverflow.com/a/2197870/9996503)
            }
            

            【讨论】:

              【解决方案9】:

              使用正则表达式在文件中查找字符串(例如函数名称)很简单。 只需读取文件并使用 preg_match_all 解析内容即可。

              我写了一个简单的函数来获取文件中的函数列表。

              https://gist.github.com/komputronika/f92397b4f60870131ef52930faf09983

              $a = functions_in_file( "mylib.php" );
              

              【讨论】:

              • 这不是“函数感知”技术,如果字符串 看起来 像函数声明,但实际上不是。
              【解决方案10】:

              最简单的事情(在我看到@joachim 的回答之后)是使用get_defined_functions,然后只注意“用户”键(其中包含一组用户定义的方法)

              这是帮助我解决问题的代码

              <?php
              //Just to be sure it's empty (as it should be)
              $functions = get_defined_functions();
              print_r($functions['user']); 
              
              //Load the needed file 
              require_once '/path/to/your/file.php';
              
              //display the functions loaded 
              $functions2 = get_defined_functions();
              print_r($functions2['user']);
              

              【讨论】:

                【解决方案11】:

                还要检索参数定义:(Source in comments)

                数组

                (
                    [0] => function foo ( &&bar, &big, [$small = 1] )
                
                    [1] => function bar ( &foo )
                
                    [2] => function noparams (  )
                
                    [3] => function byrefandopt ( [&$the = one] )
                
                )
                

                $functions = get_defined_functions();
                $functions_list = array();
                foreach ($functions['user'] as $func) {
                        $f = new ReflectionFunction($func);
                        $args = array();
                        foreach ($f->getParameters() as $param) {
                                $tmparg = '';
                                if ($param->isPassedByReference()) $tmparg = '&';
                                if ($param->isOptional()) {
                                        $tmparg = '[' . $tmparg . '$' . $param->getName() . ' = ' . $param->getDefaultValue() . ']';
                                } else {
                                        $tmparg.= '&' . $param->getName();
                                }
                                $args[] = $tmparg;
                                unset ($tmparg);
                        }
                        $functions_list[] = 'function ' . $func . ' ( ' . implode(', ', $args) . ' )' . PHP_EOL;
                }
                print_r($functions_list);
                

                【讨论】:

                  【解决方案12】:

                  在文件中包含并试试这个:

                  $functions = get_defined_functions();
                  print_r($functions['user']);
                  

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2014-06-18
                    • 2011-01-29
                    • 2012-03-19
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多