Как очистить память после выполнения file_get_contents в php

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

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

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

Есть ли способ очистить память перед выполнением следующего файла file_get_contents. Или моя концепция здесь ложна.

Вот мой код...

<?php

 if ($_POST["submit"]) {

    $ip = $_POST['ip'];
    $subnet = $_POST['subnet'];
    $gateway = $_POST['gateway'];
    $hostname = $_POST['hostname'];
    $domain = $_POST['domain'];
    $netbios = $_POST['netbios'];
    $password = $_POST['password'];


    $ipfile = 'one.txt';

    $file = fopen($ipfile, "r");
    $ipfileContents = fread($file, filesize($ipfile));

    $ipcontent = "ip='$ip'\n";
    $ipcontent .= "netmask='$subnet'\n";
    $ipcontent .= "gw='$gateway'\n";
    $conten = $ipcontent . $ipfileContents;

    $file = fopen($ipfile, "w");
    fwrite($file, $ipfileContents);

    fclose($file);

    $ipsh = shell_exec('sh path/to/CHANGE_IP.sh');



    $hostfile = 'two.txt';

    $fileh = fopen($hostfile, "r");
    $hostfileContents = fread($fileh, filesize($hostfile));

    $hostcontent = "ip='$ip'\n";
    $hostcontent .= "m_name='$hostname'\n";
    $hostcontent .= "fqdn='$domain'\n";
    $conten = $hostcontent . $hostfileContents;

    $fileh = fopen($hostfile, "w");
    fwrite($fileh, $hostfileContents);

    fclose($fileh);

$hostsh = shell_exec('sh path/to/MODIFY_HOSTS.sh');


}








?>

Я пробовал отключить, но не работает

$ipfilecontents->__destruct();
unset($ipfilecontents);

ОБНОВЛЕНИЕ:

file_get_contents & file_put_contents имеет некоторые проблемы с параллелизмом. Поэтому мне пришлось изменить свой метод на fopen/fwrite/fclose, и он работал безупречно. Спасибо за помощь, Хасинто.


