I have this function that will search and replace a given term inside a php file. When I pass an array with multiple files, the files are not modified and to avoid this problem I can only pass two files at time. How I can fix or improve this function? I think that the issue is because multiple files will occupy too much memory, but I'm not sure about this. Any help is appreciated. (I'm testing the function using a wordpress installation to find and replace the wp-prefix of some folders and files).
function wp_settings_edit(array $filename, array $patterns, array $replace){
foreach($filename as $file){
$wp_file = file_get_contents(__DIR__."/{$file}");
foreach($patterns as $pattern){
foreach($replace as $r){
$wp_file_content = file_put_contents(__DIR__."/{$file}",str_replace("{$pattern}", "{$r}", $wp_file));
}
}
}
}
Usage example:
$files = array('wp-settings.php', 'wp-load.php');
$patterns = array('wp-admin', 'wp-includes');
$replace = array('admin', 'includes');
wp_settings_edit($files, $patterns, $replace);
Unless your files are very large – like hundreds of megabytes – you're certainly not running into memory limits. You are, however, doing this quite inefficiently.
You run a foreach loop on both the search and replace arrays, making an exponential increase in the number of file writes. If str_replace()
only accepted string arguments, you could get rid of one of these loops. However, it accepts array arguments, so you can get rid of both.
function wp_settings_edit(array $filename, array $patterns, array $replace){
foreach($filename as $file){
$wp_file = file_get_contents(__DIR__ . "/$file");
file_put_contents(__DIR__ . "/$file", str_replace($patterns, $replace, $wp_file));
}
}
This will improve efficiency and what's more, it will actually do the job you want it to. By doing a nested loop over both arrays, as in the original code, you would end up replacing every item in the search array with only the first element of the replacements array:
$s = ["foo", "bar", "baz"];
$r = ["oof", "rab", "zab"];
$h = "Here is some foo text as well as some bar text and maybe some baz text.";
foreach ($s as $s1) foreach ($r as $r1) $h = str_replace($s1, $r1, $h);
echo $h;
Output:
Here is some oof text as well as some oof text and maybe some oof text.