PHP write in file in specific location - php

Imagine I have a TXT file with the following contents:
Hello
How are you
Paris
London
And I want to write beneath Paris, so Paris has the index of 2, and I want to write in 3.
Currently, I have this:
$fileName = 'file.txt';
$lineNumber = 3;
$changeTo = "the changed line\n";
$contents = file($fileName);
$contents[$lineNumber] = $changeTo;
file_put_contents($fileName, implode('',$contents));
But it only modifies the specific line. And I don't want to modify, I want to write a new line and let the others stay where they are.
How can I do this?
Edit: Solved. In a very easy way:
$contents = file($filename);
$contents[2] = $contents[2] . "\n"; // Gives a new line
file_put_contents($filename, implode('',$contents));
$contents = file($filename);
$contents[3] = "Nooooooo!\n";
file_put_contents($filename, implode('',$contents));

You need to parse the contents of the file, place the contents in a new array and when the line number you want comes up, insert the new content into that array. And then save the new contents to a file. Adjusted code below:
$fileName = 'file.txt';
$lineNumber = 3;
$changeTo = "the changed line\n";
$contents = file($fileName);
$new_contents = array();
foreach ($contents as $key => $value) {
$new_contents[] = $value;
if ($key == $lineNumber) {
$new_contents[] = $changeTo;
}
}
file_put_contents($fileName, implode('',$new_contents));

Related

Whether PHP writes file

i tried to search, but still dont know the solution at all, for my next PHP code.
<?php
$city="Budapest"; // Your city
$country="hu"; // Two digit country code
$url="http://api.openweathermap.org/data/2.5/weather?q=".$city.",".$country."&appid=2de143494c0b295cca9337e1e96b00e0&units=metric";
$json=file_get_contents($url);
$data=json_decode($json,true);
$file = '/home/cs2d/sys/lua/weather.dat';
$current = file_get_contents($file);
$current .= $data['weather'][0]['main']."\n".$data['main']['temp']."\n";
// Write the contents back to the file
file_put_contents($file, $current);
?>
As you can see it's a simple code, which write values into the weather.dat file.
But how to possible to do that its just refresh lines instead of add new one.
Any idea?
This works :
$city="Budapest"; // Your city
$country="hu"; // Two digit country code
$url="http://api.openweathermap.org/data/2.5/weather?q=".$city.",".$country."&appid=2de143494c0b295cca9337e1e96b00e0&units=metric";
$json=file_get_contents($url);
$data=json_decode($json,true);
$file = 'weather.dat';
$current = file_get_contents($file);
$contents = file_get_contents($file);
echo $current;
$contents = str_replace($current, ' ', $contents);
echo $contents;
file_put_contents($file,$contents);
$current = file_get_contents($file);
$current .= $data['weather'][0]['main']."\n".$data['main']['temp']."\n";
// Write the contents back to the file
file_put_contents($file, $current);

How can I edit the content of a ini file?

I would like to be able to edit a config file for a server application using php. The config file is as follows:
include=sc_serv_public.conf
streamid_2=2
streampath_2=/relay
streamrelayurl_2=http://<full_url_of_relay_including_port>
;allowrelay=0
;allowpublicrelay=0
I would like to edit the line:
streamrelayurl_2=http://<full_url_of_relay_including_port>
and then save the file.
I am currently using:
$data = file_get_contents("sc_serv.conf"); //read the file
$convert = explode("\n", $data); //create array separate by new line
to open the file, but now I dont know how to edit it.
As an alternative, you could just use file() instead. This just loads it up into array form, no need to explode. Then after that, you just loop the elements, if the desired needle is found, overwrite it, the write the file again:
$data = file('sc_serv.conf', FILE_IGNORE_NEW_LINES); // load file into an array
$find = 'streamrelayurl_2='; // needle
$new_value = 'http://www.whateverurl.com'; // new value
foreach($data as &$line) {
if(strpos($line, 'streamrelayurl_2=') !== false) { // if found
$line = $find . $new_value; // overwrite
break; // stop, no need to go further
}
}
file_put_contents('sc_serv.conf', implode("\n", $data)); // compound into string again and write
You can use file() to read the file content to an array, then you can iterate trough the array with foreach() searching with the strstr() function the line that have your URL (in this case is in the var $id_change) and change the value. Then as you found what you needed, you end the foreach() with break. And make your string to save in the file with implode() and save the string to the config file with file_put_content().
See the code:
<?php
$new_url = 'http://www.google.com';
$id_change = 'streamrelayurl_2';
$file = "sc_serv.conf";
$data = file($file); //read the file
foreach($data as $key => $value) {
if(strstr($value, $id_change)) {
$info = $id_change . '=' . $new_url . "\n";
$data[$key] = $info;
break;
}
}
$data = implode("", $data);
file_put_contents($file, $data);
?>
Output:
include=sc_serv_public.conf
streamid_2=2
streampath_2=/relay
streamrelayurl_2=http://www.google.com
;allowrelay=0
;allowpublicrelay=0

