Еще раз о замене строк в файлах Печать
Автор: А.Волос   

Нередко бывает необходимо заменить одну подстроку (слово) другой подстрокой (другим словом) сразу в нескольких файлах. Количество файлов может достигать несколько десятков или сотен, и располагаться они могут внутри разветвленного дерева каталогов.

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

Обе программы выводят диалоговое окно с двумя полями, в одно из них необходимо ввести заменяемую подстроку, в другое заменяющюю подстроку и нажать на кнопку "Заменить".

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

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

Второй вариант программы написан специально, чтобы предотвратить случайное удаление подстроки без замены на другую подстроку. Потому, что исправить такое удаление будет невозможно, если где-нибудь не сохранены оригиналы.

Первый вариант еще удобен тем, что некоторые люди намеренно отключают в браузере возможность использования js-скриптов. В этом случае первый вариант программы будет выполняться, а второй нет. Вы сами может выбрать что вам удобнее.

Основную работу по замене или удалению подстрок выполняет рекурсивная функция replaceStringsInTree(). Здесь так же можно обратить внимание на передачу параметров из формы методом POST и передачу параметров при перезапуске скрипта index.php js-кодом GET методом через адресную строку.

Программа Вариант 1.

<?php 

$HOME = dirname(__FILE__);
global $insideitem; //глобальная переменная для подсчета модифицированных файлов
$insideitem = 0;
//
$targett = ''; //что нужно заменить
$replacement = ''; //чем заменить

//Считаем переменные формы из глобального массива, если они там есть
if (isset($_POST['targett'])){
    $targett = $_POST['targett'];
    $replacement = $_POST['replacement'];
}

