2011-12-22 197 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