Write to file using SplFileObject()

I'm trying to edit a file by line using SplFileObject(). I can choose the line of the file I want to edit. But how do I then write a $string to that line?
Here is my code to get the line:
<?php
$file = new SplFileObject('myfile.txt');
$file->seek(9999); // Seek to line no. 10,000
echo $file->current(); // Print contents of that line
?>
How do I insert a string on that line?
Note, I don't want to overwrite the file, I simply want to insert a $string at a given line.
This isn't probably the best solution as it will read the whole file and store it in a string. But since there are no other answers you can use this as your last resource.
$ouput = '';
$file = new SplFileObject("your_file.xxx", 'r');
while (!$file->eof()) {
$line = $file->fgets();
if($line == 'your_condition'){
$line = 'replace this line';
}
$output .= $line;
}
$file = null;
$file = new SplFileObject("your_file.xxx", 'w+');
$file->fwrite($output);

Combining two text files with PHP - ForEach loops

I'm completely puzzled where to even start on this, but I need to provide a list of keywords in file A and then the same in list B.
With these too files I want to append the lines in A foreach line in file B
For example:
File A:
line1
line2
line3
File B:
test1
test2
test3
Output to a combined.txt file:
line1test1
line2test1
line3test1
line1test2 ... and so on
If you could provide me the portions of the script to research, a sample script, or even a working way to do it. I would greatly appreciate it.
Per request, here is my sample code:
<?php
$file1 = 'keywords.txt';
$file2 = 'topics.txt';
$combined = 'combined.txt';
$keywords = fopen("keywords.txt", "rb");
$topics = fopen("topics.txt", "rb");
$front = explode($topics);
$back = explode($topics);
while (!feof($keywords) ) {
file_put_contents($combined, . $front ."". $back . "\n");
fclose($keywords & $topics);
}
?>
Hope this helps. Comments are sprinkled throughout the code, which I hope is sufficient explanation as to what I'm doing.
<?php
// Open keywords file for reading
$keywords_file = 'keywords.txt';
$keywords_fh = fopen($keywords_file, 'r');
// Get line by line from keywords file, push into $keywords array
// Make sure to trim each line from fgets, to strip off \n at end.
$keywords = array();
while ($line = trim(fgets($keywords_fh))) {
array_push($keywords, $line);
}
fclose($keywords_fh);
// Open topics file for reading
$topics_file = 'topics.txt';
$topics_fh = fopen($topics_file, 'r');
// Get line by line from topics file, push into $topics array
// Make sure to trim each line from fgets, to strip off \n at end.
$topics = array();
while ($line = trim(fgets($topics_fh))) {
array_push($topics, $line);
}
fclose($topics_fh);
// Open combined file for writing
$combined_file = 'combined.txt';
$combined_fh = fopen($combined_file, 'w');
// Iterate through each keyword.
// For each iteration, iterate through each topic.
// Write the concatenation of keyword and topic to file.
foreach ($keywords as $keyword) {
foreach ($topics as $topic) {
fwrite($combined_fh, "$keyword$topic\n");
}
}
fclose($combined_fh);
Here are some links to PHP documentation for some of the key functions I used:
fopen
trim
fgets
fwrite
fclose
$f1 = explode("\n",file_get_contents("fileA.txt"));
$f2 = explode("\n",file_get_contents("fileB.txt"));
foreach ($f1 as $key => $value) {
$f3[] = $value.$f2[$key];
}
file_put_contents("fileC.txt", implode("\n",$f3));

File manupulation search and replace csv php

