Executer un script longue durée sans limitation du serveur

Soyez le premier à donner votre avis sur cette source.

Snippet vu 13 876 fois - Téléchargée 18 fois

Contenu du snippet

Généralement quand on doit exécuter des scripts d'entretien de base de données par exemple, ceux-ci peuvent prendre plusieurs minutes si la base de données est conséquente.

Pour contourner le problème de limitation de temps d'exécution des scripts à 30 secondes, voici une astuce:
découper le gros script en sous-scripts de quelques secondes
La page ci dessous va donc executer une partie du script puis se relancer pour continuer l'execution du script dans une nouvelle page.

Placez votre script dans la fonction Script (au tout début de la page).

Source / Exemple :


<?php

// PRINCIPE :
// Le script est executé par tranches afin de ne pas surcharger
// le serveur.

// CONFIGURATION :
// Temps d'execution maximum d'une "tranche" en secondes
$tempsExecMax = 2;
// Temps d'attente entre chaque "tranche" en millisecondes
$tempsRepos = 100;
	
/*	----------------------------------------------------------
	Placez dans cette fonction le script à executer
		retour :
	Retourne une valeur qui sera utilisée pour relancer le
	script (valeur start lors de la prochaine execution de
	la fonction).
	Si cette valeur vaut -1, alors l'execution du
	script est terminée.
		start :
	Valeur repérant la valeur renvoyée par l'execution
	précédente de la fonction Script. Si cette valeur vaut 0,
	alors il s'agit de la première execution de cette fonction.
	Cette valeur n'est qu'un repère pour mémoriser
	l'avancement de l'execution, elle n'est pas utilisée hors
	de cette fonction. Elle peut donc représenter
	n'importe quoi.
		tempsExec :
	Temps maximum d'execution de la fonction. Si la fonction
	atteint cette limite, elle se termine et renvoie une
	valeur de retour.
	----------------------------------------------------------  */
