PDO + beginTransaction pas content

PDO + beginTransaction pas content - PHP - Programmation

Marsh Posté le 15-10-2015 à 12:26:58    

Alors pour commencer : ma question concerne à la fois PDO et du SQL, donc je ne suis peut être pas dans la bonne sous catégorie, mais je pense que ça correspond plus à PHP qu'à SQL/NoSQL. Désolé si je me trompe, n'hésitez pas à déplacer :)

 

Ensuite, ce que j'utilise : MySQL, PDO, et ma table utilise InnoDB.

 

J'ai essayé d'obtenir des réponses sur stackoverflow, mais les personnes qui ont essayé de m'aider ont calé.

 

Tout d'abord, mon code :

Code :
  1. //connexion BDD
  2. try
  3. {
  4.     $bdd = new PDO('mysql:host=HOSTNAME;dbname=DATABASENAME', 'USERNAME', 'PASSWORD');
  5. }
  6. catch(Exception $e)
  7. {
  8.     die('Error : '.$e->getMessage());
  9. }   
  10. //construction de la requête d'update
  11. // NB : je suis actuellement en train de modifier ce bloc de code pour utiliser des placeholders dans la requête, inutile de m'interpeller sur le sujet (sauf si c'est ça qui pose mon problème, mais je pense pas)
  12. $count = count($articles)-1;
  13. $qry = 'UPDATE table SET field = CASE';
  14. foreach($elements as $el){
  15.     $qry .= ' WHEN id = '. $el['id'] .' THEN '. $el['value'];
  16. }
  17. $qry .= ' ELSE field END,
  18. update_date = CASE WHEN id IN (';
  19. foreach ($count) {
  20.     $qry .= '?, ';
  21. }
  22. $qry .= '?) THEN NOW() ELSE update_date END';
  23. //préparation de la requête
  24. $update = $bdd->prepare($qry);
  25. //transaction et tentative d'update
  26. $bdd->beginTransaction();
  27. try {
  28.     $update->execute(); 
  29.     $bdd->commit();
  30. }
  31. catch(Exception $e) {
  32.     $bdd->rollback();
  33.     echo 'Error : '.$e->getMessage().'<br />';
  34.     echo 'N° : '.$e->getCode();
  35.     exit();
  36. }
 

Autrement dit, ça donne ça :
- Je me connecte à la BDD
- Je construis une requête qui ressemble à ça :

Code :
  1. UPDATE table SET field = CASE
  2.     WHEN id = 1 THEN 'foo'
  3.     WHEN id = 2 THEN 'bar'
  4.     WHEN id = 3 THEN 'foobar'
  5.     ELSE field
  6. END,
  7. update_date = CASE
  8.     WHEN id = (1, 2, 3) THEN NOW()
  9.     ELSE update_date
  10. END;


- Je peux régler le nombre de lignes que j'essaie d'updater en modifiant mon array $elements
- Je prepare() la requête
- J'ouvre une transaction
- J'essaie de faire l'update et de commit, et si ça marche pas je rollback et j'affiche un message d'erreur.

 

Seulement voilà, après avoir testé, il se trouve que :
- Cas A) si le nombre d'éléments dans $elements est de 72 ou moins, ça marche très bien, l'update se fait, ça commit, pas de souci.
- Cas B) en revanche si le nombre d'éléments est de 73 ou plus, l'update ne se produit pas, et j'ai le message d'erreur suivant :

Code :
  1. Fatal error: Uncaught exception 'PDOException' with message 'There is no active transaction' in script.php:106
  2. Stack trace:
  3. #0 script.php(106): PDO->rollBack() #1 {main} thrown in script.php on line 106


La ligne 106 étant $bdd->rollback();

 

Dans ce cas là (le cas B, avec 73+ éléments), j'ai tenté plusieurs choses :
a) J'ai fait des tests pour voir si c'est la longueur de la requête (en nombre de caractères) qui posait problème, je vous passe les détails mais je suis à peu près certain que ça n'est pas ça qui pose problème.
b) vardump($bdd->beginTransaction(); ) me donne bool(false) dans le cas B (ça me donne bool(true) dans le cas A)
c) J'ai copié/collé la requête construite dans le cas B directement dans phpMyAdmin, ça update sans problème
d) Et de même dans mon script, si je me débarrasse des lignes qui concernant la transaction : beginTransaction(), commit() et rollback(), je n'ai plus d'erreur et l'update se produit sans problème. Donc je ne pense pas que ce soit le contenu de ma requête qui soit la source du problème.

 