I need a script that is finding and then replacing a sertain line in a CSV like file.
The file looks like this:
18:110327,98414,127500,114185,121701,89379,89385,89382,92223,89388,89366,89362,89372,89369
21:82297,79292,89359,89382,83486,99100
98:110327,98414,127500,114185,121701
24:82297,79292,89359,89382,83486,99100
Now i need to change the line 21.
This is wat i got so far.
The first 2 to 4 digits folowed by : ar a catergory number. Every number after this(followed by a ,) is a id of a page.
I acces te id's i want (i.e. 82297 and so on) from database.
//test 2
$sQry = "SELECT * FROM artikelen WHERE adviesprijs <>''";
$rQuery = mysql_query ($sQry);
if ( $rQuery === false )
{
echo mysql_error ();
exit ;
}
$aResult = array ();
while ( $r = mysql_fetch_assoc ($rQuery) )
{
$aResult[] = $r['artikelid'];
}
$replace_val_dirty = join(",",$aResult);
$replace_val= "21:".$replace_val_dirty;
// file location
$file='../../data/articles/index.lst';
// read the file index.lst
$file1 = file_get_contents($file);
//strip eerde artikel id van index.lst
$file3='../../data/articles/index_grp21.lst';
$file3_contents = file_get_contents($file3);
$file2 = str_replace($file3_contents, $replace_val, $file1);
if (file_exists($file)) {
echo "The file $filename exists";
} else {
echo "The file $filename does not exist";
}
if (file_exists($file3)) {
echo "The file $filename exists";
} else {
echo "The file $filename does not exist";
}
// replace the data
$file_val = $file2;
// write the file
file_put_contents($file, $file_val);
//write index_grp98.lst
file_put_contents($file3, $replace_val);
mail('info#', 'Aanbieding catergorie geupdate', 'Aanbieding catergorie geupdate');
Can anyone point me in the right direction to do this?
Any help would be appreciated.
You need to open the original file and go through each line. When you find the line to be changed, change that line.
As you can not edit the file while you do that, you write a temporary file while doing this, so you copy over line-by-line and in case the line needs a change, you change that line.
When you're done with the whole file, you copy over the temporary file to the original file.
Example Code:
$path = 'file';
$category = 21;
$articles = [111182297, 79292, 89359, 89382, 83486, 99100];
$prefix = $category . ':';
$prefixLen = strlen($prefix);
$newLine = $prefix . implode(',', $articles);
This part is just setting up the basics: The category, the IDs of the articles and then building the related strings.
Now opening the file to change the line in:
$file = new SplFileObject($path, 'r+');
$file->setFlags(SplFileObject::DROP_NEW_LINE | SplFileObject::SKIP_EMPTY);
$file->flock(LOCK_EX);
The file is locked so that no other process can edit the file while it gets changed. Next to that file, the temporary file is needed, too:
$temp = new SplTempFileObject(4096);
After setting up the two files, let's go over each line in $file and compare if it needs to be replaced:
foreach ($file as $line) {
$isCategoryLine = substr($line, 0, $prefixLen) === $prefix;
if ($isCategoryLine) {
$line = $newLine;
}
$temp->fwrite($line."\n");
}
Now the $temporary file contains already the changed line. Take note that I used UNIX type of EOF (End Of Line) character (\n), depending on your concrete file-type this may vary.
So now, the temporary file needs to be copied over to the original file. Let's rewind the file, truncate it and then write all lines again:
$file->seek(0);
$file->ftruncate(0);
foreach ($temp as $line) {
$file->fwrite($line);
}
And finally you need to lift the lock:
$file->flock(LOCK_UN);
And that's it, in $file, the line has been replaced.
Example at once:
$path = 'file';
$category = 21;
$articles = [111182297, 79292, 89359, 89382, 83486, 99100];
$prefix = $category . ':';
$prefixLen = strlen($prefix);
$newLine = $prefix . implode(',', $articles);
$file = new SplFileObject($path, 'r+');
$file->setFlags(SplFileObject::DROP_NEW_LINE | SplFileObject::SKIP_EMPTY);
$file->flock(LOCK_EX);
$temp = new SplTempFileObject(4096);
foreach ($file as $line) {
$isCategoryLine = substr($line, 0, $prefixLen) === $prefix;
if ($isCategoryLine) {
$line = $newLine;
}
$temp->fwrite($line."\n");
}
$file->seek(0);
$file->ftruncate(0);
foreach ($temp as $line) {
$file->fwrite($line);
}
$file->flock(LOCK_UN);
Should work with PHP 5.2 and above, I use PHP 5.4 array syntax, you can replace [111182297, ...] with array(111182297, ...) in case you're using PHP 5.2 / 5.3.

Categories