How to clear memory after file_get_contents executes in php - php

I am trying to add certain variables to couple of files which already have some content.
I am using file_get_contents to copy the contents of a particular file and then using file_put_contents to paste variable values along with the existing contents to that file.
The problem is that, on the first instance it works properly but to the second file it pastes everything that has been stored in the memory. It puts all the contents from the first file along with the contents of the second file.
Is there any way that I can clear the memory before the next file_get_contents executes. Or my concept is false here.
Here is my code...
<?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');
}
?>
I have tried unset, but didn't work
$ipfilecontents->__destruct();
unset($ipfilecontents);
UPDATE:
file_get_contents & file_put_contents has some concurrency problems. So I had to change my method to fopen/fwrite/fclose and it worked flawlessly. Thanks for your help Jacinto.

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
}

This isn't an answer - I'll delete it in a minute. It's just a convenient place to show how to do trace statements:
$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');

The most efficient would be to read and write the file in chunks simultaneously:
open the file in read-write mode
read the data chunk that will be overwritten by the new data
reset pointer to begin of read chunk
write new data
make the read data the new data to be written
repeat until there is no data to write
Example:
$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);
With this the total memory usage is only up to the length of the new data to be written.
You can make it a function like:
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;
}

Related

PHP change only one value inside ini file

I'm trying to rewrite a config.ini file which looks like this
dbhost=localhost
dbname=phonebook
dbuname=root
dbpass=
reinstall=2
I want to change the reinstall value to 1 like so
dbhost=localhost
dbname=phonebook
dbuname=root
dbpass=
reinstall=1
I already wrote some lines, yet i am stuck and don't know how to change only one value
$filepath = 'config.ini';
$data = #parse_ini_file("config.ini");;
//update ini file, call function
function update_ini_file($data, $filepath) {
$content = "";
//parse the ini file to get the sections
//parse the ini file using default parse_ini_file() PHP function
$parsed_ini = parse_ini_file($filepath, true);
foreach($data as $section => $values){
if($section === "submit"){
continue;
}
$content .= $section ."=". $values . "\n";
}
//write it into file
if (!$handle = fopen($filepath, 'w')) {
return false;
}
$success = fwrite($handle, $content);
fclose($handle);
}
update_ini_file($data, $filepath);
header('location: '.ROOT_PATH.'/');
Got it fixed like this
$filepath = 'config.ini';
$data = #parse_ini_file("config.ini");
$data['reinstall']='1';
//update ini file, call function
function update_ini_file($data, $filepath) {
$content = "";
//parse the ini file to get the sections
//parse the ini file using default parse_ini_file() PHP function
$parsed_ini = parse_ini_file($filepath, true);
foreach($data as $section => $values){
if($section === "submit"){
continue;
}
$content .= $section ."=". $values . "\n";
}
//write it into file
if (!$handle = fopen($filepath, 'w')) {
return false;
}
$success = fwrite($handle, $content);
fclose($handle);
}
update_ini_file($data, $filepath);
header('location: '.ROOT_PATH.'/');

How to change a text file and read in those changes in php

I want to read in a message from a JS file, and then change a global variable in that js file so that it will adjust its performance (and then empty the text file). Unfortunately, it always returns the original value of the text file instead of the updated value, and I can't use the updated value until I refresh the page. Is there a better way to do this?
<?php
switch($_SERVER['REQUEST_METHOD'])
{
case 'GET':
if(file_exists('chat.txt') && filesize('chat.txt') > 0){
$filesize = filesize('chat.txt');
$f = fopen('chat.txt', "a+");
$line = fread($f, $filesize);
$line = htmlspecialchars(str_replace("\n", "", $line));
echo "<script> post = '" . $line . "';</script>";
fclose($f);
fclose(fopen('chat.txt', 'w'));
}
break;
case 'POST':
$function = $_POST['function'];
switch ($function) {
case('send'):
$message = strip_tags($_POST['message']);
$f = fopen('chat.txt', 'w');
fwrite($f, $message);
fclose($f);
break;
}
}
?>

