Page 1 sur 1

équivalent de l'instruction finally [JAVA] en PHP5

Posté : 19 nov. 2008, 12:13
par kaljerhom
Bonjour,

Une question de develloppeur Java sur PHP. :lol:

Quand je créer une méthode pour effectuer des requêtes sur ma BDD avec PDO, je mets mon code (de la connection à la requête ) dans un bloc try/catch.
Et du coup je voudrais mettre la fermeture de ma connection dans un bloc finally pour etre sur qu'elle se ferme meme s'il y a un problème dans mon code.
Mais je crois que cette instruction n'existe pas en PHP5, et je me demandais s'il n'y avait pas un équivalent.

Merci d'avance pour vos réponses.

Posté : 19 nov. 2008, 19:27
par stopher
Salut ,

Tu peux peut être simplement , fermer ta connexion dans ton destructeur , et dans ton catch ...

Ainsi , tu seras certain de ta déconnexion à la base ...

Mais , il me semble , que php ferme automatiquement la connexion à la base , à la fin du script .. ( sauf paramétre contraire ) je me trompe ?

cdt,
Christophe.

Posté : 20 nov. 2008, 15:27
par Hywan
Hey :),

En effet, l'instruction finally n'existe pas dans PHP (pour l'instant, qui sait ce que PHP nous réserve ;-)).

En revanche, comme le dit stopher, la méthode __destruct (destructeur) est appelée (si elle existe) avant de supprimer l'objet. Pour rappel, la méthode __construct (constructeur) est appelée après l'instanciation. Le constructeur en PHP 4 porte le nom de la classe, comme en Java. Avec les versions PHP 5+, c'est la méthode magique __construct. La notion de destructeur n'existe pas en Java il me semble :-k, à confirmer. En PHP 4 encore une fois, les destructeurs n'existent pas. Mais tu peux tricher avec les registres de fonctions de clôtures.

Si tu utilises PDO pour te connecter à ta base, PDO ferme sa connexion tout seul avant d'être détruit. Pour les fonctions propres à chaque SGBDR, il doit en être de même, mais à confirmer (car c'est différent selon les pilotes utilisés).

Il est toujours préférable de le faire manuellement si tu n'es pas sûr. Donc placer cette instruction dans le destructeur est une bonne idée.

Mais j'ai un doute … le bloc finally attrape toutes les exceptions qui n'ont pas été attrapé par un bloc catch qui le précédait. Donc utiliser finally n'est pas très utile, car tu dis : « Et du coup je voudrais mettre la fermeture de ma connection dans un bloc finally pour etre sur qu'elle se ferme meme s'il y a un problème dans mon code ». Dans ce cas, pas besoin d'un couple try/catch (ou triplet try/catch/finally) ?

Posté : 20 nov. 2008, 16:28
par kaljerhom
Je ne suis pas sur de ce que je vais dire, mais il me semble qu'un bloc finally s'éxécute quoi qu'il se soit passé dans un script avant.
En Java c'est comme cela qu'on me l'a présenté en tout cas.
parce que justement si tu met la fermeture de ta connection juste comme ca comme tu es derrière un bloc try catch, si une erreur survient on passe dans le catch et la suite du code n'est pas éxécutée, et du coup ta connection ne se ferme pas.
Mais je retiens l'idée de mettre cela dans le destructeur.
Merci :D

Heu en fait je crois que je me suis mal fait comprendre.
Par exemple :
class UserDAO implements IUserDAO
{
	public function readUser($login, $password)
	{
		try
		{
			$pdo = ConnexionPDO::getInstance();
			$sql = "SELECT * FROM user WHERE pseudo= ? AND password= ?";
			$st = $pdo->getDBH()->prepare($sql);
			$st->execute(array($login,$password));	//return FALSE ou return un objet PDOStatement =>$st [en fait execute le prepare()]
			
			//$userDTO = $st->fetchAll(PDO::FETCH_CLASS, 'UserDTO');
			//$userDTO = $st->fetchObject("UserDTO", $st->fecthAll()); //array $ctor_args)
			while($resultat = $st->fetch())
			{
				$userDTO = new UserDTO();	//j'instancie un objet de classe UserDTO
				//j'initialise mon objet avec les résultats de ma requête SQL qui me retourne 1 user
				$userDTO->init($resultat['idUser'],$resultat['pseudo'],$resultat['password'],$resultat['statut']);
				//$idUser = ;
				//$login = ;
			}
		}
		catch (Exception $e) { echo 'Exception reçue : ',  $e->getMessage(), "\n"; } //être plus précis dans le typage des Exception	
		
		CloseConnBD::closeConnection($pdo->getDBH());

		return $userDTO;
	}
}

?>
C'est l'instruction CloseConnBD::closeConnection($pdo->getDBH())); qui ferme ma connexion à la BDD.
Et c'est cette ligne dont je voudrais etre sur qu'elle s'éxécute.

Imaginer que je me connecte, mais qu'il y ait un problème au moment du prepare(), du execute() ou du fecth(), bien mon instruction close() ne sera pas lu non?

Posté : 20 nov. 2008, 16:41
par Hywan
Ah … bah dans ce cas :
try {

    // On tente.
    $pdo = ConnexionPDO::getInstance();
    // …
}
catch ( PDOException $e ) {

    // On ferme la connexion.
    CloseConnBD::closeConnection($pdo->getDBH());

    // On fait ce qu'on veut de l'exception par la suite.
    throw $e;
}
C'est à vérifier, mais il me semble que le bloc finally fonctionne comme ça : si aucun bloc n'a pu capturer l'exception, il ira dans la dernière. C'est équivalent à avoir un bloc qui capture l'exception mère (Exception dans PHP, et pareil en Java je crois). Donc :
try {

    // On lance une exception.
    throw new MyException('Gotcha', 0);
}
catch ( AnException $e ) {

    // In n'ira pas ici, …
}
catch ( AnOtherException $e ) {

    // … ni ici.
}
catch ( Exception $e ) {

    // On ira forcément ici si tous les autres échoues.
}