在php中执行file_get_contents后如何清除内存
How to clear memory after file_get_contents executes in 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
并且它完美地工作。感谢 Jacinto 的帮助。
这不是答案 - 我会在一分钟内删除它。这只是展示如何执行跟踪语句的方便位置:
$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');
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
}
最有效的方法是同时读取和写入文件块:
- 以读写模式打开文件
- 读取将被新数据覆盖的数据块
- 将指针重置为读取块的开始
- 写入新数据
- 将读取的数据作为要写入的新数据
- 重复直到没有数据可写
示例:
$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;
}
我正在尝试将某些变量添加到几个已有内容的文件中。
我正在使用 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 的帮助。
这不是答案 - 我会在一分钟内删除它。这只是展示如何执行跟踪语句的方便位置:
$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');
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
}
最有效的方法是同时读取和写入文件块:
- 以读写模式打开文件
- 读取将被新数据覆盖的数据块
- 将指针重置为读取块的开始
- 写入新数据
- 将读取的数据作为要写入的新数据
- 重复直到没有数据可写
示例:
$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;
}