person PeeJay    schedule 20.03.2015    source источник
comment
обычно с помощью unset   -  person Mark Baker    schedule 20.03.2015
comment
да, я пытался использовать $ipfilecontents-›__destruct(); сбросить ($ ipfilecontents); но не сработало @MarkBaker   -  person PeeJay    schedule 20.03.2015
comment
Вы не должны беспокоиться об этом. Что-то еще происходит, но я не улавливаю...   -  person Peter Bowers    schedule 20.03.2015
comment
Я не знаю... Мне кажется, это нормально @PeterBowers   -  person PeeJay    schedule 20.03.2015
comment
Вы сделали echo из $ipfileContents и $hostfileContents с соответствующими разделителями === между ними?   -  person Peter Bowers    schedule 20.03.2015
comment
Это для регистрации? Лучшим вариантом было бы добавить новые журналы в файл, используя fopen и fwrite. Таким образом, вам вообще не нужно читать файл в память. Тем не менее, это добавит новые данные в конец файла, но на самом деле это обычно так.   -  person GolezTrol    schedule 20.03.2015
comment
Убедитесь, что вы перезапустили one.txt и two.txt с новым содержимым...   -  person Peter Bowers    schedule 20.03.2015
comment
Нет... На самом деле это относится к разным файлам сценариев оболочки... и данные должны быть поверх файла. Просто он хранит значения в виде переменных, которые будут вызываться функцией. @GolezTrol   -  person PeeJay    schedule 20.03.2015
comment
file_put_contents также имеет режим добавления. И если вам нужно заблокировать файл, используйте вместо него fopen.   -  person Gumbo    schedule 20.03.2015
comment
Я пробовал режим добавления с помощью lock_ex... но тогда он сохраняет содержимое в конец файла. Но я хочу, чтобы содержимое было поверх файла. @Гамбо   -  person PeeJay    schedule 20.03.2015
comment
Попробуйте закомментировать свой вызов shell_exec() на случай, если он делает что-то странное...   -  person Peter Bowers    schedule 20.03.2015
comment
Какие данные у вас есть в one.txt и two.txt? команды оболочки?   -  person Peter Bowers    schedule 20.03.2015
comment
этого файла не существует.. но я попытаюсь его прокомментировать. @ПитерБауэрс   -  person PeeJay    schedule 20.03.2015
comment
Да. На данный момент это тестовые файлы. Оригиналы будут файлами .sh. @ПитерБауэрс   -  person PeeJay    schedule 20.03.2015
comment
комментирование shell_exec() тоже не сработало. @ПитерБауэрс   -  person PeeJay    schedule 20.03.2015
comment
Вы подтвердили содержание 2-х файлов (краткий, уникальный) и проверили его через echo сразу после прочтения?   -  person Peter Bowers    schedule 20.03.2015
comment
Если вы попытаетесь сделать вместо file_gets_content, используйте fopen и fread. после записи с помощью fwrite. если хочешь, я могу показать тебе пример   -  person Jacinto    schedule 20.03.2015
comment
Для теста ... два файла пусты ... и когда я запускаю файл php ... он сначала помещает соответствующие значения в one.txt, а в two.txt он, конечно, помещает соответствующие значения, но также помещает содержимое один.txt. Надеюсь, я ясно выразился. @ПитерБауэрс   -  person PeeJay    schedule 20.03.2015
comment
НЕТ, я этого не пробовал... Но при таком способе содержимое будет отображаться в верхней части страницы. Потому что это мое основное требование. Если да, я бы попросил вас показать мне пример. Спасибо @Jacinto   -  person PeeJay    schedule 20.03.2015
comment
эхо? Вы предполагаете, что проблема исходит от file_put_contents, и я почти уверен, что вы обнаружите, что ваши переменные не содержат того, что, по вашему мнению, они содержат... Пожалуйста, попробуйте эхо-трассировку. Вы должны проверить все 4 vars - по 2 перед каждым file_put_contents.   -  person Peter Bowers    schedule 21.03.2015
comment
Ваш код точно скопирован/вставлен выше? Или немного подредактировал?   -  person Peter Bowers    schedule 21.03.2015
comment
Я неправильно понимаю часть эко-трассировки... не могли бы вы показать мне пример того, что запускать @PeterBowers   -  person PeeJay    schedule 21.03.2015


Ответы (3)


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

    $ipfile = 'one.txt';
    $ipfileContents = file_get_contents($ipfile);
    $ipcontent = "ip='$ip'\n";
    $ipcontent .= "netmask='$subnet'\n";
    $ipcontent .= "gw='$gateway'\n";
    echo "DEBUG: hostcontent=<pre>$ipcontent</pre><br />====<br />hostfileContents=<pre>$ipfileContents</pre><br />\n";            
    file_put_contents($ipfile, $ipcontent . $ipfileContents,  LOCK_EX);
    $ipsh = shell_exec('sh path/to/CHANGE_IP.sh');

    $hostfile = 'two.txt';
    $hostfileContents = file_get_contents($hostfile);
    $hostcontent = "ip='$ip'\n";
    $hostcontent .= "m_name='$hostname'\n";
    $hostcontent .= "fqdn='$domain'\n";
    echo "DEBUG: hostcontent=<pre>$hostcontent</pre><br />====<br />hostfileContents=<pre>$hostfileContents</pre><br />\n";
    file_put_contents($hostfile, $hostcontent . $hostfileContents,  LOCK_EX);
    $hostsh = shell_exec('sh path/to/MODIFY_HOSTS.sh');
person Peter Bowers    schedule 20.03.2015
comment
Спасибо... Я попробую это сейчас... Вы, конечно, можете удалить его... но я прошу вас сохранить его для будущих ссылок. - person PeeJay; 21.03.2015
comment
Вы можете обнаружить, что ваша форма выводит какие-то странные значения в $domain... Содержимое $ipcontent помещается до или после $hostcontent? - person Peter Bowers; 21.03.2015
comment
Это результат.... DEBUG: hostcontent= ip='180.151.2.164' netmask='255.255.255.0' gw='192.168.0.1' ==== hostfileContents= DEBUG: hostcontent= ip='180.151.2.164' m_name='hello' fqdn='fibromixer.com' ==== hostfileContents= - person PeeJay; 21.03.2015
comment
Хорошо, я сдаюсь - я все еще довольно озадачен, но я не вижу ничего другого, что могло бы вызвать это... Я бы рекомендовал использовать fopen/fwrite/fclose, который был предложен и на который был дан ответ здесь - если это решит проблему. проблема, то это должно быть что-то странное с file_put_contents. - person Peter Bowers; 21.03.2015