Voila. Si vous avez une idée de choses à tenter et/ou de ce qui ne tourne pas rond, je vous en serais fort reconnaissant. Merci !


Message édité par saint malo le 16-10-2015 à 12:50:30
Reply

Marsh Posté le 15-10-2015 à 12:26:58   

Reply

Marsh Posté le 16-10-2015 à 11:09:57    

Tu as essayé de forcer l'autocommit à false explicitement (Ne serait-ce que par sécurité) ?

 
Citation :


Important

 

Many APIs used for writing MySQL client applications (such as JDBC) provide their own methods for starting transactions that can (and sometimes should) be used instead of sending a START TRANSACTION statement from the client. See Chapter 20, Connectors and APIs, or the documentation for your API, for more information.

 

To disable autocommit mode explicitly, use the following statement:

 

SET autocommit=0;


https://dev.mysql.com/doc/refman/5.0/en/commit.html


Message édité par kao98 le 16-10-2015 à 11:10:29

---------------
Kao ..98 - Uplay (R6S) : kao98.7.62x39 - Origin (BF4, BF1) : kntkao98
Reply

Marsh Posté le 16-10-2015 à 12:46:59    

Je suis pas certain de comprendre ce que tu me conseilles de faire, disabler l'autocommit c'est ça ? Et je ferais ça dans phpMyAdmin ? Ou dans mes scripts via PDO ?


Message édité par saint malo le 16-10-2015 à 12:51:09
Reply

Marsh Posté le 16-10-2015 à 14:02:23    

Faire

Code :
  1. $bdd->exec('SET AUTOCOMMIT=0');


juste avant le beginTransaction

 

(nb: ne pas oublier de le remettre à 1 après la transaction bien sûr :o)


Message édité par kao98 le 16-10-2015 à 14:02:32

---------------
Kao ..98 - Uplay (R6S) : kao98.7.62x39 - Origin (BF4, BF1) : kntkao98
Reply

Marsh Posté le 16-10-2015 à 15:04:50    

Ok, merci. J'ai essayé... Rien n'a changé, même message d'erreur :/

Reply

Marsh Posté le 16-10-2015 à 15:16:57    