?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Замена подстрок в файлах</title>
<style>
body { font-size: 12px; font-family: Arial, Helvetica, sans-serif; background: #FFF; color: #000; }
.FOUND { color: #F30; font-size: 14px; font-weight: bold; }
</style>
</head>
<body>
<h2>Замена подстрок</h2>

Эта программа осуществляет замену подстрок во всех файлах текущего каталога и подкаталогов.

Введите в поле <b>"Меняем что"</b> подстроку, которую следует заменить.

Введите в поле <b>"На что"</b> новую подстроку. 
<form name="form1" method='post' action='index.php'>
<table bgcolor='#cccccc'>
<tr><td>Меняем что:</td><td><input type='text' name='targett' value="<?php echo $targett  ?>"></td></tr>
<tr><td>На что:</td><td><input type='text' name='replacement' value="<?php echo $replacement  ?>"></td></tr>
<tr><td colspan=2 align='center'><input type='submit' value='Заменить'></td></tr>
</table></form> 
<?php

if($targett ==''){//если строка для поиска пуста
    echo '
 Заполните поля ввода данными ';
}else{

    if( $replacement == ''){//если строка для замены пуста
        echo '
Введите подстроку в поле <b>"На что"</b> ';      
    }else{

        if( $replacement == $targett ){ //если подстроки идентичны    
            echo '
Подстроки идентичны! Замена не имеет смысла. Введите новые данные ';
        }else{
///////////////////////////////////////////////////////
/////////////// Данные корректны. Сделаем замену //////
///////////////////////////////////////////////////////
            replaceStringsInTree($HOME, $targett, $replacement, $insideitem); 
            if($insideitem){
                echo " 
Поздравляем!  Подстрока:<b> $targett</b> заменена подстрокой:<b> $replacement </b>  ";
                echo " 
Произведена модификация <b> $insideitem </b> файлов</b>  ";
            }
            else{
                echo " 
К сожалению подстрока <b> $targett </b> не найдена ни в одном файле.  ";
            }
//////////////////////////////////////////////////
//////////////////////////////////////////////////
        }
    }
}
?>
</body>
</html>

<?php
///////////////////////////////////////////////////
//
function replaceStringsInTree($folder, $targett, $replacement, &$insideitem) {

    // Получаем полный список файлов и каталогов внутри $folder 
    $files = scandir($folder);
        
    foreach($files as $file) {
                        
        // Отбрасываем текущий и родительский каталог 
        if (($file == '.') || ($file == '..')) continue;

        $file_ref = $folder.'/'.$file; //Получаем полный путь к файлу
        if (is_dir($file_ref)) { // Если это каталог 
            replaceStringsInTree($file_ref, $targett, $replacement,$insideitem);
        }
        else{ //  Если это файл, открываем, считываем, обрабатываем, перезаписываем  
                
            $str_source = file_get_contents($file_ref); //скопируем контент файла в строку
            if(strpos($str_source, $targett)){
                $str_new = str_replace($targett,$replacement,$str_source); //сделаем замены!
                $numbyte = file_put_contents($file_ref, $str_new); //скопируем строку обратно в файл
                $insideitem++;
            }
        }
    }
}

?>

Программа Вариант 2

<?php 
$HOME = dirname(__FILE__);
global $insideitem; //глобальная переменная для подсчета модифицированных файлов
$insideitem = 0;
//
$yn = 'what';
$targett = ''; //что нужно заменить
$replacement = ''; //чем заменить

//Задача: установить значение переменных $yn и $targett
//Для того, чтобы либо заменить $targett, либо удалить $targett
//значения переменных могут быть получены либо как значения формы из глоб. массива POST,
//либо как значения переменных, переданные в адресной строке браузера - глоб. массив GET,
//используем оба способа

//Считаем переменные формы из глобального массива, если они там есть
if (isset($_POST['targett'])){
    $yn = $_POST['yn'];
    $targett = $_POST['targett'];
    $replacement = $_POST['replacement'];
}

if($yn=='') $yn = 'what';

if (isset($_GET['yn'])){
    $yn = $_GET['yn'];
    $targett = $_GET['u_targett'];
}

?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Замена подстрок в файлах</title>
<style>
body { font-size: 12px; font-family: Arial, Helvetica, sans-serif; background: #FFF; color: #000; }
.FOUND { color: #F30; font-size: 14px; font-weight: bold; }
</style>
<script>
<!--
function confirmation()
{
 if(confirm("Вы хотите удалить подстроку без замены?"))
 {
  return document.getElementById('yn').value = 'yes';
 }
 else
 {
  return document.getElementById('yn').value = 'no';
 }
 document.forms['form1'].submit();
}
//-->
</script>
</head>
<body>
<h2>Замена подстрок</h2>

Эта программа осуществляет замену подстрок во всех файлах текущего каталога и подкаталогов.

Введите в поле <b>"Меняем что"</b> подстроку, которую следует заменить.

Введите в поле <b>"На что"</b> новую подстроку. 

<form name="form1" method='post' action='index.php'>
<table bgcolor='#cccccc'>
<tr><td colspan=2><input type='hidden' id="yn" value="<?php echo $yn  ?>"> </td>
<tr><td>Меняем что:</td><td><input type='text' name='targett' value="<?php echo $targett  ?>" ></td></tr>
<tr><td>На что:</td><td><input type='text' name='replacement' value="<?php echo $replacement  ?>"></td></tr>
<tr><td colspan=2 align='center'><input type='submit' value='Заменить'></td></tr>
</table></form> 
<?php

if($targett ==''){//если строка для поиска пуста
    echo '
 Заполните поля ввода данными ';
}else{

    if( $replacement == '' && $yn != 'yes'){//если строка для замены пуста

        if($yn=="what"){                
        ?>
        <script type='text/javascript'> 
            var yn = confirmation() 
            document.write('
 \r\n = ' + yn + '  ')
        </script>
           
        <?php
            //перезапустим скрипт index.php при помощи метода js,  
            //передав значение переменных yn и u_targett в адресную строку 
            echo '<script type="text/javascript">';
            echo 'document.location.href="' . $_SERVER['REQUEST_URI'] . '?yn=" + yn + \'&u_targett='.$targett.' \'';
            echo '</script>';
        }
            echo '
Введите подстроку в поле <b>"На что"</b> ';               
    }else{//если строка для замены НЕ пуста

        if( $replacement == $targett ){ //если подстроки идентичны    
            echo '
Подстроки идентичны! Замена не имеет смысла. Введите новые данные ';
        }else{
///////////////////////////////////////////////////////
/////////////// Данные корректны. Сделаем замену //////
///////////////////////////////////////////////////////
            replaceStringsInTree($HOME, $targett, $replacement, $insideitem); 
            if($insideitem){

                if($yn == 'yes'){
                    echo " 
Поздравляем!  Подстрока:<b> $targett </b> удалена из текста.  ";
                    echo " 
Произведена модификация <b> $insideitem </b> файлов</b>  ";
                }
                else{
                    echo " 
Поздравляем!  Подстрока:<b> $targett </b> заменена подстрокой:<b> $replacement </b>  ";
                    echo " 
Произведена модификация <b> $insideitem </b> файлов</b>  ";
                }
            }
            else{
                echo " 
К сожалению подстрока <b> $targett </b> не найдена ни в одном файле.</b>  ";
            }
//////////////////////////////////////////////////
//////////////////////////////////////////////////
        }
    }
}
?>
</body>
</html>

<?php
///////////////////////////////////////////////////
//
function replaceStringsInTree($folder, $targett, $replacement, &$insideitem) {

    // Получаем полный список файлов и каталогов внутри $folder 
    $files = scandir($folder);
        
    foreach($files as $file) {
                        
        // Отбрасываем текущий и родительский каталог 
        if (($file == '.') || ($file == '..')) continue;

        $file_ref = $folder.'/'.$file; //Получаем полный путь к файлу
        if (is_dir($file_ref)) { // Если это каталог 
            replaceStringsInTree($file_ref, $targett, $replacement,$insideitem);
        }
        else{ //  Если это файл, открываем, считываем, обрабатываем, перезаписываем  
                
            $str_source = file_get_contents($file_ref); //скопируем контент файла в строку
            if(strpos($str_source, $targett)){
                $str_new = str_replace($targett,$replacement,$str_source); //сделаем замены!
                $numbyte = file_put_contents($file_ref, $str_new); //скопируем строку обратно в файл
                $insideitem++;
            }
        }
    }
}


?>

Обновлено 15.11.2015 19:09