Working on a small script that will read in a file containing filenames, and check if the filename is to be deleted or not. My in_array() function only seems to work on the last entry in the earray. Here is the code …
<?php
$files = array(
'403.php',
'404.php',
'406.php',
'414.php',
'500.php',
'501.php',
'favicon.ico',
'.htaccess',
'robots.txt');
print_r($files);
$handle = @fopen('WP_ro_files.txt', "r");
if ($handle) {
while (!feof($handle)) {
$filenames[] = fgets($handle, 4096);
}
fclose($handle);
}
//print_r($filenames);
foreach ($filenames as $filename) {
$delete_ok = 1;
if (in_array($filename, $files)) {
echo "Filename found - $filename\
";
$delete_ok = 0;
} else {
$pieces = explode("/", $filename);
$result = count($pieces);
$path = $pieces[1]; //get the second element, which is the path or filename
if ($path == "plugins"){ //no files to be deleted in the plugins path
$delete_ok = 0;
}
if ($path == "themes"){ //no files to be deleted in the themes path
$delete_ok = 0;
}
}
if ($delete_ok){
echo "File to be deleted - $filename\
";
//put code here yo unlink the file (path name + filename)
} else {
echo "File will not be deleted - $filename\
";
}
}
?>
When a file is matched from the array $files, it is expected to find an entry, but it only finds the last one ??
Noticed that no matter what method I used to load the file into an array, the results were the same, only one match. This match was the last value in the array, and then noticed all other lines has spaces to the right of the filename. So, added this …
foreach ($filenames as &$filename) {
$filename = rtrim($filename);
}
and got all expected matches. There must be a more elegant method to load a file into an array, and do a “rtrim” at the same time ??
The in_array() works okay now, it was the method I was using to load the file, should be doing a right trim on ach line in file.
while (!feof($handle)) {
$filenames[] = rtrim(fgets($handle, 4096));
}
Since fgets() should stop reading when it reaches a new-line, you might also want to take a look at the script that creates the file in input (if it’s created by one of your scripts) and make sure a new line character is placed directly after the filename, leaving no tracing spaces.
So what am I doing here?
[FPHP]file/FPHP returns the file, split into an array.
[FPHP]array_map[/FPHP], in the optional step, applies the [FPHP]trim[/FPHP] function to every element of the array.
Changing the search is plain enough; putting it into regex so that it can be read into a preg function.
Filtering the array:
[FPHP]preg_filter[/FPHP] goes through the array, and filters out any files that do not match one of the patterns. This will leave a result of every file in the array that is in your ‘skip list’.
[FPHP]array_diff[/FPHP] then takes that result, and subtracts those entries from the original array; resulting in the files that were NOT in your ‘skip list’.
I first wanted to say file(), then decided against it because it loads the entire file at once which could create a problem with a huge file. Which of course is a no-reason, because in the code the entire file is loaded in an array anway… duh.
Thanks for the code tips, and explaining what each function does. I’m not familar with regex, but can see what the patterns will do. The script might get down to just a few lines now.
the dump returns all filenames. The preg_filter() function has the array $files defined as 2 parameters, the “pattern”, and the “replace”. Is that correct ?
I think the contents of $filenames is causing unexpected results. There are filenames like