PHP|Débutant :: Forums

Advertisement

Besoin d'aide ? N'hésitez pas, mais respectez les règles

Vous n'êtes pas identifié(e).

#1 20-03-2017 16:59:55

Maljuna Kris
Infantimigulo
Lieu : Douarnenez 29100 Breizh Izel
Inscription : 08-05-2009
Messages : 2 453
Site Web

[RÉSOLU] SQLite et un peu de PDO

Saluton de la part d'un revenant.

Sur mon site de chansons j'essaye de faire apparaître le hit-parade des 30 chansons les plus visitées.
Jusqu'ici j'ai bricolé un truc qui utilise un array sérialisé et sauvegardé sous forme d'un fichier texte sur le serveur.
Ça fonctionne relativement bien sauf que, de temps à autres, un accès concurrentiel au fichier texte réinitialise ce dernier à vide et tout repart à zéro.
J'ai donc décidé de me faire violence et de gérer ça avec une petite base de donnée SQLite (comme au bon vieux temps).
Voici le script de test :

<?php
$choix=0;                
if(isset($_GET['chant'])){$choix=intval($_GET['chant']);}

/// DB connection string and username/password
$connStr = 'sqlite:pdo.db';
$user = 'root';
$pass = '';

// Create the connection object
try
    {
    $conn = new PDO($connStr, $user, $pass);
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    }
catch(PDOException $e)
    {
    showHeader('Erreur');
    showError("Désolé, une erreur s'est produite.\n" . $e->getMessage());
    }
   
// Création de la table hits si elle n'existe pas
$conn->query("CREATE TABLE IF NOT EXISTS hits (id INTEGER PRIMARY KEY, song INTEGER UNIQUE, score INTEGER)");
// Y-a-t'il une chanson sélectionnée ?
if(isset($choix) && $choix>0){
                        // Lire l'enregistrement correspondant à la chanson sélectionnée
                        $q=$conn->query("SELECT COUNT(*) AS trouve FROM hits WHERE song = $choix");
                        $count = $q->fetch();
                        $q->closeCursor();
                        ?><pre><?php var_dump($count); ?></pre><?php
                        if($count['trouve']>0){// l'enregistrement existe mettre la table à jour
                                      $conn->query("UPDATE hits SET score = score + 1 WHERE song = $choix");
                                      echo 'UPDATE<br />';
                                      }
                                  else{
                                      $conn->query("INSERT INTO hits(song, score) VALUES($choix,1)");
                                      echo 'INSERT<br />';
                                      }
                            }
// récupérer les 10 meilleurs scores
$q=$conn->query("SELECT song, score FROM hits ORDER BY score DESC, song LIMIT 30");
$q->setFetchMode(PDO::FETCH_ASSOC);
while($r = $q->fetch());{
                        $favoris[$r['song']]['vus']=$r['score'];
                        echo 'dans While<br />';
                        }
$q->closeCursor();
?>
<pre><?php var_dump($favoris);?></pre>

et les résultats de son appel, le premier sans passage de valeur et les deux suivants avec passage de ?chant=300

1er appel

dans While

array(1) {
  [""]=>
  array(1) {
    ["vus"]=>
    NULL
  }
}
++++++++++++++++++++
2ème appel

array(2) {
  ["trouve"]=>
  string(1) "0"
  [0]=>
  string(1) "0"

INSERT
dans While

array(1) {
  [""]=>
  array(1) {
    ["vus"]=>
    NULL
  }
}
+++++++++++++++++++++
3ème appel

array(2) {
  ["trouve"]=>
  string(1) "1"
  [0]=>
  string(1) "1"
}

UPDATE
dans While

array(1) {
  [""]=>
  array(1) {
    ["vus"]=>
    NULL
  }
}

La particularité de SQLite est que lorsqu'on se connecte à une base de données inexistante il crée un fichier vide, ici pdo.db.

Je trouve déjà bizarres les affichages des var_dump[$count]

On voit bien qu'au premier appel on accède directement au parcours de la requête SELECT, au deuxième appel on passe par INSERT,  logique la table est vide et au troisième on passe bien par UPDATE, toujours logique puisque on a le même chant 300 sélectionné par $_GET['chant].
Sauf que les résultats des var_dump ne sont pas cohérents puisque la valeur 300 de “song” n'apparaît pas.
J'ai testé ensuite avec ?chant=400 et il passe bien par INSERT, puis UPDATE la fois suivante, mais les var_dump restent les mêmes.
Et, de toutes façons, quand je rapatrie la base pdo.db depuis mon serveur pour la tester avec sqliteman, la table “hits” est bien créée mais reste désespérément vide.
Qu'est-ce qui m'échappe selon vous ?



Gloire à qui n'ayant pas d'idéal sacro-saint,
Se borne à ne pas trop emmerder ses voisins. G. Brassens Don Juan 1976.
Avĉjo MoKo kantas
La chaîne YouTube MoKo Papy

Hors ligne

#2 20-03-2017 19:18:00

Maljuna Kris
Infantimigulo
Lieu : Douarnenez 29100 Breizh Izel
Inscription : 08-05-2009
Messages : 2 453
Site Web

Re : [RÉSOLU] SQLite et un peu de PDO

Bon, je vous fais part de mes découvertes au fil de l'eau.
Finalement j'ai installé le module SQLite de Firefox et lui me permet de voir le contenu de la table hits qui contient bien les chants 300 et 400 avec chacun un score de 2.

Donc je vais maintenant me concentrer sur le parcours de la requête SELECT dont le résultat semble vide ????


Gloire à qui n'ayant pas d'idéal sacro-saint,
Se borne à ne pas trop emmerder ses voisins. G. Brassens Don Juan 1976.
Avĉjo MoKo kantas
La chaîne YouTube MoKo Papy

Hors ligne

#3 20-03-2017 19:39:09

Maljuna Kris
Infantimigulo
Lieu : Douarnenez 29100 Breizh Izel
Inscription : 08-05-2009
Messages : 2 453
Site Web

Re : [RÉSOLU] SQLite et un peu de PDO

Bien j'ai trouvé la source de mon problème.

Comme souvent erreur d'étourderie (ou fatigue, notamment due au grand âge)

while($r = $q->fetch());{

Ce point-virgule intempestif avant l'accolade empêchait à la boucle de s'éxécuter.
C'est piégeur parce que ça ne déclenche pas d'exception de parsing PHP et le code entre les {} s'exécute une fois et affichait donc “while”


Gloire à qui n'ayant pas d'idéal sacro-saint,
Se borne à ne pas trop emmerder ses voisins. G. Brassens Don Juan 1976.
Avĉjo MoKo kantas
La chaîne YouTube MoKo Papy

Hors ligne

Pied de page des forums