I have a text file. I want to delete some lines with a query of search.
The array is line by line. I want to made it like http://keywordshitter.com/
The logic is,
SEARCH --> IN ARRAY --> OUTPUT IS ARRAY WITHOUT "QUERY OF SEARCH"
Code I have tried:
$fileset = file_get_contents("file.txt");
$line = explode("\n", $fileset);
$content = array_search("query",$line);
print_r($content);
MY file.txt
one
two
three
apple
map
I have used array_search but not working.
you can do search like
$fileset=file("file.txt"); // file function reads entire file into an array
$len=count($fileset);
for($i=0;$i<$len;$i++)
{
if($fileset[$i]=="query")
{
$fileset[$i]="";
break; //then we will stop searching
}
}
$fileset_improve=implode($fileset); //this will again implode your file
$handle=fopen("file.txt","w"); //opening your file in write mode
fwrite($handle,$fileset_improve); //writing file with improved lines
fclose($handle); //closing the opened file
remember this lines will make your search line blank....
if you wanna then you can arrange whole array i.e. shifting following indexed data to previous index to decrease line counts but this will increase your programming complexity.
Hope this will work for you.
Thanks
Use PHP_EOL on your explode function instead of "\n". PHP_EOL will handle the correct line break character(s) of the server platform.
Related
I want to delete current iterating row from CSV file,
Suppose I have 5 rows (1,2,3,4,5) into my CSV file, I opened my file while iterating the rows one by one using foreach, when it comes to 3rd row then 3rd row should be deleted from CSV file and other 1,2,4,5 rows will be same while same iterration. I don't want to use like Skip the 3rd iterration and save it into another file, not like rename file name. So, Please anyone can help me how to do this in PHP?
Suppose, like SQL command to delete current row, is there anything in PHP?
Thanks.
You will need to have permissions to write the file. If you remove a row, you will have to save the file. As you do not want to have any empty rows as well, you need to read the whole file.
I suggest to get the file content, and split it into a array by lines. With the explode function you can split the content by the line break, most likely "\n". So an array wich will contain each line of the csv file will be existing. Now you can simply remove the line from the array and create a string out of it, before saveing the changed content back to the csv file.
// get csv content into string variable
$csvContent = file_get_contents(__DIR__ . "/yourfile.csv");
// create array out of csv, limited by PHP_EOL wich determines the systems line break
// this means, every line in the csv file will be represended by an array key and its value
$csvArray = explode(PHP_EOL, $csvContent);
// unset the 3th csv line.
unset($csvArray[2]); // keep in mind array starts at 0, so third line is array key 2
// from here on you can manipulate the array $csvArray as you like.
// add lines, remove lines or just use the given content for future operations.
// you can also iterate over the array with: foreach ($csvArray as $line => $value) {}
// create string out of modified csv array
$csvContent = implode(PHP_EOL, $csvArray);
// save result back into the csv file
file_put_contents( __DIR__ . "/yourfile.csv", $csvContent);
Check implode/explode php function docs:
http://php.net/manual/en/function.implode.php
http://php.net/manual/en/function.explode.php
I want to read a CSV data file, load it into an array, edit it and write it back to a file. I have been able to accomplish this a single iteration with examples here on Stackoverflow! Thanks.
The trouble is when I write the new data back to the file, both methods I have tried to write the edited Array back to the file add an newline at the end the file. This creates an issue when loading the CSV file data a 2nd time. The 2nd read causes an empty Index in the Array that causes an error when writing the file.
Example #1:
foreach($editArray as $row) {
$writeStuff = implode(",", $row);
fwrite($file_handle, $writeStuff);
fwrite($file_handle, "\n");
}
Example #2:
foreach ($editArray as $row) {
fputcsv($file_handle, $row);
}
This is the original csv data:
1/1/16,Yes,No
1/2/16,No,Yes
When written using the above it produces this data with the added newline:
1/1/16,Yes,No
1/2/16,No,Yes
This extra new line creates an issue when reading the file a 2nd time. I get an error on both the fputcsv() or implode(). I believe it is because the empty Index caused by the newline when I read the file the 2nd time after the first write.
I could use a for loop with a conditional on the last fwrite() in the implode() Example #1, but that would seem clunky and not the way to do it.
Maybe there is a completely different way to handle this?
This is the expected behaviour of fputcsv
fputcsv() formats a line (passed as a fields array) as CSV and write it (terminated by a newline) to the specified file handle.
Being that all lines are terminated by newline, you will have an extra blank line at the end of the file
You should apply a fix for the second read, where the last line creates issues, by checking if the line is empty before processing.
If you want to prevent adding a new line at the end of the file, you could build your data set with new lines where you need them (and where you don't) then write it once:
$writeStuff = [];
foreach($editArray as $row) {
$writeStuff[] = implode(',', $row);
}
fwrite($file_handle, implode(PHP_EOL, $writeStuff));
Also, I'm not sure how you load the file, but you could always skip empty lines - here's an example:
$editArray = file('your_filename.csv', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
Based upon the recommendation, I looked for a solution when reading and loading the file rather than when I wrote the file.
These are the solutions I came up with.
First Option:
while(! feof($file_handle)) {
$tmp = fgetcsv($file_handle);
if($tmp != NULL) {
$myArray[] = $tmp;
}
}
fgetcsv returns a NULL if the line is empty.
Second Option. Ditch the fgetcsv() for file(). It ignores the empty newline without testing.
$data_Array = file($file);
foreach($$data_Array as $key) {
$myArray[] = explode(",", $key);
}
This seems to work. Additionally the example given earlier with implode() and PHP_EOL seems to work also. I may be missing something, but these work for now.
Would appreciate some assistance
i have a txt file witht he following contents:
1234|dog|apartment|two
1234|cat|apartment|one
1234|dog|house|two
1234|dog|apartment|three
I want to delete the entry where the animal is "dog" living in an "house"
<?php
if (isset($_POST['delete_entry]))
{
//identifies the file
$file = "db.txt";
//opens the file to read
#$fpo = fopen($file, 'r');
//while we have not reached the end of the file
while(!feof($fpo))
{
//read each line of the file into an array called animal
$animal[] = fgets($fpo);
}
//close the file
fclose($fpo);
//iterate through the array
foreach ($animal as $a)
{
if the string contains dog and apartment
if ((stripos ($a, 'dog']))&&(stripos ($a, 'house')))
{
//dont do anything
}
else
{
//otherwise print out the string
echo $a.'<br/>';
}
}
}
?>
This successfully prints out the array without the entry where 'dog' and 'house' appears.
I need to write this back to the flat file though, but running into difficulties.
I have tried a variety of options include writting back to the file immediately when each entry is found.
Warning: feof() expects parameter 1 to be resource, boolean given in
Warning: fwrite(): 9 is not a valid stream resource in
Warning: fclose(): 9 is not a valid stream resource in
These are amongst the errors i have encountered. Now from my understanding of arrays,
- when i go through this array called animal,
- it checks index [0] for the two conditions and
- if the entry is not found, it assigns to to $a.
- It then goes through the array starting at index [1],
- and so forth.
Each time the new value is assigned to $a.
I thought that printing it to file each time it appears might work, but this is where i get the fwrite and fclose errors above, and no idea how to resolve this (yet).
I still have to do the bit where i need to replace 'apartment' with house, for one specifically selected entry, but will get there once I have sorted out the "delete"
I dont need code, maybe just a logic flow that might assist me.
Thanks
To save some time, you could store your data in array only if it passes your validation rules when it's being read from file, and after reading the end of file, you'd have array ready for writing it back to file.
How about this for steps:
Read the file.
Store File contents in array.
Remove item from array.
Overwrite the file with new contents.
What you can do is opening the source file in read mode and a temporary file in write mode. As you read content from the "in" file, you write lines to the "out" file. When the "in" file is processed and closed, you rename "out" to "in". This way you need to worry less about memory constraints.
When processing each line, it's better if you split on '|', so you know that the second element contains an animal name and the third element contains a housing name. Who knows if a cat is living in a doghouse.
<?php
$fileName = 'db.txt';
$data = #file($fileName);
$id = 0;
$animal = "";
$type = "";
$number = 0;
$excludeAnimal = array("dog");
$excludeHouseType = array("house");
foreach($data as $row) {
list($id,$animal,$type,$number) = explode("|",$row);
if(in_array($animal,$excludeAnimal) && in_array($type,$excludeHouseType))
continue
/* ... code ... */
}
?>
Although this doesn't answer your original question, I'd like to share what I've come up with.
I'm pretty sure this will do your entire script in three lines:
$file = file_get_contents( 'db.txt');
$result = preg_replace('/^\d+\|dog\|house\|\w+$/m', '', $file);
file_put_contents( 'db.txt', $result);
It uses a regex to replace the lines with dog|house, then writes the file back.
Read and dump all data until the one you want deleted into $array_1.
Read and dump rest of file into $array_2.
Concatenate 2 arrays in a $newarray, rewrite to original flatfile.
Simple!
I do have two text files and want to loop through both files then combine both line (line 1 of first test file and line1 of second text file. like that for thousands of lines) and do some function
I am familiar with loop through one file and for that code is given below:
$lines = file('data.txt');
foreach ($lines as $line) {
//some function
}
but how will I do for two files and combine bothe lines?
Not sure what you mean by search through the table, but to open both files and do stuff with them:
$file1 = fopen("/path/to/file1.txt","r"); //Open file with read only access
$file2 = fopen("/path/to/file2.txt","r");
$combined = fopen("/path/to/combined.txt","w"); //in case you want to write the combined lines to a new file
while(!feof($file1) && !feof($file2))
{
$line1 = trim(fgets($file1)); //Grab a line of the first file, note the trim will clip off the carriage return/new line at the end of the line, can remove it if you don't need it.
$line2 = trim(fgets($file2)); //Grab a line of the second file
$combline = $line1 . $line2;
fwrite($combined,$combline . "\r\n"); //Write to new combined file, and add a new carriage return/newline at the end of the combined line to replace the one trimmed off.
//You can do whatever with data from $line1, $line2, or the combined $combline after getting them.
}
Note: You might run into trouble if you hit the end of file on one file before the other, which would only happen if they aren't the same length, might need some if control statements to set $line1 or $line2 to "" or something else if feof() their respective files, once both hit the end of file, the while loop will end.
You can do this programmatically as Crayon and Tim have shown. If both files have the same number of lines, it should work. If the line number is different you will have to loop over the larger file to make sure you get all lines or check EOF on both.
To combine line by line, I often use the unix command paste which is very fast. This also accounts for files with different lengths. Run this on the command line:
paste file1 file2 > output.txt
See the manpage for paste for command line options, field delimiters.
man paste
Example:
$file1 = fopen("file1.txt", "rb");
$file2 = fopen("file2.txt", "rb");
while (!feof($file1)) {
$combined = fread($file1, 8192) . " " . fread($file2, 8192);
// now insert $combined into db
}
fclose($file1);
fclose($file2);
you will want to use the longer of the two files in the while condition.
you may need to adjust the bytes read in fread depending on how long your lines are
change " " to whatever delimiter you want
I have the following scenarion.
Everytime my page loads I create a file. Now my file has two tags within. {theme}{/theme} and {layout}{/layout}, now everytime I choose a certain layout or theme it should replace the tags with {layout}layout{/layout} and {theme}theme{/theme}
My issue is that after I run the following code
if(!file_exists($_SESSION['file'])){
$fh = fopen($_SESSION['file'],"w");
fwrite($fh,"{theme}{/theme}\n");
fwrite($fh,"{layout}{/layout}");
fclose($fh);
}
$handle = fopen($_SESSION['file'],'r+');
if ($_REQUEST[theme]) {
$theme = ($_REQUEST[theme]);
//Replacing the theme bracket in the cache file for rememberence
while($line=fgets($handle)){
$line = preg_replace("/{theme}.*{\/theme}/","{theme}".$theme."{/theme}",$line);
fwrite($handle, $line);
}
}
My output looks as follows
{theme}{/theme}
{theme}green{/theme}
And it needs to look like this
{theme}green{/theme}
{layout}layout1{/layout}
I rarely use random-access file operation but like to read it all as text and write ti back so I might be wrong here. BUT as I can see, you read the first line (so the pointer is at the beginning of the second line). Then you write '{theme}green{/theme}' into that file so it replaces the next position text (the second line).
In this case (as your data is small), you better get the hold file. Change it as string and write it back.