Read serialized file, record by record

I save to file data from form:
$name = $_POST['name'];
$url = $_POST['url'];
$comm = $_POST['comm'];
$data["name"]=$name;
$data["url"]=$url;
$data["comm"]=$comm;
file_put_contents("db.txt", serialize($data));
Now, I would like to read this file record by record.
$file_handle = fopen("db.txt", "r");
while (!feof($file_handle)) {
$line = fgets($file_handle);
$arr = unserialize($line);
var_dump($arr);
}
fclose($file_handle);
But this code read only last record. How to read all file?
Replace file_put_contents("db.txt", serialize($data)); to
file_put_contents("db.txt", PHP_EOL .serialize($data), FILE_APPEND);
file_put_contents("db.txt", serialize($data));// will over write the file again and again. so you cant able to read all the data. FILE_APPEND helps to append the data And PHP_EOL helps to leave a line breake.
Hi i try this code for your solution:
<?php
$name = "rdn";
$url = "http://google.it";
$comm = "com";
$data["name"]=$name;
$data["url"]=$url;
$data["comm"]=$comm;
file_put_contents("db.txt", serialize($data)."\n",FILE_APPEND);
$fh = fopen('db.txt','r');
while ($line = fgets($fh)) {
// <... Do your work with the line ...>
var_dump(unserialize($line));
}
fclose($fh);
?>
without "\n" don't work!

Create CSV from data returned from API

I'm trying to use Mailchimp's Export API to generate a CSV file of all members of a given list. Here' the documentation and the example PHP code they give:
$apikey = 'YOUR_API_KEY';
$list_id = 'YOUR_LIST_ID';
$chunk_size = 4096; //in bytes
$url = 'http://us1.api.mailchimp.com/export/1.0/list?apikey='.$apikey.'&id='.$list_id;
/** a more robust client can be built using fsockopen **/
$handle = #fopen($url,'r');
if (!$handle) {
echo "failed to access url\n";
} else {
$i = 0;
$header = array();
while (!feof($handle)) {
$buffer = fgets($handle, $chunk_size);
if (trim($buffer)!=''){
$obj = json_decode($buffer);
if ($i==0){
//store the header row
$header = $obj;
} else {
//echo, write to a file, queue a job, etc.
echo $header[0].': '.$obj[0]."\n";
}
$i++;
}
}
fclose($handle);
}
This works well for me and when I run this file, I end up with a bunch of data in this format:
Email Address: xdf#example.com
Email Address: bob#example.com
Email Address: gerry#example.io
What I want to do is turn this into a CSV (to pass to a place on my server) instead of echoing the data. Is there a library or simple syntax/snippit I can use to make this happen?
If the format simply like:
Email Address, xdf#example.com
Email Address, bob#example.com
Email Address, gerry#example.io
is what you after, then you can do:
$handle = #fopen($url,'r');
$csvOutput = "";
if (!$handle) {
echo "failed to access url\n";
} else {
$i = 0;
$header = array();
while (!feof($handle)) {
$buffer = fgets($handle, $chunk_size);
if (trim($buffer)!=''){
$obj = json_decode($buffer);
if ($i==0){
//store the header row
$header = $obj;
} else {
//echo, write to a file, queue a job, etc.
echo $header[0].', '.$obj[0]."\n";
$csvOutput .= $header[0].', '.$obj[0]."\n";
}
$i++;
}
}
fclose($handle);
}
$filename = "data".date("m.d.y").".csv";
file_put_contents($filename, $csvOutput);
The variable $csvOutput contains the CSV format string.
This ones on me. From now on you might want to actually read some documentation instead of copying and pasting your way through life. other's will not be as nice as i am. here's a list of file system functions from the php website. http://php.net/manual/en/ref.filesystem.php Getting the file output to the desired csv format is an exercise left to the reader.
$apikey = 'YOUR_API_KEY';
$list_id = 'YOUR_LIST_ID';
$chunk_size = 4096; //in bytes
$url = 'http://us1.api.mailchimp.com/export/1.0/list?apikey='.$apikey.'&id='.$list_id;
/** a more robust client can be built using fsockopen **/
$handle = #fopen($url,'r');
if (!$handle) {
echo "failed to access url\n";
} else {
$i = 0;
$header = array();
$output = ''; //output buffer for the file we are going to write.
while (!feof($handle)) {
$buffer = fgets($handle, $chunk_size);
if (trim($buffer)!=''){
$obj = json_decode($buffer);
if ($i==0){
//store the header row
$header = $obj;
} else {
//write data into our output buffer for the file
$output .= $header[0].': '.$obj[0]."\n";
}
$i++;
}
}
fclose($handle);
//now write it to file
$path = '/path/to/where/you/want/to/store/file/';
$file_name = 'somefile.csv';
//create a file resource to write to.
$fh = fopen($path.$file_name,'w+');
//write to the file
fwrite($fh,$output);
//close the file
fclose($fh);
}