Et plutôt que de faire une requête UPDATE CASE WHEN, tu as essayé de faire autant de requête UPDATE  (toujours au sein d'une même transaction bien sûr) ?


---------------
Kao ..98 - Uplay (R6S) : kao98.7.62x39 - Origin (BF4, BF1) : kntkao98
Reply

Marsh Posté le 16-10-2015 à 15:20:55    

genre comme ça (nb: j'ai rien testé, écris de tête :o) :

Code :
  1. //connexion BDD
  2.    try
  3.    {
  4.        $bdd = new PDO('mysql:host=HOSTNAME;dbname=DATABASENAME', 'USERNAME', 'PASSWORD');
  5.    }
  6.    catch(Exception $e)
  7.    {
  8.        die('Error : '.$e->getMessage());
  9.    }  
  10.  
  11.    //construction de la requête d'update
  12.    // NB : je suis actuellement en train de modifier ce bloc de code pour utiliser des placeholders dans la requête, inutile de m'interpeller sur le sujet (sauf si c'est ça qui pose mon problème, mais je pense pas)
  13.    $count = count($articles)-1;
  14.  
  15.    $bdd->beginTransaction();
  16.  
  17.    foreach($elements as $el){
  18.        $qry = ' UPDATE table SET field = ' . $el['value'] . ', update_date = NOW() WHERE id = ' . $el['id'];
  19.  
  20.      //préparation de la requête
  21.      $update = $bdd->prepare($qry);
  22.      try {
  23.          $update->execute();
  24.      }
  25.      catch(Exception $e) {
  26.          $bdd->rollback();
  27.          echo 'Error : '.$e->getMessage().'<br />';
  28.          echo 'N° : '.$e->getCode();
  29.          exit();
  30.      }
  31.  
  32.    }
  33.    $bdd->commit();


---------------
Kao ..98 - Uplay (R6S) : kao98.7.62x39 - Origin (BF4, BF1) : kntkao98
Reply

Marsh Posté le 16-10-2015 à 15:45:44    

J'ai modifié un poil le code (en gros j'ai mis des placeholders) :
 

Code :
  1. $bdd->beginTransaction();
  2. $qry = ' UPDATE table SET field = ?, update_date = NOW() WHERE id = ?';
  3. $update = $bdd->prepare($qry);
  4. foreach($elements as $el){
  5.       try {
  6.           $update->execute(array($el['value'],$el['id']));
  7.       }
  8.       catch(Exception $e) {
  9.           $bdd->rollback();
  10.           echo 'Error : '.$e->getMessage().'<br />';
  11.           echo 'N° : '.$e->getCode();
  12.           exit();
  13.       }
  14.     }
  15.     $bdd->commit();


 
Et même résultat, même message d'erreur :(
 
(NB : j'ai essayé avec et sans entourer le code de $bdd->exec('SET AUTOCOMMIT=0'); et $bdd->exec('SET AUTOCOMMIT=1'); , pas de changement notable)

Reply

Marsh Posté le 16-10-2015 à 16:01:06    

Tu as une exception sur l'appel à la méthode "rollback". Ca veut dire que tu as déjà eu une erreur dans le scope du "try". Quelle est-elle ? Tu n'affiches ses infos qu'après le rollback, donc tu ne les affiches jamais parce que le rollback pète :/
 
Déplace le rollback (juste avant le "exit" ), et met un breakpoint dans le block catch pour voir l'erreur qui survient avant. Cela nous donnera peut-être des indices !


---------------
Kao ..98 - Uplay (R6S) : kao98.7.62x39 - Origin (BF4, BF1) : kntkao98
Reply

Marsh Posté le 17-10-2015 à 18:34:35    

Alors du coup en fait j'ai dû manquer d'attention quand je faisais mes tests, parce que mon problème existe toujours, même sans la transaction : quand je suis sous les 72 éléments, ça update, et au dessus, non...

 

Connais pas les breakpoints, comment ça fonctionne ? Comme ça ? :

 
Code :
  1. try {
  2.     $test = $update->execute($contenuQry);
  3.     if($test==1){
  4.         echo 'execute ok<br />';
  5.     }
  6.     echo 'bloc try ok';
  7.     apd_breakpoint();
  8. }
  9. catch(Exception $e) {
  10.     echo 'Il y a eu une erreur lors de l\'execution de la requête de modification.<br />';
  11.     echo 'Erreur : '.$e->getMessage().'<br />';
  12.     echo 'N° : '.$e->getCode();
  13.     exit();
  14. }
 


(Ca a pas l'air) :

Code :
  1. Fatal error: Call to undefined function apd_breakpoint() in script.php on line 127


Message édité par saint malo le 17-10-2015 à 21:03:19
Reply

Marsh Posté le 17-10-2015 à 18:34:35   

Reply

Marsh Posté le 17-10-2015 à 19:10:44    

Oublie le breakpoint.
L'erreur sans transaction, elle dit quoi ?
Normalement, avec une requête par modification (comme j'ai montré plus haut), ça devrait fonctionner :/


---------------
Kao ..98 - Uplay (R6S) : kao98.7.62x39 - Origin (BF4, BF1) : kntkao98
Reply

Marsh Posté le 17-10-2015 à 21:07:49    

kao98 a écrit :

Oublie le breakpoint.
L'erreur sans transaction, elle dit quoi ?


Ah oui désolé : ça me donne aucune erreur, ça se contente simplement ne pas updater. D'où l'ajout du bloc

Code :
  1. if($test==1){
  2.        echo 'execute ok<br />';
  3.    }


qui est mon seul moyen de voir si l'update a effectivement été effectuée (l'echo 'bloc try ok' apparaît à chaque fois, que l'update ait effectivement lieu ou non). Quand j'ai plus de 73 éléments, la ligne n'apparaît plus.

 
Citation :


Normalement, avec une requête par modification (comme j'ai montré plus haut), ça devrait fonctionner :/

 

Tu parles de ça j'imagine.

kao98 a écrit :


Code :
  1. foreach($elements as $el){
  2.        $qry = ' UPDATE table SET field = ' . $el['value'] . ', update_date = NOW() WHERE id = ' . $el['id'];
  3.      $update = $bdd->prepare($qry);
  4.      try {
  5.          $update->execute();
  6.      }
  7.      catch(Exception $e) {
  8.          echo 'Error : '.$e->getMessage().'<br />';
  9.          echo 'N° : '.$e->getCode();
  10.          exit();
  11.      }
  12.    }


 

J'essaie demain et je te dis.
Mais c'est pas très efficace d'assaillir ma bdd de requêtes, non ? (On m'a dit que c'était à éviter à tout prix)

Message cité 1 fois
Message édité par saint malo le 17-10-2015 à 21:08:13
Reply

Marsh Posté le 17-10-2015 à 21:40:27    

saint malo a écrit :


Ah oui désolé : ça me donne aucune erreur, ça se contente simplement ne pas updater. D'où l'ajout du bloc  

Code :
  1. if($test==1){
  2.        echo 'execute ok<br />';
  3.    }


qui est mon seul moyen de voir si l'update a effectivement été effectuée (l'echo 'bloc try ok' apparaît à chaque fois, que l'update ait effectivement lieu ou non). Quand j'ai plus de 73 éléments, la ligne n'apparaît plus.


Ajoute quelque chose comme ça :
 

Code :
  1. if($test!==FALSE){
  2.    echo 'execute ok<br />';
  3. } else {
  4.    echo $update->errorCode();
  5.    echo $update->errorInfo();
  6. }


ca va renvoyer l'erreur qui se produit à ce moment là.


---------------
Kao ..98 - Uplay (R6S) : kao98.7.62x39 - Origin (BF4, BF1) : kntkao98
Reply

Marsh Posté le 19-10-2015 à 11:52:30    

Alors.
1) Avec ma grosse requête unique UPDATE CASE WHEN

 
Code :
  1. if($test!==false){
  2.         echo 'execute ok<br />';
  3.     }
  4.     else {
  5.         echo 'error code : <br />';
  6.         var_dump($update->errorCode());
  7.         echo '<br />';
  8.         echo 'error info : <br />';
  9.         var_dump($update->errorInfo());
  10.     }


Me donne :

Code :
  1. error code :
  2. string(5) "HY000"
  3. error info :
  4. array(3) { [0]=> string(5) "HY000" [1]=> int(2006) [2]=> string(26) "MySQL server has gone away" }

 

2) La même chose avec une requête UPDATE différente pour chaque élément me donne la ligne "execute ok" autant de fois que d'éléments à updater... et pourtant la table n'est pas updatée ! Du coup j'ai modifié le code comme ça :

Code :
  1. if($test!==false){
  2.         echo 'execute ok<br />';
  3.         echo 'error code : <br />';
  4.         var_dump($update->errorCode());
  5.         echo '<br />';
  6.         echo 'error info : <br />';
  7.         var_dump($update->errorInfo());
  8.     }


Et là, j'ai ça autant de fois que d'éléments à updater :

Code :
  1. execute ok
  2. error code :
  3. string(5) "HY000"
  4. error info :
  5. array(3) { [0]=> string(5) "HY000" [1]=> int(2006) [2]=> string(26) "MySQL server has gone away" }
 

(De ce que je lis de l'erreur "MySQL server has gone away", ça veut juste dire que j'essaie d'updater trop de choses à la fois et qu'il me reste que mes yeux pour pleurer..., c'est ça ?)


Message édité par saint malo le 19-10-2015 à 11:54:18
Reply

Marsh Posté le 19-10-2015 à 14:09:14    

Ok donc en fait, il s'agit juste d'un timeout de MySql (en fait, je pense que ça vient plutôt du driver php mysql)
Jettes un oeuil là : http://stackoverflow.com/questions [...] 60-seconds


---------------
Kao ..98 - Uplay (R6S) : kao98.7.62x39 - Origin (BF4, BF1) : kntkao98
Reply

Marsh Posté le 19-10-2015 à 15:42:45    

Par hasard, ton appli web ne serait pas hébergée chez OVH :??: Parce que ton pb m'en rappelle un que j'ai eu avec eux pour une appli qui faisait pas mal d'accès à la BD. Du coup, il valait mieux faire un seul accès un peu gros plutôt que de nombreux petits accès à la BD. :/


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 19-10-2015 à 15:47:45    

rufo a écrit :

Par hasard, ton appli web ne serait pas hébergée chez OVH :??: Parce que ton pb m'en rappelle un que j'ai eu avec eux pour une appli qui faisait pas mal d'accès à la BD. Du coup, il valait mieux faire un seul accès un peu gros plutôt que de nombreux petits accès à la BD. :/


C'est ce qu'il faisait initialement, un gros accès.
Je lui ai proposé de faire plein de petits accès, mais le problème est encore là il semblerait.


Message édité par kao98 le 19-10-2015 à 15:48:02

---------------
Kao ..98 - Uplay (R6S) : kao98.7.62x39 - Origin (BF4, BF1) : kntkao98
Reply

Marsh Posté le 19-10-2015 à 17:00:22    

Je sais pas si j'ai fait ce qu'il fallait, mais j'ai ajouté ces deux lignes :

Code :
  1. ini_set('mysql.connect_timeout', 300);
  2. ini_set('default_socket_timeout', 300);

juste après la connexion à la bdd. C'est bien ce qu'il fallait faire ?
Et aucun changement notable :(

 

(Je ne suis pas chez OVH mais chez hostinger :) )

Message cité 1 fois
Message édité par saint malo le 19-10-2015 à 17:00:40
Reply

Marsh Posté le 19-10-2015 à 17:02:39    

saint malo a écrit :

Je sais pas si j'ai fait ce qu'il fallait, mais j'ai ajouté ces deux lignes :  

Code :
  1. ini_set('mysql.connect_timeout', 300);
  2. ini_set('default_socket_timeout', 300);

juste après la connexion à la bdd. C'est bien ce qu'il fallait faire ?
Et aucun changement notable :(
 
(Je ne suis pas chez OVH mais chez hostinger :) )


Il faut les mettre juste avant la connexion. Tout au début du script.
Mais si tu es sur un hébergeur mutualisé, ça ne changera sans doute rien.
Il faut découper le travail et le répartir dans le temps, à travers plusieurs requêtes.


---------------
Kao ..98 - Uplay (R6S) : kao98.7.62x39 - Origin (BF4, BF1) : kntkao98
Reply

Marsh Posté le 19-10-2015 à 17:08:28    

hostinger, c'est du mutualisé, le pb est très probablement le même que chez OVH. Comme indiqué, il va falloir "ruser" en faisant en sorte que ton script limite le nb de requêtes SQL à la BD et son temps de connexion à cette dernière :/


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 19-10-2015 à 17:28:30    

En effet, ça change rien. C'est dingue quand même, 72 lignes updatées ça me parait peu, non ?
 
Du coup, comment je fais ça ? En updatant par paquets de 72 (vu qu'apparemment c'est la limite) et en mettant des sleep() ?  
J'ai un moyen d'avoir des infos sur les limites sur le nombre de requêtes et sur le temps de connexion, histoire d'optimiser et me mettre juste en dessous de ces limites ?

Reply

Marsh Posté le 19-10-2015 à 17:35:46    

Les sleep() ne changeront rien à mon avis car les limites de connexion/requêtes à la BD doivent probablement être associées au nom du script en cours d'exécution.
 
Si t'as moyen, fait le update via le cron par paquets de qq enregistrements :/
 
Moi, sur la page où ça me posait le plus de pb (un gros tableau de type formulaire avec pleins de cases à cocher), j'avais résolu le pb avec de l'ajax. Plutôt que de mettre à jour la BD sur le post du formulaire et donc pleins de cases à cocher à traiter ce qui faisait planter le script à cause de la limitation d'OVH, je mettais la BD à jour à chaque fois qu'une case était cochée/décochée avec une requête ajax. Du coup, plus besoin de poster le gros formulaire :)


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 19-10-2015 à 21:38:26    

saint malo a écrit :

En effet, ça change rien. C'est dingue quand même, 72 lignes updatées ça me parait peu, non ?
 
Du coup, comment je fais ça ? En updatant par paquets de 72 (vu qu'apparemment c'est la limite) et en mettant des sleep() ?  
J'ai un moyen d'avoir des infos sur les limites sur le nombre de requêtes et sur le temps de connexion, histoire d'optimiser et me mettre juste en dessous de ces limites ?


72 updates ça paraît peut effectivement.
Ta table est correctement optimisée (des index existent ? Sur les bons champs ?) ?


---------------
Kao ..98 - Uplay (R6S) : kao98.7.62x39 - Origin (BF4, BF1) : kntkao98
Reply

Marsh Posté le 20-10-2015 à 11:24:35    

Citation :

Si t'as moyen, fait le update via le cron par paquets de qq enregistrements :/


Ben du coup c'est ce que je fais, mais par paquets de 72 maximum...

 
Citation :

Ta table est correctement optimisée (des index existent ? Sur les bons champs ?) ?

 

Honnêtement je saurais pas vraiment dire, SQL et moi ça fait pas deux...

 

J'ai essayé de limiter au maximum le nombre d'index parce que je me sens pas à l'aise avec, donc j'ai qu'un PRIMARY et un UNIQUE : ma table a 34 colonnes, dont :

 

- la colonne id : UNSIGNED MEDIUMINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
- 2 autres colonnes d'id pour faire la jointure avec deux autres tables (genre categorie_id et auteur_id) : UNSIGNED MEDIUMINT NOT NULL,
- 19 colonnes contenant des données numériques : UNSIGNED MEDIUMINT NOT NULL,
- 7 colonnes qui me permettent de savoir quand certaines des données numériques ont été updatées pour la dernière fois DATETIME NOT NULL,
- 1 colonne BOOLEAN NOT NULL,
- 3 colonnes TEXT NOT NULL,
- et une colonne VARCHAR(255) NOT NULL UNIQUE

 

Si vous avez des conseils sur des modifs à apporter, je suis preneur :)

Message cité 1 fois
Message édité par saint malo le 20-10-2015 à 23:05:07
Reply

Marsh Posté le 21-10-2015 à 10:57:24    

En faisant une autre requête simple ça marche ? T'es sûr des paramètres des connexions BDD ?

Reply

Marsh Posté le 21-10-2015 à 17:11:28    

Pablo Escrobarbe a écrit :

En faisant une autre requête simple ça marche ? T'es sûr des paramètres des connexions BDD ?


C'est gentil de vouloir aidé, mais ce serait bien de lire le sujet avant  :whistle:


---------------
Kao ..98 - Uplay (R6S) : kao98.7.62x39 - Origin (BF4, BF1) : kntkao98
Reply

Marsh Posté le 21-10-2015 à 18:49:14    

Hehe oui, j'étais pas sur de comment répondre ^^

 
Pablo Escrobarbe a écrit :

En faisant une autre requête simple ça marche ? T'es sûr des paramètres des connexions BDD ?

 

Mais peut être que tu veux dire une requête autre qu'un update ? Pas dans ce script là, mais j'ai d'autres endroits de mon appli où j'ai des requêtes insert, et elles fonctionnent. Mais bon, j'insert jamais plus de 72 éléments d'un coup, donc je peux pas vraiment te dire si ça ça fonctionne.

 

Par paramètres de connexion BDD, tu entends quoi ? Si tu entends ce qui est là dedans :

Code :
  1. $bdd = new PDO('mysql:host=HOSTNAME;dbname=DATABASENAME', 'USERNAME', 'PASSWORD');


la réponse est que ça se connecte bien et n'a aucun souci à faire les select, insert, etc, et les update de moins de 73 éléments du coup :p donc à priori, ça va
Après si tu parles d'autre chose avec "paramètres de connexion BDD", je sais pas de quoi il est question et je veux bien des précisions.


Message édité par saint malo le 21-10-2015 à 18:50:58
Reply

Marsh Posté le 23-10-2015 à 15:20:49    

saint malo a écrit :

Si vous avez des conseils sur des modifs à apporter, je suis preneur :)


Pas d'idées ? :/
 
En tout cas merci pour l'aide jusqu'ici

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed