Bon, après une batterie de tests et de googling, je suis à deux doigts de déclarer forfait.
J’ai développé une classe Image permettant de gérer toutes les images d’un site. Les images sont stockées ou non sur le serveur, avec éventuellement une miniature et/ou un preview (entre la taille réelle et le thumb minuscule), et à chaque image correspond une entrée dans une table dédiée de la base de données. On peut donc avoir une entrée dans la base d’une image sur un site extérieur, avec tout de même un aperçu sur le serveur.
Les images possèdes entre autre pour attributs:
$mId: id de la bdd
$mUrl: url de l’image
$mPreviewUrl: url de la preview
Tout allait pour le mieux dans le meilleur des mondes jusqu’à ce que je mette le doigt sur une bizarrerie. Avant tout, voici un exemple d’application:
$img = new Image;
$img->NewImage(TBL_IMAGES, ‘Un titre’, ‘Un auteur’, ‘image/jpg’, ‘Auteur original’, ‘http://www.google.com/intl/fr_ALL/images/logo.gif’, ‘/url de la miniature si elle existe déjà/’, ‘/idem mais pour la preview/’, ‘Un commentaire’);
$img->Save(); // On enregistre tout dans la base de données
echo $img->View(); // Ceci sort juste un code HTML
echo $img->Preview(‘index.php’,1); // Ceci sort aussi un code HTML, avec un lien autour
echo $img->mId; // Ceci rend l’identifiant, qui correspond au champ id, en auto_increment, de la base contenant les références des images
Tout le problème semble venir de la méthode Preview. Si l’option est à 0, on décide que c’est l’image de base qui servira de preview si on ne trouve pas l’image réduite. Un autre code indique qu’on souhaite qu’une miniature soit créée, et le code de 1 à 3 est une indication sur le redimensionnement (taille maxi, hauteur maxi, ou largeur maxi).
Et voilà à quoi ressemble cette méthode:
/*
- $dest: link direction
- $option:
- 0 -> image used if no preview
- 1-3 : build preview and put it in cache
- 1 -> w and h < max
- 2 -> w < MaxW
- 3 -> h < MawH
*/
function Preview($dest, $option, $imgClass = ‘’, $linkClass = ‘’)
{
$url = $this->mPreviewUrl; // TOUT SE JOUE ICI!!!
if ($option == 0) {
if (0 == file_exists($this->mPreviewUrl)) {
$url = $this->mUrl; // On a pas de preview et on a choisit de voir l’image de base dans ce cas
}
} elseif ($option != 0 && $this->mExternal == 0)
$url = $this->BuildPreview(1, $option); // Appelé pour construire la miniature, sous réserve que l’image soit sur le serveur, ce qui se traduit par la variable mExternal à 0
$preview = $this->LinkHtmlCode($dest, $this->mTitle, $linkClass); // Ne fait que rendre des caractères (code Html)
$preview .= $this->ImgHtmlCode($url, $this->mTitle, $imgClass); // Ne fait que rendre des caractères (code Html)
$preview .= ‘’;
return $preview;
}
Dernière info, j’utilise une classe de connexion pour MySQL.
Maintenant la magie : l’exécution du code avec l’option à 0 ne pose pas de problème. Par contre, si l’option vaut 1 ou plus, alors je me retrouve avec deux entrées dans la base mais
- elles sont strictement identiques
- seul Save effectue une entrée dans la base de donnée, et cette méthode est bien exécutée une seule fois (j’ai fait un echo “pouet” pour tester ça)
- une seule requête dans la BDD est effectuée (vérifié en modifiant ma classe SQL rien que pour le test)
- la valeur de mId correspond à la 1ère des deux entrées (c’est le echo $img->mId que vous pouvez voir)
- si $this->mPreviewUrl est changé en $this->mUrl dans la méthode, le bug disparait (j’ai juste pas la bonne url…)
Bon, je pense que ça cadre assez bien le problème. La solution que j’ai trouvé est de remplacer les valeurs d’option par des chaines de caractères (p1,p2,p3 au lieu de 1,2,3).
Une idée? :P)
Ce message a été édité par Jub le 26/05/2004