0

I'd like to report how many files get deleted from a function that I'm running within php via a cron task.

Current codes is as follows:-

<?php

function deleteAll($dir) {
    $counter = 0;
    foreach(glob($dir . '/*') as $file) {
        if(is_dir($file)) {
            deleteAll($file); }
        else {
            if(is_file($file)){
// check if file older than 14 days
                if((time() - filemtime($file)) > (60 * 60 * 24 * 14)) {
                    $counter = $counter + 1;
                    unlink($file);
                } 
            }
        }
    }
}   

deleteAll("directory_name");

// Write to log file to confirm completed
$fp = fopen("logthis.txt", "a");
fwrite($fp, $counter." files deleted."."\n");
fclose($fp);

?>

That makes sense to me with a VBA background, but the counter returns null I think when written to my custom log file at the end. I presume there is some restriction on a shared hosting site of being able to declare the variable globally or similar?

Appreciate any help! It's not the end of world if I can't count the deleted files, but it would be nice to log the output in the format I've chosen.

larkim
  • 3
  • 1
  • 1
    Have the function `return $counter`. Right now you're dealing with a scope issue where the `$counter` used in your `fwrite()` call is not the same one as inside of your function. – Patrick Q Feb 04 '19 at 15:56
  • Simply a scope issue. Take a look at [this question](https://stackoverflow.com/questions/5631962/php-variable-scope) and [this question](https://stackoverflow.com/questions/16959576/reference-what-is-variable-scope-which-variables-are-accessible-from-where-and) for details. – Dave Feb 04 '19 at 16:17

1 Answers1

0

This doesnt work due to scopes. In your example $counter only exists inside your function.

function deleteAll($dir):int {
    $counter = 0; // start with zero
    /* Some code here */
    if(is_dir($file)) {
        $counter += deleteAll($file); // also increase with the recursive amount
    }
    /* Some more code here */
    return $counter; // return the counter (at the end of the function
}

$filesRemoved = deleteAll("directory_name");

Alternatively, if you want to send back more info, eg 'totalCheck' etc, you can send back an array of info:

function deleteAll($dir):array {
    // All code here
    return [
        'counter' => $counter,
        'totalFiles' => $allFilesCount
    ];
}
$removalStats = deleteAll("directory_name");
echo $removalStats['counter'].'files removed, total: '.$removalStats['totalFiles'];

There are other solutions like 'pass-by-reference', but you dont want those.

Martijn
  • 15,791
  • 4
  • 36
  • 68
  • An alternate following some PHP functions: `function deleteAll($dir, &$counter)` then call as `deleteAll("directory_name", $filesRemoved);` But I would only use this if the function needs to return something else. – AbraCadaver Feb 04 '19 at 15:57
  • And even then I'd change the function so I dont have to reference. IMO it's a code smell. – Martijn Feb 04 '19 at 16:01
  • Thanks all - rapid respones! Think I've got my head around that, just a different concept to VBA on the basis of scope where you can't declare variables I suppose. – larkim Feb 04 '19 at 16:17
  • Hmmm. Still having issues with this. In my code, I've amended to call the funciton with "$filesRemoved = deleteAll("dir_name"); and added "return $counter; at the end of the "if" which tests the files age. But this bails out on me. If I add "return $counter" to the final sub clause of the if statement, no error is thrown but it just returns "0". – larkim Feb 04 '19 at 16:44
  • @Martijn So I've amended my code to add as per your first suggestion 'return $counter' but all I'm getting returned is the default value I'm setting '$counter' to at the beginning. I can output the incremental count within the if statement, but it isn't being sent at the end. I'm clearly doing something daft, but can't quite see it!! – larkim Feb 04 '19 at 17:09
  • In PHP, if you return, all following code wont be excuted. You want to put the return before the final closing bracket, at the end of the function – Martijn Feb 05 '19 at 08:12
  • @Martijn - think I've unpicked my issue - because the function is recursive and calls itself to iterate through the folders and subfolders, `$counter` gets reset each time as it only has scope within that function. So I can append the count to the log as it deletes each file, and can see it incrementing properly. But then every time it moves onto a new folder it resets back to 0 as each new folder prompts a new instance of that function. Will have to think around that a little!! Thanks for your help, it confirmed I was putting the `return` in the correct place. – larkim Feb 05 '19 at 12:58
  • Ah, recursiveness. I'll update my answer just a bit to provide that solution – Martijn Feb 05 '19 at 13:27
  • @Martijn Wondering if the counter set to zero at the beginning is potentially a problem for the recursiveness in your revised answer? Won't `$counter = 0` be executed on each recursion? – larkim Feb 05 '19 at 13:39
  • Yes you are correct. But thát `$counter` only has the value set to zero for thát itteration. – Martijn Feb 05 '19 at 13:44