2013-09-05 38 views
-1

我需要一個PHP腳本,它將讀取其他PHP源文件並提取include,require和require函數中引用的文件路徑。我特別要求這樣做來創建一個部署項目,以便輸出包只能包含項目中使用的庫文件夾中的文件。從一組特定的PHP源文件中獲取包含文件的列表

PHP中是否有任何函數可以讀取源文件並在require,include和require_once語句中提取路徑?

+0

請包括您嘗試過的代碼和出錯的地方。詢問代碼的問題必須證明對所解決問題的最小理解。包括嘗試解決方案,爲什麼他們沒有工作,以及預期的結果。 http://meta.stackexchange.com/questions/156810/stack-overflow-question-checklist – showdev

+0

沒有出錯。只需要一個算法來解析源文件並提取路徑 –

+0

以某種方式使用[get_included_files](http://www.php.net/manual/en/function.get-included-files.php)。 –

回答

1

下面是正確的答案,它實際上解析PHP語法。請注意,真正做你想做的事是不可能的。例如,您可能有自動加載程序,或者不能自動提取的可變包含路徑。

<?php 
$required_file = ''; 
$required_files = array(); 
$is_required_file = false; 

// Parse the PHP source using the Tokenizer library (PHP 4.3.0+) 
$tokens   = token_get_all($text); 

foreach ($tokens as $token) { 
    // Get the token name to make our code more readable. 
    $token_name = is_int($token[0]) ? token_name($token[0]) : $token[0]; 

    echo $token[0]. ': ' . htmlentities($token[1]) . '<br>'; 

    // Is this token a require/include keyword? 
    if (in_array($token_name, array('T_INCLUDE', 'T_INCLUDE_ONCE', 'T_REQUIRE', 'T_REQUIRE_ONCE'))) { 
     $is_required_file = true; 
    } 

    elseif ($is_required_file && $token[0] != ';' && $token[0] != '.' && $token_name != 'T_WHITESPACE') { 
     if ($token_name == 'T_STRING') { 
      $token[1] = '{{CONST:' . $token[1] . '}}'; 
     } 
     $required_file .= $token[1] ? trim($token[1], '\'"') : $token[0]; 
    } 

    elseif ($is_required_file && $token[0] == ';') { 
     $is_required_file = false; 
     $required_files[] = trim($required_file, '()'); 
     $required_file = ''; 
    } 
} 

$required_files是這些文件的數組。匹配require,require_once, includeinclude_once

對於以下輸入:

<?php 
include APPLICATION_MODULES_ROOT . 'test1.php'; 
include($some_var . 'test55.php'); 
include('test2.php'); 
include ('test3.php'); 
include_once 'test4.php'; 
include_once('test5.php'); 
include_once ('test6.php'); 
require 'test7.php'; 
require('test8.php'); 
require ('test9.php'); 
//require ('test99.php'); 
require_once 'test10.php'; 
require_once('test11.php'); 
require_once ('test12.php'); 

你結束了這個:

Array 
(
    [0] => {{CONST:APPLICATION_MODULES_ROOT}}test1.php 
    [1] => test55.php 
    [2] => test2.php 
    [3] => test3.php 
    [4] => test4.php 
    [5] => test5.php 
    [6] => test6.php 
    [7] => test7.php 
    [8] => test8.php 
    [9] => test9.php 
    [10] => test10.php 
    [11] => test11.php 
    [12] => test12.php 
) 

所有你需要做的就是更換您的應用程序使用,使用str_replace函數或類似的常量。

重要提示:這不適用於變量包含名稱,例如include $some_path;。你無法解析這些。

+0

我也試過這個,但這給出了錯誤:警告:token_name()期望參數1很長,字符串在378行的F:\ dev \ htdocs \ package.php中給出378行引用:$ token_name = token_name($令牌[0]); –

+0

@ asim-ishaq更新我的代碼,一時刻 –

+0

我已經進一步討論了這個算法。 $ token [0]通常包含一個數字,但不是全部。一些無效值如下:,; )} {[我可以添加一個代碼檢查,以便它檢查一個數字的$ token [0],然後進一步處理? –

1

嘗試這樣:

<?php 
$source = file_get_contents('source.php'); 
preg_match_all('/(include|include_once|require|require_once) *\(? *[\'"](.*?)[\'"] *\)? *;/', $source, $matches); 
$files = $matches[2]; 

$files現在被列入/所需的文件的數組。

儘管這不是一個合適的解決方案,因爲它會匹配註釋掉的代碼。

+0

我在項目中試過這個解決方案。它提取像require(「myfile.php」)這樣的語法的文件名。我的項目有這樣的代碼(APPLICATION_MODULES_ROOT。「\\ pages \\ Screen.php」);但它不會讀取我的代碼。讓我試試你的其他解決方案。 –

+0

@ asim-ishaq我明白了。我的另一個例子不適用於你所需要的。 –

相關問題