function Script( $start, $tempsExec )
{
	// Repère le temps d'execution de la fonction
	list($usec, $sec) = explode(' ', microtime());
	$start_time=(float)$usec + (float)$sec;
	$new_time = $start_time;
	/*	----------------------------------------------------------
		Placez ici votre code d'initalisation si besoin

  • /
// ---------------------------------------------------------- // Tant qu'on reste dans le temps imparti while ($new_time - $start_time < $tempsExec) { /* ---------------------------------------------------------- Placez ici votre code
  • /
// ---------------------------------------------------------- // Temps d'exécution de la page list($usec, $sec) = explode(" ", microtime()); $new_time=(float)$usec + (float)$sec; } /* ---------------------------------------------------------- Précisez la valeur de retour
  • /
// return xxx; // ---------------------------------------------------------- } // Gestion de l'autorelancement de la page //ob_start(); header("Expires: Mon, 1 Dec 2003 01:00:00 GMT"); header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); header("Cache-Control: no-store, no-cache, must-revalidate"); header("Cache-Control: post-check=0, pre-check=0", false); header("Pragma: no-cache"); ?> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>Script longue durée</title> <meta http-equiv="CONTENT-TYPE" content="text/html; charset=iso-8859-1"/> <meta http-equiv="CONTENT-LANGUAGE" content="FR"/> <meta http-equiv="Cache-Control" content="no-cache/"/> <meta http-equiv="Pragma" content="no-cache"/> <meta http-equiv="Expires" content="-1"/> </head> <body style="font-family: Verdana; font-size: 12px"> <p style="font-size: 13px; font-weight: bold; margin-bottom: 30px"> Exécution d'un script de longue durée par découpage et relancement automatique. </p> <div> <p> Avancement de l'exécution : <?php // On récupère l'avancement du script $run = 0; if (isset($_GET['run'])) $run = $_GET['run']; $start = 0; if (isset($_GET['start'])) $start = $_GET['start']; // Affichage de l'avancement actuel if ($run == 1) { echo $start; } else { echo 'Exécution non démarrée'; } // Appel du script $start = Script( $start, $tempsExecMax ); // Si exécution terminée if (($run==1) and ($start == -1)) { echo '<br><b>Exécution terminée</b>'; } ?> </p> <?php // Si l'execution n'est pas démarrée ou est terminée if (($run != 1) or ($start == -1)) { // On propose de la démarrer ?> <p style="font-weight: bold"> <a href="<?php echo $_SERVER["PHP_SELF"]; ?>?start=0&amp;run=1" title="Lancer le script"> Démarrer l'exécution du script</a> </p> <?php } else // Si l'execution est lancée, on la continue { // Si l'execution n'est pas terminée if ($start > -1) { // Relancement du script if ($tempsRepos != 0) { ?> <p> Attente de <?php echo $tempsRepos; ?> millisecondes avant la reprise de l'execution. </p> <?php } echo ("<script language=\"JavaScript\" type=\"text/javascript\">window.setTimeout('location.href=\"".$_SERVER["PHP_SELF"]."?start=$start&run=1\";',500+$tempsRepos); </script>\n"); echo ("<noscript>\n"); echo ("<p><a href=\"".$_SERVER["PHP_SELF"]."?start=$start&run=1\">Cliquez ici pour continuer</a> (Activez JavaScript pour le faire automatiquement)</p>\n"); echo ("</noscript>\n"); echo ("<p><b><a href=\"".$_SERVER["PHP_SELF"]."\">Arrêter l'exécution du script</a></b></p>\n"); } } ?> </div> <p style="font-size: 11px; margin-top: 50px; text-indent: 0px; text-align: center"> Par <a title="Mon site web" href="http://matthieu.napoli.free.fr/"> Matthieu Napoli<a/> </p> </body>

Conclusion :


Votre script doit gérer 2 parametres :

Valeur de retour :
Retourne une valeur qui sera utilisée pour relancer le
script (valeur start lors de la prochaine execution de
la fonction).
Si cette valeur vaut -1, alors l'execution du
script est terminée.
parametre start :
Valeur repérant la valeur renvoyée par l'execution
précédente de la fonction Script. Si cette valeur vaut 0,
alors il s'agit de la première execution de cette fonction.
Cette valeur n'est qu'un repère pour mémoriser
l'avancement de l'execution, elle n'est pas utilisée hors
de cette fonction. Elle peut donc représenter
n'importe quoi.
parametre tempsExec :
Temps maximum d'execution de la fonction. Si la fonction
atteint cette limite, elle se termine et renvoie une
valeur de retour.

En espérant que ça vous serve

MadMatt

A voir également

Ajouter un commentaire

Commentaires

pouda
Messages postés
265
Date d'inscription
mercredi 18 décembre 2002
Statut
Membre
Dernière intervention
27 octobre 2014
-
exact merci pour ce code je regarde un peu ce que ca donne car je suis heberger chez 1and1 mutualise en safemod...et le set time limit est vraiment tres court...et pour l'envoie de mail sur phpBB c'est effectivement impossible (+ de 1500 mails)
MadM@tt
Messages postés
2215
Date d'inscription
mardi 11 novembre 2003
Statut
Membre
Dernière intervention
16 juillet 2009
-
set_time_limit n'est pas toujours disponible dans des hébergements mutualisés (et ça se comprend).
De plus, ça permet d'éviter des problème de mémoire (on ne sait jamais des script de plusieurs minutes... une erreur est vite faite), ça surcharge moins le serveur donc celui-ci continue à tourner (à peu près) normalement et donc on se fait pas engueuler par monsieur notre hébergeur.
cs_yoman64
Messages postés
592
Date d'inscription
samedi 19 janvier 2002
Statut
Membre
Dernière intervention
4 décembre 2008
-
Salut,

Biensur que oui sur un serveur tu peux configurer ça... Rare sont les hébergeurs qui désactivent la fonction set_time_limit (enfin rare, disont que ce n'est pas la majorité...sauf ceux qui ont le foutu safemod...)

Et euh... il me semble avoir vu une source semblable il n'y a pas très longtemps.

Ah ouais voila: http://www.phpcs.com/codes/EXECUTER-SCRIPT-DELA-TIMEOUT-PHP_45336.aspx
MadM@tt
Messages postés
2215
Date d'inscription
mardi 11 novembre 2003
Statut
Membre
Dernière intervention
16 juillet 2009
-
Oui mais sur un serveur tu ne peux pas le configurer.
webdeb
Messages postés
509
Date d'inscription
samedi 5 avril 2003
Statut
Membre
Dernière intervention
31 mars 2009
3 -
Le temps d'exécution maximum se configure dans le php.ini (max_execution_time)

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.