Help writing to two files simultaneously in PHP?

In the script below, I try to write in the same time in two files, but don't perform. How I can do it ?
$filename1 = "guestbook.doc" ;
$filename2 = "cour.doc" ;
$name = htmlspecialchars($_POST['name']);
$email = htmlspecialchars($_POST['email']);
$message = stripslashes(nl2br(htmlentities($_POST['message'])));
$d = date ( "d/m/Y H:i:s" )
$handle1 = fopen($filename1, "w+");
$handle2 = fopen($filename2, "a+");
if ($handle1 && $handle2) {
fwrite($handle1, "<b>$name</b> "." - $d<br>$message<br><hr>\n");
fwrite($handle2, "<b>$name</b> ".$email." - $d<br>$message<br>\n");
}
if ($handle1) {
fclose($handle1);
}
if ($handle2) {
fclose($handle2);
}
then
{
header('Location: contact.php?' . http_build_query($_POST));
}
?>
One thing I do notice is that is kinda odd is :
then
{
header('Location: contact.php?' . http_build_query($_POST));
}
then is not a valid control structure. It's if/elseif/else.
writing to a file in PHP is procedural it will wait for handle1 to be written before moving onto handle2. It will not write them at the same time. There must be an error occurring or its not getting inside the if statement if($handle1 && $handle2) . It possibly cannot open those files for writing due to permission problems? are there any errors at all?
Try replacing that if statement with something like this and see if it breaks?
if (is_writable($filename1) or die ("Can not write to ".$filename1)) {
fwrite($handle1, "<b>$name</b> "." - $d<br>$message<br><hr>\n");
}
if (is_writable($filename2) or die ("Can not write to ".$filename2)) {
fwrite($handle2, "<b>$name</b> "." - $d<br>$message<br><hr>\n");
}
Just write one under another it will work perfect.
<?php
$filename = "guestbook.doc" ;
$name = htmlspecialchars($_POST['name']);
$email = htmlspecialchars($_POST['email']);
$message = stripslashes(nl2br(htmlentities($_POST['message'])));
$d = date ( "d/m/Y H:i:s" )
$handle1 = fopen($filename, "w+");
$size = filesize($filename);
fwrite($handle, "<b>$name</b> "." - $d<br>$message<br><hr>\n");
$text = fread($handle, $size);
fclose($handle);
$filename = "cour.doc" ;
$name = htmlspecialchars($_POST['name']);
$email = htmlspecialchars($_POST['email']);
$message = stripslashes(nl2br(htmlentities($_POST['message'])));
$d = date ( "d/m/Y H:i:s" )
$handle = fopen($filename1, "w+");
$size = filesize($filename1);
fwrite($handle, "<b>$name</b> ".$email." - $d<br>$message<br>\n");
$text = fread($handle, $size);
fclose($handle);
?>

Categories