web-dev-qa-db-fra.com

PHP: exécution de travaux planifiés (travaux cron)

J'ai un site sur mon webhotel sur lequel j'aimerais exécuter certaines tâches planifiées. Quelles méthodes de réalisation recommanderiez-vous?

Ce que j’ai pensé jusqu’à présent, c’est de placer un script en haut de chaque page, puis de laisser ce script vérifier s’il est temps d’exécuter ce travail.

Ceci est juste un exemple rapide de ce à quoi je pensais:

if ($alreadyDone == 0 && time() > $timeToRunMaintainance) {
   runTask();
   $timeToRunMaintainance = time() + $interval;
} 

Quelque chose d'autre que je devrais prendre en considération ou y at-il une meilleure méthode que celle-ci?

38
Eikern

C'est pour ça que les cronjobs sont faits. man crontab en supposant que vous utilisez un serveur linux. Si vous n'avez pas d'accès Shell ou aucun moyen de configurer des tâches cron, des services gratuits vous permettent de configurer des tâches cron sur des serveurs externes et d'envoyer une requête ping à l'une de vos URL.

33
Armin Ronacher

Je réponds maintenant parce que personne ne semble avoir mentionné cette solution exacte.

Sur un site sur lequel je travaille actuellement, nous avons configuré un travail cron à l'aide de cPanel, mais au lieu d'exécuter directement l'interpréteur PHP (car nous utilisons CodeIgniter et que notre code est mappé sur une fonction de contrôleur, ce n'est probablement pas une bonne idée) nous utilisons wget.

wget -q -O cron_job.log http://somehost/controller/method

-q fait en sorte que wget ne génère aucun résultat (afin que vous ne continuiez pas à recevoir des courriels). -O cron_job.log enregistre le contenu de tout ce que votre contrôleur génère dans un fichier journal (écrasé à chaque fois pour éviter sa croissance).

J'ai trouvé que c'était le moyen le plus simple de faire fonctionner le bon cron.

16
user7094

Si vous avez un hôte cPanel, vous pouvez ajouter des tâches cron via l'interface Web. Allez à Options avancées -> Travaux cron et utilisez le formulaire non avancé pour configurer la fréquence cron. Vous voulez une commande comme celle-ci:

/usr/bin/php /path/to/your/php/script.php
12
David McLaughlin

Avez-vous déjà regardé ATrigger ? La bibliothèque PHP est également disponible pour commencer à créer des tâches planifiées sans surcharge.

Disclaimer: Je fais partie de leur équipe.

5
Kousha

si vous vous demandez comment exécuter votre script PHP à partir de cron, vous avez le choix entre deux options: appelez directement l'interpréteur PHP (par exemple, "php /foo/myscript.php") ou utilisez lynx (lynx http://mywebsite.com/myscript.php ). Le choix que vous choisissez dépend principalement de la manière dont votre script a besoin que son environnement soit configuré: les chemins d'accès et les autorisations d'accès aux fichiers seront différents selon que vous l'appelez via Shell ou le navigateur Web. Je recommande d'utiliser le lynx.

Un des effets secondaires est que vous recevez un courrier électronique à chaque exécution. Pour résoudre ce problème, je fais en sorte que mes scripts cron PHP ne génèrent rien (et ce ne doit être rien, pas même un espace) s'ils aboutissent et un message d'erreur en cas d'échec. Je les appelle ensuite en utilisant un petit script PHP de cron. De cette façon, je ne reçois un e-mail qu'en cas d'échec. C'est fondamentalement la même chose que la méthode lynx, sauf que mon script Shell fait la requête HTTP et non pas lynx.

Appelez ce script "docron" ou quelque chose de ce genre (rappelez-vous de chmod + x), puis utilisez la commande de votre crontab: "docron http://mydomain.com/myscript.php ". Il vous envoie par courrier électronique le résultat de la page sous forme de courrier HTML, si la page renvoie quelque chose.

#!/usr/bin/php
<?php

$h = @file_get_contents($_SERVER['argv'][1]);

if ($h === false)
{
        $h = "<b>Failed to open file</b>: " . $_SERVER['argv'][1];
}

if ($h != '')
{
        @mail("[email protected]", $_SERVER['argv']['1'], $h, "From: [email protected]\nMIME-Version: 1.0\nContent-type: text/html; charset=iso-8859-1");
}

?>
5
MrZebra

