Tester une fonction ou une requête avant de l'executer

Eléphant du PHP | 190 Messages

13 oct. 2011, 16:36

Je me pose une question sur la gestion des erreurs.

Par exemple: Un simple formulaire d'envoi d'image qui contient un champ texte, et un champ FILE qui contient donc l'image.

Sur la page de traitement, le champs texte est envoyer dans la BDD, et l'image dans un dossier. Imaginons que la requête réussi, mais que l'upload échoue, on se retrouve avec une entrée dans la BDD qui ne sert a rien puisque l'image n'est pas dans le dossier.

Y'a t'il un moyen concret dans ce cas ci de tester les 2 avant de les exécuter, et si une erreur se produit sur l'un ou l'autre, ne rien faire tout simplement.
if(!empty($_POST['name']) && !empty($_FILES['image']['name'])){
		if(substr($_FILES['image']['name'],-4) == ".jpg"){
			$query=mysql_query("INSERT INTO images VALUES('','".mysql_real_escape_string(htmlspecialchars($_POST['name']))."')");
			if($query){
				move_uploaded_file($_FILES['image']['tmp_name'], "../images/".mysql_insert_id().".jpg");
				$message="Image successfully added";
			}else{
				$message="Database Error: ".mysql_error();
			}
		}else{
			$message="Image not .jpg file";
		}

ViPHP
xTG
ViPHP | 7331 Messages

13 oct. 2011, 16:50

Pour la requête tu peux travailler avec les transactions.
Si l'upload réussi tu valides la transaction, sinon tu l'annules.
http://fr2.php.net/manual/fr/pdo.transactions.php

Sinon le cas moins propre, si l'upload échoue tu lances une requête DELETE. ;)

Eléphant du PHP | 190 Messages

13 oct. 2011, 16:58

Le delete après l'upload, c'est à ca que je pensais, c'est d'ailleur pour l'éviter que j'ai posté.

Mais si ma seule alternative est pdo ... Je préfère le delete alors :oops:

pdo... J'ai voulu m'y mettre un jour mais la poo n'est pas du tout faite pour moi :oops:

ViPHP
xTG
ViPHP | 7331 Messages

13 oct. 2011, 17:34

Tu n'es pas obligé d'utiliser PDO, ce n'est qu'une interface...
Le driver MySQL supporte les transactions, ce n'est qu'une utilisation via les fonctions quand on utilise PDO. Il ne fait aucunement une émulation logicielle.
Mais il est possible de les utiliser via requête directement : http://dev.mysql.com/doc/refman/5.0/fr/commit.html

Eléphant du PHP | 190 Messages

13 oct. 2011, 19:25

Ok, grâce à tes informations j'ai trouvé un petit tutoriel qui explique ça, mais en anglais.

http://www.devarticles.com/c/a/MySQL/Us ... 0-and-PHP/

Je me débrouille en anglais mais si tu pouvais m'éclaircir quelques points ça serai sympa.

Dois-je refaire un BEGIN pour chaque requête ? ou puis-je toutes les faire entre mon BEGIN et mon COMMIT (ou ROLLBACK) ?

J'ai cru comprendre sur le lien que tu m'as donné qu'il fallait configurer mysql (SET AUTOCOMMIT=0), mais le tuto que j'ai renseigné ci dessus n'en parle pas, j'ai loupé un truc ?

Je te remercie.

ViPHP
xTG
ViPHP | 7331 Messages

13 oct. 2011, 19:55

En effet le paramètre autocommit doit être mis à 0 sinon le commit est réalisé après chaque requête.

Le commit démarre une transaction, c'est en quelque sorte une nouvelle BDD temporaire.
Tu peux effectuer toutes les opérations que tu souhaites dessus cela n'affecte en rien la BDD réelle.
Et lors du commit les différences sont réglées pour transférer les modifications vers la BDD réelle.

N'ayant jamais utilisé ce système je ne saurai cependant pas te répondre quand à : "Que se passe-t-il si je n'utilise ni commit ni rollback à la fin de mon script ?"

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

15 oct. 2011, 20:29

wé enfin si tu fait l'upload puis l'insertion en base en fonction du résultat de l'upload c'est plus simple et plus cohérent :)


@+
Il en faut peu pour être heureux ......

Eléphant du PHP | 190 Messages

15 oct. 2011, 21:52

wé enfin si tu fait l'upload puis l'insertion en base en fonction du résultat de l'upload c'est plus simple et plus cohérent :)


@+
Je m'en étais rendu compte :) Merci.

Pour info: Finalement je n'utilise pas les transactions. Pas que je ne les aie pas comprises, mais comme tu le suggère, je fais l'upload puis la requête. Si la requête échoue je n'ai qu'a supprimer l'image.

Mais merci à xTG qui m'a fait découvrir les transactions qui me seront peut-être utiles si d'aventures je me lançais dans un plus gros projet.