Наиболее эффективным было бы одновременное чтение и запись файла кусками:

  • открыть файл в режиме чтения-записи
  • прочитать фрагмент данных, который будет перезаписан новыми данными
  • сбросить указатель на начало прочитанного фрагмента
  • записать новые данные
  • сделать прочитанные данные новыми данными для записи
  • повторять до тех пор, пока не останется данных для записи

Пример:

$bufw = "ip=''\n";
$bufw .= "netmask=''\n";
$bufw .= "gw=''\n";

$bufw_len = strlen($bufw);

$file = fopen($ipfile, 'c+');
while ($bufw_len > 0) {
    // read next chunk
    $bufr = fread($file, $bufw_len);
    $bufr_len = strlen($bufr);

    // reset pointer to begin of chunk
    fseek($file, -$bufr_len, SEEK_CUR);

    // write previous chunk
    fwrite($file, $bufw);

    // update variables
    $bufw = $bufr;
    $bufw_len = strlen($bufw);
}
fclose($file);

При этом общее использование памяти ограничивается только длиной записываемых новых данных.

Вы можете сделать это функцией, например:

function file_prepend_contents($filename, $data, $flags = 0, $context = null) {
    if (!is_null($context)) {
        $handle = fopen($filename, 'c+', ($flags & FILE_USE_INCLUDE_PATH) === FILE_USE_INCLUDE_PATH, $context);
    } else {
        $handle = fopen($filename, 'c+', ($flags & FILE_USE_INCLUDE_PATH) === FILE_USE_INCLUDE_PATH);
    }

    if (!$handle) return false;

    if (($flags & LOCK_EX) === LOCK_EX) {
        flock($handle, LOCK_EX);
    }

    $bytes_written = 0;

    $bufw = $data;
    $bufw_len = strlen($bufw);
    while ($bufw_len > 0) {
        // read next chunk
        $bufr = fread($handle, $bufw_len);
        $bufr_len = strlen($bufr);

        // reset pointer
        fseek($handle, -$bufr_len, SEEK_CUR);

        // write current chunk
        if (ftell($handle) === 0) {
            $bytes_written = fwrite($handle, $bufw);
        } else {
            fwrite($handle, $bufw);
        }

        // update variables
        $bufw = $bufr;
        $bufw_len = strlen($bufw);
    }
    fclose($handle);

    return $bytes_written;
}
person Gumbo    schedule 21.03.2015

person    schedule
comment
извините, в треде я забыл изменить переменную $statusLocation. Измените это на $ipfile. И в fwrite($file, $content). слишком - person Jacinto; 21.03.2015
comment
После добавления вашего кода... теперь он ничего не добавляет в файлы. Я добавил новый код к своему вопросу... посмотрите, не пропустил ли я что-нибудь. Спасибо. - person PeeJay; 21.03.2015
comment
@PeeJay $content= $ipcontent . $ipfileContents; fwrite($файл, $контент); изменить эти два - person Jacinto; 21.03.2015
comment
Да.. это сработало.... Наконец.... вы не поверите, я пробовал это последние 4 часа, используя file_get_contents и file_put_contents..... Спасибо!!! Я считаю, что теперь я могу следовать одному и тому же коду для всех файлов. - person PeeJay; 21.03.2015
comment
Пришлось проголосовать против, так как в ответе четко не указано, в чем заключалось исправление ... пришлось пойти и сравнить код, чтобы увидеть, что отличается. Исправьте вышеизложенное и добавьте измененную строку - person Andrew; 08.08.2018