Зацикливание каталогов в PHP? - PullRequest
1 голос
/ 22 декабря 2011

Я работаю над сценарием, который заменяет все файлы в каталоге и подкаталогах одной строкой, чтобы избавиться от общего сообщения об ошибке, отображаемого нашим программным обеспечением.

Я сделал это довольно легко со всемифайлы в одном каталоге, но затем мы запустили его в папке с подкаталогами, и, как вы можете догадаться, это породило много ошибок.Я полностью забыл о подкаталогах.

Так что теперь я делаю скрипт, который работает с подкаталогами, но я в тупике.

Вот мой код:

<?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 ]

1 голос
/ 22 декабря 2011

Значение $_SERVER['SCRIPT_NAME'], вероятно, не то, что вы ожидаете, а причина для создания пути типа test/test/p.php.Я предполагаю, что когда вы исполняете php test/p.php, тогда значение php помещается в SCRIPT_NAME.Вы можете использовать функцию basename (), чтобы обойти это.

Кроме того, вы должны использовать 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 голосов
/ 22 декабря 2011

Рекурсивные итераторы 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

0 голосов
/ 22 декабря 2011

Проблема связана с тем, что LS возвращает содержимое базового каталога, не обязательно того, в котором находится ваш скрипт. Честно говоря, я бы избегал exec и просто попытался бы абстрагировать ваше копирование в функцию, использовать функции файловой системы php и превратить его в рекурсивный алгоритм вместо попыток выполнения процессов ls.

0 голосов
/ 22 декабря 2011

Попробуйте что-то вроде этого:

Codingforums

или попробуйте поискать в Google «рекурсивный список каталогов php» или что-нибудь подобное.

С функцией readdir () вы получите файлы и подкаталоги в определенном каталоге. Таким образом, ключевым моментом является выяснить, является ли это просто файл или это подкаталог с функцией is_dir (). Также убедитесь, что вы будете использовать полный путь к файлам в подкаталогах, когда вы хотите открыть и редактировать его. Итак, как я уже сказал, попробуйте использовать Google и найти что-то полезное.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...