Quelle est la bonne façon de nettoyer les fichiers temporaires stockés en PHP?

Dec 01 2020

J'essaie de trouver un moyen de nettoyer mon espace de stockage temporaire en utilisant php. Je sais que je peux configurer des tâches cron mais, y a-t-il un moyen de le faire à partir de php lui-même?

J'utilise un dossier de stockage temporaire pour stocker les fichiers pdf générés que l'utilisateur peut télécharger. J'ai réussi à forcer une expiration sur le fichier afin qu'il ne soit plus accessible publiquement après 3 minutes. Maintenant le problème. Bien que le fichier ne soit pas accessible publiquement, il est toujours stocké sur mon serveur. J'ai codé quelque chose comme ça pour nettoyer le stockage.

/** from the main thread */
if (rand(1, 100) <= 5) {
    Reports::clean();
}

/** the clean function */
public static function clean()
{
    $path = static::getStoragePath(); if($dir_handle = opendir($path)) { while (($fileName = readdir($dir_handle)) !== false) { $file = $path . '/' . $fileName;
            
            if (!is_file($file)) continue; // If file is older that 3 minutes delete it if (time() - filemtime($file) > static::$expires) { unlink($file);
            }
        }
        closedir($dir_handle);
    }
}

donc cela nettoiera le stockage au hasard. C'est généralement bien. mais le problème est lorsque le nettoyage du stockage commence ce ralentir cette demande comme tortue.

J'ai donc pensé à créer un cronjob. Mais y a-t-il un bon moyen de le faire à partir de php lui-même?

Remarque: j'utilise slim-4, je n'ai pas non plus beaucoup d'expertise sur la configuration de cronjobs. Donc, toute ressource sera également utile

Réponses

3 MarcinJóźwikowski Dec 01 2020 at 17:04

Réponse courte: non.

PHP n'a aucun moyen d'auto-déclencher des actions.

Créez un script (ou une commande s'il s'agit d'un framework) et déclenchez-le avec un cronjob.

2 MarkusAO Dec 01 2020 at 17:23

Dans votre implémentation, chaque fois que la routine de nettoyage atteint le thread principal, en fonction du volume de fichiers dans votre répertoire PDF, cela peut créer un décalage important dans la réponse.

Comme indiqué dans les autres commentaires / réponses, un travail cron serait en effet la manière "standard" de gérer cela. Cependant, si vous n'avez pas accès aux tâches cron, ou si vous préférez simplement une solution PHP pure, il existe plusieurs approches possibles, en plus de ce que vous faites déjà.

  1. Gardez un journal des fichiers créés avec un horodatage de création. Lorsque la routine de nettoyage est appelée, au lieu d'effectuer une analyse complète du répertoire avec des vérifications d'heure modifiées, supprimez sur la base de votre enregistrement et purgez les entrées supprimées de l'enregistrement. Stockez votre enregistrement, par exemple sous forme de fichier JSON ou CSV / TSV. Cela devrait fournir une accélération significative dans les cas où il y a un volume important de fichiers, étant donné la réduction de l'accès au système de fichiers.

  2. Si vous ne voulez pas déranger vos utilisateurs avec le décalage de nettoyage, déplacez la routine des fichiers destinés aux utilisateurs vers des fichiers réservés aux administrateurs, ou effectuez une vérification de l'utilisateur administrateur et ajustez le déclencheur de fréquence de nettoyage (dans OP avec 1:20) pour correspondre à la fréquence d'utilisation de l'administrateur. Cela peut bien sûr réduire la fréquence de nettoyage (si les administrateurs ne sont pas là), mais soulagera le public.

  3. Enfin, évidemment, devenez M. Cron et déclenchez le nettoyage manuellement de temps en temps, quotidiennement ou avant que votre serveur ne manque d'espace. En général, à moins que vous ne soyez très limité sur l'espace, il ne semble pas nécessaire de nettoyer tous les 20 appels de page environ. Je n'ai aucune idée du volume de PDF générés, du trafic en cours ou des ressources du serveur, il est donc difficile de trouver des chiffres recommandés sur la fréquence de nettoyage.

TomiL Dec 01 2020 at 21:55

C'est un mauvais concept, utilisez le planificateur de tâches cron pour ce travail. Voici bash oneliner pour supprimer tous les fichiers du dossier / tmp / some_path si le contenu du dossier dépasse 10 Mo (veuillez le modifier en fonction de vos besoins):

SIZE=$(du -bs --block-size=1M /tmp/some_path | cut -f1); if [[ $SIZE -gt 10 ]];then echo "Folder '/tmp/some_path' has size ($SIZE MB)."; rm -r /tmp/some_path/*; fi

Vous pouvez coller ce code dans script.sh (inclure shebang par exemple pour bash #!/bin/bashen haut et rendre le fichier exécutable par exemple chmod +x script.sh), puis ajouter une nouvelle ligne au planificateur cronjob (par exemple crontab -e) pour vérifier la taille du dossier toutes les heures :

0 * * * * <path_to_the_script>/script.sh

Vous pouvez en savoir plus sur les cronjobs ici: https://crontab.guru