Exécuter un script au-delà du timeout de php

Description

Ce script montre une méthode permettant d'exécuter un script au-delà du timeout de PHP.

J'en suis venu à cette idée ainsi: si je fais par exemple un export d'une grosse base de données avec un script PHP, je risque de dépasser les 30 secondes (le max_execution_time) autorisées par le serveur où je suis hébergé.

Alors comment faire? En associant AJAX à PHP!

Le principe: Ajax surveille que le script ne s'exécute que pendant un temps t<timeout et fait boucler le script jusqu'à ce que l'exécution soit terminée.

Le code présenté ici est un exemple. A vous de l'adapter si vous en avez l'intérêt!

Source / Exemple :


############# FICHIER index.php

<html>
	<head>
		<title>Exécuter un script au-delà du timeout de PHP</title>
		<!-- script mootools.js téléchargé sur http://mootools.net/download -->
		<script type="text/javascript" src="mootools.js"></script>
		<script type="text/javascript">
			<?php
			
				// temps maximal d'exécution du script autorisé par le serveur
				$max_time = ini_get('max_execution_time');
				// 30 secondes par défaut:
				if ($max_time == '') $max_time = 30;
				
				// on prend 10% du temps maximal comme marge de sécurité
				$ourtime = ceil(0.9*$max_time);
				
				// variable pour les tests, à retirer en production
				$ourtime = 4;
				
				// variable(s) devant être surveillée(s) - exemple
				$i = 10;
				
			?>
		
			window.addEvent('domready', function(){
				$('start').addEvent('click', function(e) {
					e = new Event(e).stop();
					var url = "time.php?t=<?php echo $ourtime;?>&i=<?php echo $i;?>";
					new Ajax(url, {method: 'get', evalScripts:true}).request();
				});
			}); 	
		</script>
	</head>
	<body>
		<h3>Exécuter un script au-delà du timeout de PHP</h3>
		<p><a id="start" href="#">Cliquez ici</a> pour lancer le test</p>
		Timeout après: <b><?php echo $ourtime;?> secondes</b><br />
		Temps d'une boucle: <b>environ 1 seconde</b><br /><br />
		Résultat:<br /><div id="result"></div>
	</body>
</html>

############# FICHIER time.php

<?php
header('Content-type: text/html; charset=iso-8859-1');

echo '<script type="text/javascript">'."\n";

// récupération des variables;
$main_ourtime = $_GET['t'];
$i = $_GET['i'];
$temps_total = $_GET['tillnow'];
$ourtime = $main_ourtime;

function timer(){ //chronomètre - http://www.phpcs.com/code.aspx?ID=32471
	$time=explode(' ',microtime());
	return $time[1] + $time[2];
}

$rep = '';

$start_while=timer(); // début du chronométrage du while
while ($i>0 && $ourtime>0){

	$start=timer(); // début du chronométrage de l'itération
	
	sleep(1); // traitement - le sleep simule un temps de traitement de une seconde
	
	$i--;
	
	$ourtime -= (int)number_format(timer()-$start,7);
	$rep .= $i.'... ';// texte de sortie
}
$end_while = number_format(timer()-$start_while,7);
$temps_total += $end_while;

echo '$(\'result\').innerHTML += \'<b>'.$rep.'(<font color="#00aa00">'.$end_while.' sec.</font>)</b><br />\';'."\n";

if($i>0){ // si l'exécution du script a été interrompue pour éviter le timeout, on reprend où on s'est arrêté
echo 'var url = "time.php?t='.$main_ourtime.'&i='.$i.'&tillnow='.$temps_total.'";

	new Ajax(url, {
			method: \'get\',';
if ($i>0)
	echo 'evalScripts:true,';
echo '}).request();';
}
else
	echo '$(\'result\').innerHTML += \'<b><font color="#0000aa">terminé en '.$temps_total.' secondes!</font></b><br />\';'."\n"; // traitement des données
	
echo '</script>';
?>

Conclusion :


AJAX est traité ici avec l'excellente librairie mootools disponible sur http://www.mootools.net

Une condition sine qua none pour que cette astuce fonctionne est que le temps d'exécution d'une itération dans la boucle soit inférieur au time out.

L'exécution de l'exemple ci-dessus donne:

9... 8... 7... 6... (4.0000000 sec.)
5... 4... 3... 2... (4.0000000 sec.)
1... 0... (2.0000000 sec.)
terminé en 10 secondes!

Codes Sources

A voir également

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.