Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

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

share|improve this question
    
what do these array items correspond to? lines?, I think running something like sed on these files would be a lot faster than reading->parsing->processing->saving –  Mohammad AbuShady Feb 23 at 15:27
    
the array is words....for example first i parse the file and gather all fruit words from the file....which i want to replace with vegetable words...each one is replaced by its equivalent. getNewValueFor() does that for me. Replaces word : apple with potato. And i use the preg_replace('/\\b'.$value.'\\b/' to match EXACTLY that value only, as many times as it appears in the text. –  user1033882 Feb 23 at 15:31
    
@NeilMasters: the g modifier doesn't exist in PHP. –  Casimir et Hippolyte Feb 23 at 15:33
    
Your right. My brain is mush today :) –  Neil Masters Feb 23 at 15:36
    
I am curious of the content of makeArrayOfValuesToReplace() and getNewValueFor(). Could you post these two functions? –  Casimir et Hippolyte Feb 23 at 15:56
show 1 more comment

2 Answers

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.

share|improve this answer
    
Not sure i follow what you are saying here. It took me forever to get the array the way i want it...and to bring this function to the bare minimum...str_replace isnt the problem....the problem is that i have to 1st change all occurrences of the strings....but HOLD THAT somehow to a value that outside the loop i can use to write to a file. This will be the fastest way possible (i think) to parse 100 files with some having 100 values to change.... –  user1033882 Feb 23 at 15:33
    
You just have 2 arrays $search = array('apples', 'oranges'); $replace = array('pears', 'lemons');. Then $newFileContents = str_replace($search, $replace, $holdcontents); Then all occurrences of 'apples' will be changed to pears and all 'oranges' will be changed to 'lemons' –  Galadai Feb 23 at 15:39
    
I dont think you are getting the problem here. The algorithm that i am trying to do here is this: Open file, while file is open replaces for each array value "this" to "this", hold somehow the whole result in a value, close the while file is open, and write that value to the file replacing what was there in the first place. Edit: There must be a preg_replace to be safe i am replacing ONLY these values. maybe a word starts with apple...like applesauce...i dont want to replace that....just any occurrence of apple. just that. Besides why are you stuck to the str_replace :) ? That working fine... –  user1033882 Feb 23 at 15:40
    
Just added an edit with the code. All apples in the file will be replaced by pears and all oranges replaced by lemons. You would obviously set up your own search and replace arrays... –  Galadai Feb 23 at 15:48
    
str_replace is many times faster than preg_replace, that's why I was suggesting that. If speed isn't a problem, then use preg_replace and you are right that it does solve the word boundary problem. –  Galadai Feb 23 at 16:00
show 1 more comment

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.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.