2011-12-22 72 views
1

我正在研究一個腳本,它用一個字符串替換目錄和子目錄中的所有文件,以擺脫我們的軟件顯示的通用錯誤消息。在PHP中循環瀏覽目錄?

我使用單個目錄中的所有文件很容易地工作,但後來我們在一個包含子目錄的文件夾中運行它,正如您可能猜到的那樣,它會拋出很多錯誤。我完全忘記了子目錄。

所以,現在我正在製作一個可以與子目錄一起工作的腳本,但我很難過。

這裏是我的代碼:

<?php 

$files = explode("\n", shell_exec('ls')); 
$count = 0; 

foreach ($files as $file) 
{ 
    if (empty($file) || $file == $_SERVER['SCRIPT_NAME']) 
    { 
     continue; 
    } 
    if (is_dir($file)) 
    { 
     echo "Copying to {$file}/{$_SERVER['SCRIPT_NAME']}\n"; 
     copy($_SERVER['SCRIPT_NAME'], $file . "/" . $_SERVER['SCRIPT_NAME']); 
     exec("php {$file}/{$_SERVER['SCRIPT_NAME']}"); 
     unlink($file . "/" . $_SERVER['SCRIPT_NAME']); 
     continue; 
    } 
    $fh = fopen($file, 'w'); 
    fwrite($fh, '<!-- Generated %T by %h (%s) -->'); 
    fclose($fh); 
    echo "Rewrote {$file}\n"; 
    $count++; 
} 
echo "Finished. Rewrote {$count} files. Don't forget to delete {$_SERVER['SCRIPT_NAME']}.\n"; 

?> 

它結束了這個輸出:

[[email protected] orgytest]# php p.php 
Rewrote blah 
Rewrote dfas 
Rewrote dfasfsdjkfjsa 
Rewrote dfdsafdsaf 
Rewrote dfsaf 
Rewrote orgy 
Rewrote query 
Rewrote scsew 
Copying to test/p.php 
Rewrote blah 
Rewrote dfas 
Rewrote dfasfsdjkfjsa 
Rewrote dfdsafdsaf 
Rewrote dfsaf 
Rewrote orgy 
Rewrote p.php 
Rewrote query 
Rewrote scsew 
Copying to test/test/p.php 
PHP Warning: copy(test/test/p.php): failed to open stream: No such file or directory in /root/orgytest/test/p.php on line 15 
Could not open input file: test/test/p.php 
PHP Warning: unlink(test/test/p.php): No such file or directory in /root/orgytest/test/p.php on line 17 
Copying to test2/test/p.php 
PHP Warning: copy(test2/test/p.php): failed to open stream: No such file or directory in /root/orgytest/test/p.php on line 15 
Could not open input file: test2/test/p.php 
PHP Warning: unlink(test2/test/p.php): No such file or directory in /root/orgytest/test/p.php on line 17 
Finished. Rewrote 9 files. Don't forget to delete test/p.php. 
Copying to test2/p.php 
<!-- Generated %T by %h (%s) -->Finished. Rewrote 8 files. Don't forget to delete p.php. 

有什麼奇怪的,在我看來,它正試圖做這樣的事情test/test/p.php而非test/p.php。我認爲這與它在達到該點時從較高的目錄運行的事實有關。

任何人都知道我可以解決這個問題嗎?

+0

有什麼理由不使用' sed'或其他更簡單的linux工具? – 2011-12-22 15:36:56

+0

@tandu,老實說我不知道​​'sed'是什麼。除了我只是一名PHP程序員之外,沒有其他理由。所以我去了PHP。別人真的不知道。 – Rob 2011-12-22 15:40:01

回答

-1

嘗試用這樣的事情:

Codingforums

或嘗試在谷歌搜索「的PHP遞歸目錄列表」或類似的話。

使用readdir()函數,您將獲得特定目錄中的文件和子目錄。所以關鍵是要弄清楚它只是一個文件,或者它是帶有is_dir()函數的子目錄。當你想打開和編輯它時,請確保你將使用子目錄中文件的完整路徑。所以就像我說的嘗試使用谷歌,並找到一些有用的東西。

1

$_SERVER['SCRIPT_NAME']的值可能不是您所期望的,也可能是構建像test/test/p.php這樣的路徑的原因。我的猜測是,當你執行php test/p.php那麼這是值的地方SCRIPT_NAME。你可以使用basename()函數來解決這個問題。

另外,動態創建shell命令時,您應該使用escapeshellarg()。

或者......

$self = realpath(__FILE__); 
$ritit = new RecursiveIteratorIterator(new RecursiveDirectoryIterator(__DIR__)); 
foreach ($ritit as $splFileInfo) { 
    $fileName = $splFileInfo->getRealPath(); 
    if ($fileName !== $self) { 
     file_put_contents($fileName, '<!.....stuff'); 
    } 
} 
+0

它仍在踢我的屁股。感謝代碼,但我想寫我自己的代碼。完成任務當然是首要任務,但我也想自己學習。我將在大約40分鐘後回家,在這一點上,我會在你的basename()建議之後發佈我的新代碼。 – Rob 2011-12-22 16:30:17

0

問題從LS返回基本目錄中的內容,不一定是你的房子腳本一個莖。我真的會避免執行,只是嘗試將你的拷貝抽象成一個函數,使用PHP文件系統函數,並把它變成一個遞歸算法,而不是試圖執行進程。

0

SPL的遞歸迭代器非常適合這個,我會使用類似如下的

<?php 
// get scriptname from $argv[0] 
$scriptname = basename(array_shift($argv)); 

// optional argument indicating path to run this script in (defaults to current path) 
if (!empty($argv[0])) { 
    $workspace = $argv[0]; 
}else { 
    $workspace = getcwd(); 
} 

// Recursively iterate over files in the specified workspace folder and all subfolders 
try { 
    $count = 0; 
    foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($workspace)) as $file) { 
     // ignore the folders, and this script if present 
     if ($file->isDir() || $file->getFilename() == $scriptname) continue; 
     // write the file 
     echo "Writing to $file\n"; 
     file_put_contents($file, '<!-- Generated %T by %h (%s) -->'); 
     $count++; 
    } 
    echo "Rewrote $count files"; 
} catch (Exception $e) { 
    // oops, likely invalid path, or unreadable folder 
    echo "Problem reading $workspace"; 
} 
?> 

SPL手冊:

RecursiveIteratorIterator
RecursiveDirectoryIterator