0

我正在尝试获取包含在 php 脚本中的所有文件的列表。

我正在阅读整个文件,其中包含以下内容:

<?php
    echo 'Hello there';

    include 'some_functions.php';

    echo 'Trying to find some includes.';

    include 'include_me.php';

    echo 'Testtest.';
?>

然后,我在该文件上运行此代码:

if (preg_match_all ("/(include.*?;){1}/is", $this->file_contents, $matches))
  {
      print_r($matches);
  }

当我运行这个匹配时,我得到了预期的结果......这是两个包含部分,但我也得到了完全相同的东西的重复,或者包含语句的随机块。以下是输出示例:

    Array ( 
[0] => Array ( [0] => include 'some_functions.php'; [1] => include 'include_me.php'; ) 
[1] => Array ( [0] => include 'some_functions.php'; [1] => include 'include_me.php'; ) ) 

如您所见,它多次嵌套具有相同结果的数组。对于每个包含语句,我需要数组中的 1 项,没有重复,没有嵌套数组。

我在使用这些正则表达式时遇到了一些问题,所以一些指导会很好。感谢您的时间。

4

3 回答 3

4

这个如何

<?php
  preg_match_all( "/include(_once)?\s*\(?\s*(\"|')(.*?)\.php(\"|')\s*\)?\s*;?/i", $this->file_contents, $matches );
  // for file names
  print_r( $matches[3] );
  // for full lines
  print_r( $matches[0] );
?>

如果你想要一个更好更干净的方法,那么唯一的方法就是 phptoken_get_all

<?php
  $tokens = token_get_all( $this->file_contents );
  $files  = array();
  $index  = 0;
  $found  = false;
  foreach( $tokens as $token ) {
    // in php 5.2+ Line numbers are returned in element 2
    $token  = ( is_string( $token ) ) ? array( -1, $token, 0 ) : $token;
    switch( $token[0] ) {
      case T_INCLUDE:
      case T_INCLUDE_ONCE:
      case T_REQUIRE:
      case T_REQUIRE_ONCE:
        $found  = true;
        if ( isset( $token[2] ) ) {
          $index  = $token[2];
        }
        $files[$index]  = null;
      break;

      case T_COMMENT:
      case T_DOC_COMMENT:
      case T_WHITESPACE:
      break;

      default:
        if ( $found && $token[1] === ";" ) {
          $found  = false;
          if ( !isset( $token[2] ) ) {
            $index++;
          }
        }
        if ( $found ) {
          if ( in_array( $token[1], array( "(", ")" ) ) ) {
            continue;
          }
          if ( $found ) {
            $files[$index]  .=  $token[1];
          }
        }
      break;
    }
  }
  // if your php version is above 5.2
  // $files index will be line numbers
  print_r( $files );
?>
于 2013-06-23T22:07:53.890 回答
3

如果不包含脚本,则使用get_included_files(), 或内置标记器

我正在搜索其他文件内容的字符串,而不是当前文件

那么你最好的选择是分词器。尝试这个:

$scriptPath = '/full/path/to/your/script.php';
$tokens = token_get_all(file_get_contents($scriptPath));
$matches = array();
$incMode = null;

foreach($tokens as $token){

  // ";" should end include stm.
  if($incMode && ($token === ';')){
    $matches[] = $incMode;
    $incMode = array();
  }

  // keep track of the code if inside include statement
  if($incMode){
    $incMode[1] .= is_array($token) ? $token[1] : $token;
    continue;
  }  

  if(!is_array($token))
    continue;

  // start of include stm.
  if(in_array($token[0], array(T_INCLUDE, T_INCLUDE_ONCE, T_REQUIRE, T_REQUIRE_ONCE)))
    $incMode = array(token_name($token[0]), '');
}

print_r($matches); // array(token name, code)
于 2013-06-23T22:00:34.547 回答
1

请阅读,preg_match_all的工作原理

数组中的第一项 - 它返回正则表达式中的所有文本。数组中的下一项 - 这是来自正则表达式的文本(在括号中)。

你应该使用 $matches[1]

于 2013-06-23T22:02:29.420 回答