I have an array and an external file, both contains lots of words. I want to match strings in the array with the entire external file. Then if there are identical words, I want to delete the word from the array.
Much shorten example:
$words = {"apple", "orange", "banana", "grape", "peach"}
The external text file is a pure list of words
apple
banana
melon
...
I'd like to delete the words that are in the external file, and finally get this.
$words = {"orange", "grape", "peach"}
Should I call the external file, slice every line, then save them to another array? Then compare with the source array?
What is the most effective way to compare the array and a text file?
I'd appreciate your wisdom!
You could use array_diff.(file to get an array from file.)
$result = array_diff($words, file('path_to_file', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES));
PS: If your external text file is very big, and you don't want to load it to memory at one time, you could read it line by line, and check it whether it exists in the array.
Related
I apologize if this question has a no brainer answer. I am still learning more ins and outs of php.
I have a snippet of code that is taking in a CSV file. This CSV file is uploaded by a user who downloads it from an external source. In the CSV file, the person's first name and last name is not split in separate columns. Therefore, in PHP the following is used:
$member_name = explode( " ", $application_data[5]);
The problem is that when this data is then used to render a PDF document to send a letter to the member, it cuts off their last name if their last name is two words.
The information is loaded into the PDF document with the first name and last name field by using:
$member_name[0],
$member_name[1]
Can I safely do:
$member_name[0],
$member_name[1] + $member_name[2]
Even if 99% of the members do not have a space in the last name? Will I get an error that member_name[2] doesn't exist 99% of the time this is done?
I've done some searching on array_merge. Is that a better option? I've been trying to search for how php handles when you add something that doesn't exist and I'm drawing a blank.
I don't want to assume my solution will work and then when the person uploads their CSV file tomorrow, they get an error.
Or maybe I'm looking at this the wrong way and before it attempts to render a pdf document, I should do an if statement that figures out if $member_name[2] exists.
Thank you!
You can use the limit parameter of explode to only split at the first space.
$member_name = explode( " ", $application_data[5], 2);
Of course, if the first name also has more than one word, this still won't be quite right. Names are tricky.
Regarding array_merge, I don't think it would really be useful in this situation.
You could just use a limiter on your explode to only seperate on the first space. Here is an example.
$name = "George The King";
print_r(explode(' ', $name, 2)); //prints -> Array ( [0] => George [1] => The King )
This is a tricky one...I am trying to replace some strings in a file that i hold in array.
Because there are a lot of files...i've been trying to find the fastest way possible.
I tried this (which worked) but it was slow.
First parsed all the files and got an array of the values i want to
change (lets say 500).
Then I wrote a foreach loop to parse through the files one by one.
Then inside that, another foreach loop to go through the values one by one
preg_replacing the file for any occurrences of the array value.
This takes forever though cause not all files need to be parsed with 500 array elements.
So i am changing the code now like this:
Parse every file and make an array of the values i want to replace.
Search the file again for all the occurrences for each array value and replace it.
Save the file
I think this will be much faster that the old way...The problem i am having though now is with the read/write loop, and the array loop...
I want to do this as fast as possible...cause there will be a lot of files to parse and some have 100+ values.
So far i got this in a function.
function openFileSearchAndReplace($file)
{
$holdcontents = file_get_contents($file);
$newarray = makeArrayOfValuesToReplace($holdcontents);
foreach ($newarray as $key => $value) {
$replaceWith = getNewValueFor($value);
$holdcontent = preg_replace('/\\b'.$value.'\\b/', $replaceWith, $holdcontents);
}
file_put_contents($file, $holdcontent, LOCK_EX); //Save and close
}
Now, this doesnt work...it just changes 1 value only because i have file_put_contents and file_get_contents outside of the foreach. (Not to mention that it replaces values that it shouldnt replace. Probably cause the read/write are outside of the loop.) I have to put them inside to work..but thats gonna be slow..cause it take 3-4seconds per file to do the change since there are a lot of elements in the array.
How can i "Open the file", "Read it", "Change ALL values first", "Then save close the file", so i can move to the next.
EDIT:
Maybe i am not explaining it well i dont know...or is this too complicated....I have to parse the array of values...there is no way i can avoid that...but instead of (In every loop), i open the file search and replace 1 value, close the file.....I want to do this:
Open the file, get the content in an array or string or whatever. For all the values i have keep replacing the text with the equivalent value, and when all the values are done...that array or string write to the file. So i am only opening/closing the file once. Instead of waiting for php to read/write/close all the time.
-Thanks
How about just using str_replace(mixed $search , mixed $replace , mixed $subject)?
You can have an array of search strings which will be replaced by their corresponding item in the replace array and as the PHP manual says:
If you don't need fancy replacing rules (like regular expressions), you should always use this function instead of preg_replace().
Also just close the file and reopen it with mode 'w'. File will be truncated to 0 length
Added Edit
$fileContents = file_get_contents("theFile");
$search = array('apples', 'oranges');
$replace = array('pears', 'lemons');
$newContents = str_replace($search, $replace, $fileContents);
$handle = fopen("theFile","w");
fwrite($handle, $newContents);
fclose($handle);
That's it your file has all the old strings replaced with new ones.
There is no solution to the problem. file_get_contents and file_put_contents simply doesnt work like that.
I appreciate everyone's attention to the problem.
I have a php file that has an array in it. I'd like to be able to add an item to that array using a simple form.
Here is an example similar to my array:
$list = array("BA0UKSF","BA9IHHE","BAC8GMB","BAC8HMC","BAC8HMC","BAC8HMC","BACI60T","BAEIDFD","BAEIEFE","BAEIEFE","BAMB0","BAOUKSE","BAOUKSF","BAPQADL","BAPQADM","BUNDLE","CN3ICDC","CN3ICDCA","CN7IZDPA","CN8ID42","CN8ID72","CNECBCBA");
I'd like to add the new item to the array someplace either at the beginning or end of the array list.
I know how to pass the forms data to php but what I dont know is how to get php to open this file, locate the array and add something to it.
I'd just store your array data in JSON format what makes it very easy to operate on the array.
Reading array:
$list = json_decode(file_get_contents($file));
Saving array:
file_put_contents($file, json_encode($list));
Reasons:
It is very bad practice to patch PHP code. (difficult to maintain; will possibly stop to work as you change the code in the file etc.)
If your input you add to $list is user-input and not 100% validated, it may be malicious code in it...
You can parse the text file line by line and locate the array first. And then, you can simply use:
array_push() -- if you want to add elements to the end of the array
array_unshift() - if you want to add elements to the beginning of the array
Examples:
array_push($list, "CN7IZDPA"); //adding to the end
array_unshift($list, "CN7IZDPA"); //adding to the beginning
But reading your array definition from a text file seems like a bad idea. You really should use a database as it makes managing the stuff easier.
Hope this helps!
I have the following CSV file:
08-0018421032;00-0018151831;G-20009429-0;G-20009429-0;0374048-0
27-001842101232;10-0018151831;G-30009429-0;G-50009429-0;7374048-0
36-0018421033232;20-0018151831;G-40009429-0;G-60009429-0;8374048-0
As you can see the separator is the ; symbol.
I then send this info to php via a jquery plugin which works perfect since I can read the file in PHP. The following code grabs the CSV file (Which is the $csvfile variable) and I can see the lines in it:
$file = fopen("upload/$csvfile", "r");
while (!feof($file) ) {
$line = fgetcsv($file, 1024,';');
print $line[0].'<br/>';
}
fclose($file);
What I need is to be able to select not only the line but on the value in it. To go to a specific value, for example in the first line the 3rd value would be G-20009429-0 and I would assign this to a php variable to be used later on.
Right now I have no idea how to grab a specific value in a line and also when I print the $line[0] it shows the values in a vertical order instead of a horizontal order. What I mean with this is that it shows the following output:
00-0018151831
10-0018151831
20-0018151831
Instead of showing me like this:
08-0018421032;00-0018151831;G-20009429-0;G-20009429-0;0374048-0
Maybe is the sleep but am stuck here. Just to repeat, the csv file is read by Php correctly since I can do a print_r on it and it shows all the lines in it. The thing is how to manipulate the information after I have the csv and how to grab a specific value in a specific line. Thank you.
$line is an array containing every element from that row. $line[0] is the first element of the row, $line[1] the second element and so on. Try var_dump($line). What you're doing is you output every first element of every row.
If you want to output every element in one line, just concatenate the array again:
echo join(';', $line);
But then that's missing the point of fgetcsv, which is specifically helpfully separating those elements into an array for you so you can work with them.
I am trying to make a news feed type thing in php.
I have a text file - news.txt and a php file index.php.
I have done the surrounding code and opening/closing the text file. Now I am stuck how to insert the new news item $newsnew to the top of the news.txt file and how to delete the old bottom news file in the news.txt file.
Is there any way to do this without deleting the whole file and writing it all again?
EDIT: Each news item is just a small string, say 500 characters, a single line.
Use a database.
If you really must use text files, use a different file for every news-item and name them sequentially like:
news001.txt
news002.txt
etc.
Then you can just add and delete files, read the directory and display what´s there.
Use the file() function to import the items in news.txt as an array, and use array_unshift() to add the new first item, and array_pop() to remove the last item. Join the array back into a single string and write it to news.txt:
$items = file('news.txt');
array_unshift($items, 'New item 1');
array_pop($items);
$newstext = implode(PHP_EOL, $items);
// write $newstext to the external file
If this is a XML file you could read it, parse it and delete the last child in the DOM. But if you have all your data in a DB it could be much easier to rewrite the file every time.
EDIT: after your edit: yes, you can do it like this:
write your new line to a new file
read the old file line by line and write it to the new one
skip the last line (detected by counting or EOF)
delete the old file and rename the new
No, there is not. But you might consider storing the messages in revers order. That way you only need to append to news.txt when new news arrive.
You are not going to be able to prepend to the beginning of the file without writing the whole thing out again. You could append to the end of it with the "a" mode flag to fopen(), but still to delete the oldest item you'll need to write out the entire file again.
Really, a database is solution here instead of a single text file.
There are many ways you can do it using the flat text file, but I'm not really sure it it's worth it. You can use some lightweight structured file or embedded database. For example SQLite, which would store it in normal file, no additional setup needed.