Code Tips and Snippets


Pas encore membre ?
Cliquez ici pour vous inscrire.
Vous pourrez poster des commentaires.
N'autoriser l'exécution que d'une seule instance d'un script php
Posté par pk le Dimanche 21 Septembre 2014 à 16:37:43
Niveau 4 étoilesLangage phpSystème d'exploitation Linux

Quelle bonne idée d’administrer un serveur linux en écrivant des scripts php plutôt que des scripts shell...

Nous avons déja vu comment exécuter des scripts php en suid root

On rencontre souvent le besoin de pouvoir exécuter un script en étant sur que ce même script ne s’exécute pas plusieurs fois en même temps... on dit dans le jargon informatique que l’on ne souhaite exécuter qu’une seule instance de ce script à la fois.

On va se servir des classes php pour arriver à nos fins... en particulier, le fait que lorsqu’un script se termine, le destructeur des objets instanciés est appelé automatiquement.

Passons directement aux choses sérieuses en dévoilant un exemple de code que vous pourrez adapter à vos besoins.

class SingleInstanceProcess
{
	private	$pid_file;
	public	$is_ok;

	function __construct()
	{
		global $argv;

		$this->is_ok	= 0;
		$my_name		= basename($argv[0]);
		$this->pid_file	= "/tmp/$my_name.pid";
		$pid			= getmypid();				if (!$pid) exit(1);

		$this->is_ok	= 1;
		if (file_exists($this->pid_file))
		{
			$old_pid	= file_get_contents($this->pid_file);
			$cmd		= "ps -Cp $old_pid | grep $my_name";
			$result		= trim(`$cmd`);
			$t_result	= explode(" ",$result);
			$result		= $t_result[0]; 
			if ($old_pid==$result)			// le programme s'exécute déjà ou (bug acceptable) :
			{								// 			Si l'ancien programme a été tué ( i.e. kill -9  ou coupure secteur et /tmp non vidé)
				$this->is_ok	= 0;		//			et qu'un autre programme avec exactement le même nom s'exécute
				return;						//			et qu'il a récupéré exactement le même pid que le processus tué... 
											//			(en pratique la probabilité est négligeable)
			}								//			alors on supposera de façon erronée qu'une instance de notre programme tourne déjà...
		}
		file_put_contents($this->pid_file, $pid);
		chmod($this->pid_file,0777);
	}

	public function __destruct()
	{
		if($this->is_ok && file_exists($this->pid_file))	unlink($this->pid_file);
	}
}

$single_instance_process = new SingleInstanceProcess;

if (!$single_instance_process->is_ok) exit(0);


Le script php en question se nomme single_instance.php

Il vous suffit juste de faire un include dans votre script, qui ne s’exécutera alors que si une autre instance ne s’exécute pas déjà !

#!/usr/bin/php
< ?php
// ici mon script toto.php

include "/chemin/single_instance.php";

//  mon code ici

? >

 

yakpro rulez!

Ce Site a été mis à jour le Mercredi 19 Janvier 2022 à 09:43:57