循环遍历PHP中的目录?

时间:2011-12-22 15:34:24

标签: php file directory

我正在编写一个脚本,用一个字符串替换目录中的所有文件和子目录,以摆脱我们软件显示的一般错误消息。

我使用单个目录中的所有文件很容易地工作,但后来我们在子目录的文件夹中运行它,你可能猜到,它引发了很多错误。我完全忘记了子目录。

所以现在我正在创建一个与子目录一起工作的脚本,但我很难过。

这是我的代码:

<?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";

?>

最终输出:

[root@proxy1 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之类的事情。我认为这与它到达那一点时从较高的目录运行这一事实有关。

任何人都知道如何解决这个问题?

4 个答案:

答案 0 :(得分:1)

$_SERVER['SCRIPT_NAME']的值可能不是您所期望的,以及构建test/test/p.php之类路径的原因。我的猜测是当你执行php test/p.php时,这就是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');
    }
}

答案 1 :(得分:0)

问题源于LS返回基目录的内容,不一定是包含脚本的内容。老实说,我会避免使用exec,只是尝试将复制抽象为函数,使用php文件系统函数,并将其转换为递归算法,而不是尝试执行ls进程。

答案 2 :(得分: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

答案 3 :(得分:-1)

尝试这样的事情:

Codingforums

或尝试在谷歌上搜索“php recursive directory listing”或类似内容。

使用readdir()函数,您将获得特定目录中的文件和子目录。所以关键是要弄清楚它只是一个文件,还是一个带有is_dir()函数的子目录。当您要打开和编辑子目录时,还要确保使用完整路径到子目录中的文件。就像我说的尝试使用谷歌并找到有用的东西。