【问题标题】:How to clear memory after file_get_contents executes in php如何在php中执行file_get_contents后清除内存
【发布时间】:2015-05-24 09:04:19
【问题描述】:

我正在尝试将某些变量添加到已经有一些内容的几个文件中。

我正在使用 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,它完美地工作。感谢您的帮助 Jacinto。

【问题讨论】:

  • 一般使用unset
  • 是的,我尝试过使用 $ipfilecontents->__destruct();未设置($ipfilecontents);但没有工作@MarkBaker
  • 您不必担心。还有其他事情发生,但我没听懂……
  • 我不知道...对我来说看起来不错@PeterBowers
  • 您是否在 echo$ipfileContents$hostfileContents 之间使用了适当的 === 分隔符?

标签: php php-5.5


【解决方案1】:

这不是答案 - 我会在一分钟内删除它。它只是一个方便的地方展示如何进行跟踪语句:

    $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');

【讨论】:

  • 谢谢...我现在试试这个...你当然可以删除它...但我会要求你保留它以供将来参考。
  • 您可能会发现您的表单在 $domain 中传递了一些奇怪的值... $ipcontent 的内容是放在 $hostcontent 之前还是之后?
  • 这是输出......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=
  • 好吧,我投降了——我仍然很迷惑,但我看不出任何其他可能导致这种情况的东西...我建议使用建议的 fopen/fwrite/fclose并在这里回答 - 如果这解决了问题,那么 file_put_contents 一定很奇怪。
【解决方案2】:
        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";
        $content = $ipcontent . $ipfileContents;

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

        fclose($file);

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

//do the same to the next file
}

【讨论】:

  • Warning: fread(): Length parameter must be greater than 0 in /home1/pramir/public_html/development/samba/new/test.php on line 17Warning: fread(): 4 is not a valid stream resource in /home1/pramir/public_html/development/samba/new/test.php on line 36
  • 抱歉,我忘了更改变量 $statusLocation。将其更改为 $ipfile。在 fwrite($file, $content) 中。太
  • 添加代码后...现在不会向文件中添加任何内容。我已将新代码添加到我的问题中......请看看我是否遗漏了什么。谢谢。
  • @PeeJay $content= $ipcontent 。 $ipfile 内容; fwrite($文件,$内容);改变这两个
  • 是的..它起作用了.... Atlast....你不会相信我在过去 4 个小时里使用file_get_contentsfile_put_contents 尝试了这个.....谢谢你!!!我相信我现在可以对所有文件使用相同的代码。
【解决方案3】:

最有效的方法是同时分块读取和写入文件:

  • 以读写模式打开文件
  • 读取将被新数据覆盖的数据块
  • 将指针重置为读取块的开头
  • 写入新数据
  • 使读取的数据成为要写入的新数据
  • 重复直到没有数据可写

例子:

$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;
}

【讨论】:

    猜你喜欢
    • 2012-06-28
    • 2020-04-25
    • 2017-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-27
    相关资源
    最近更新 更多