Si vous voulez éviter de créer des tâches cron et autres (bien que je dirais que c'est une meilleure méthode), la solution que vous avez fournie est assez bonne. Sur un certain nombre de projets, le script PHP lui-même vérifie s'il est temps d'exécuter la mise à jour.

L'inconvénient (ok, un des inconvénients) est que si personne n'utilise l'application pendant une certaine période, le script ne s'exécutera pas.

L'avantage, c'est que si personne n'utilise l'application pendant une certaine période, le script ne s'exécutera pas. Les tâches que j'ai configurées sont les suivantes: "mettre à jour un fichier de cache", "effectuer une sauvegarde quotidienne" et ainsi de suite. Si quelqu'un n'utilise pas l'application, vous n'aurez pas besoin de fichiers de cache mis à jour, ni de modifications de la base de données à sauvegarder.

La seule modification de votre méthode suggérée est que vous n'exécutez ces contrôles que lorsque quelqu'un se connecte avec succès. Vous n'avez pas besoin de vérifier chaque chargement de page.

4
nickf

Cron est une solution polyvalente pour les problèmes de planification. Mais quand vous allez gros et que les horaires vont en fréquence, il peut y avoir des problèmes de fiabilité/chevauchement. Si vous voyez de tels problèmes, envisagez quelque chose comme supervise ou plus sophistiqué monit .

4
mixdev

Si vous utilisez cpanel, vous devriez ajouter ceci comme ceci: 

/usr/local/bin/php -q /home/yoursite/public_html/yourfile.php
3
mokiSRB

La méthode que vous utilisez convient, si vous ne souhaitez pas utiliser de tâches cron ou autres tâches externes, mais elles peuvent être lourdes à vérifier chaque fois qu'une page est chargée.

Au début, certaines tâches cron peuvent probablement être remplacées. Par exemple, si vous avez un compteur du nombre d'utilisateurs enregistrés sur votre site Web, vous pouvez simplement mettre à jour ce numéro lorsqu'un utilisateur s'enregistre, de sorte que vous n'ayez pas à utiliser de tâche cron ni aucune tâche planifiée à cet effet.

Si vous souhaitez utiliser des tâches planifiées, je vous suggère d'utiliser la méthode que vous utilisez actuellement, mais avec quelques modifications. Si votre site contient suffisamment de visites chaque jour, vous pouvez simplement exécuter les tâches (ou exécuter la fonction de vérification des tâches) uniquement pour 1% ou peut-être 0,01% des visites au lieu de toutes, le pourcentage que vous devez utiliser dépend sur la page que vous avez et combien de fois vous voulez exécuter la tâche. Donc, ajoutez simplement un randomiseur pour obtenir cette fonctionnalité.

Vous pouvez simplement utiliser une fonction comme celle-ci;

if(Rand (1, 100) <= 1) { // 1, 100 is used to generate a number between 1 and 100. 1 is for one percent.
    // Run the tasks system
}

J'espère que cela t'aides,

1
Tim Visée

J'externaliserais les tâches avec www.guardiano.pm et appellerais une URL toutes les X minutes. Lorsque votre URL (c'est-à-dire www.votresite.com/dothis.php) est appelée, vous exécutez du code. Si vous ne souhaitez pas que le Web demande la page quand vous le souhaitez, vous pouvez uniquement autoriser la demande dans POST et envoyer un paramètre que vous seul connaissez avec guardiano.pm 

Cest ce que je ferais parce que je le fais sur mes projets de compagnie. S'amuser! 

1
Lorenzo Sinisi

La ligne de commande PHP + cron serait ce que je voudrais faire. C'est simple et devrait convenir. Il est généralement installé avec PHP.

0
Gavin M. Roy

Si vous n'avez pas la possibilité de configurer un cronjob, vous pouvez appeler le script avec cUrl (au lieu de wget - même fonctionnalité). Effectuez simplement une tâche planifiée sur votre ordinateur local qui exécute la fonction cUrl.

0
meeeeeh

Si vous voulez quelque chose de plus abstrait, vous pouvez utiliser quelque chose comme un planificateur PHP. Par exemple: 

De plus, pour analyser l'expression cron, vous pouvez utiliser une bibliothèque existante telle que https://github.com/mtdowling/cron-expression . Il fournit de nombreuses méthodes utiles pour vous aider à comprendre les informations d'un travail cron.

J'espère que cela pourra aider.

0
XuDing