2017-09-20 10 views
2

Je ne peux vraiment pas comprendre ce que je fais mal ici. Je fais une requête pour vérifier s'il y a des enregistrements dans une table DB appelée 'newCards'.PHP PDO alors que la boucle ne retourne rien

Avec $count Je vérifie combien de résultats il retourne: il me montre '1'. Mais la boucle while ne retourne rien. Les seules choses que je vois sont les <th> en haut de la table, mais aucun enregistrement de table n'est présent, alors que $count donne '1' comme résultat. Ce qui est vrai, car il y a actuellement 1 enregistrement présent dans DB.

Comment puis-je résoudre ce problème?

<?php 
    $query = $db->prepare("SELECT * FROM `newCards` WHERE `company` = :companyID"); 
    $query->bindParam(":companyID", $enterprise['id'], PDO::PARAM_INT); 
    $query->execute(); 
    $count = $query->rowCount(); 
    echo $count; 

    if(empty($query->fetch())){ 
     echo "Geen gevonden"; 
    } else { 
?> 
        <table> 
         <tr> 
          <th>Ontvanger</th> 
          <th>Saldo</th> 
          <th></th> 
         </tr> 
<?php 
     while($result = $query->fetch()){ 
?> 
         <tr> 
          <td><?php echo $result['id']; ?></td> 
          <td>2</td> 
          <td>3</td> 
         </tr> 
<?php 
     } 
?> 
        </table> 
<?php 
    } 
?> 
+0

Notez que 'fetch()' retourne FALSE non seulement quand il n'y a pas de documents trouvés, mais aussi lorsque l'interrogation de la DB échoue, des raisons différentes .Et vous ne pouvez pas faire la différence entre les deux situations. Ceci est un bug dans PDO. Donc, je vous recommande d'utiliser 'fetchAll()' à la place. Il retourne un tableau vide quand aucun enregistrement n'est trouvé, ou FALSE en cas d'échec. Les deux situations peuvent être traitées de manière correspondante. De même, ne mélangez pas les fonctions d'accès aux données au format HTML. Récupère toutes les données dans les tableaux, dans le code php supérieur. Travaillez avec ces tableaux lorsque vous construisez vos parties HTML. –

+0

@aendeerei son retour null sur un resultset vide (si je me souviens bien), pas faux. Et ce n'est pas vraiment un bug, je ne le crois pas. C'est ainsi que vous pouvez le boucler, et donc la boucle se brise quand il n'y a plus de résultats à récupérer. Il n'adhère pas à la norme SQLSTATE SQL-92, mais cela fonctionne – Qirel

+0

@Qirel Merci de m'avoir ponté. J'ai revérifié mon docus: il renvoie définitivement un booléen FAUX. J'ai fait - je dirais beaucoup de - recherches et tests il y a un mois. Et j'ai noté les résultats. La première phrase en eux est mon commentaire précédent. La deuxième phrase est: "_Maybe en cas d'échec, une exception sera levée_" :-) Cela signifie que je n'ai pas pu tester cela à ce moment-là. Et je me réfère à cela comme étant un bogue, parce que dans ce contexte ce n'est pas le comportement naturel, souhaitable, comme dans le cas de fetchAll(). –

Répondre

1

$query->fetch() déjà récupère un record. Donc, appel suivant à fetch() récupère suivant enregistrement ou rien s'il n'y a pas de dossiers. Dans votre cas avec un enregistrement deuxième fetch() ne récupère rien, donc while ne démarre jamais.

Vous pouvez modifier votre code:

if($count){?> 
<table> 
    <tr> 
     <th>Ontvanger</th> 
     <th>Saldo</th> 
     <th></th> 
    </tr> 
<?php 
    while($result = $query->fetch()){ 
     // show row 
    }?> 
</table> 
} else { 
    // echo that no rows found 
} 
0

Je pense d'extraction en premier si est exécuté c'est pourquoi la deuxième retour à vide, essayer de l'affecter à var avant que les conditions ou vérifier l'esprit $ suite var

0

Parce que fetch() récupère la première ligne, même lors de la vérification empty(), il va essayer d'aller chercher la ligne suivante lorsque vous utilisez while($result = $query->fetch()){. Vous pouvez vérifier la valeur de $count (comme le montre u_mulder), mais vous devriez vous méfier de la note dans le manuel pour rowCount() (Souligné par)

Si la dernière instruction SQL exécutée par le PDOStatement associé était un SELECT instruction, certaines bases de données peuvent renvoyer le nombre de lignes renvoyées par cette instruction. Toutefois, ce comportement n'est pas garanti pour toutes les bases de données et ne doit pas être utilisé pour les applications portables.

Vous pouvez utiliser une structure do..while et vérifier si la récupération a été réussi ou non à la place. Si vous changez if(empty($query->fetch())){ avec if (!$row = $query->fetch()) {, vous vérifiez si une ligne a été récupérée ou non (car fetch() renvoie null sur un résultat vide). Alors $row est prêt à l'emploi, et vous pouvez l'utiliser avant que la première boucle ait lieu.

<?php 
$query = $db->prepare("SELECT * FROM `newCards` WHERE `company` = :companyID"); 
$query->bindParam(":companyID", $enterprise['id'], PDO::PARAM_INT); 
$query->execute(); 
$count = $query->rowCount(); 
echo $count; 

if (!$row = $query->fetch()) { 
    echo "Geen gevonden"; 
} else { 
    ?> 
    <table> 
     <tr> 
      <th>Ontvanger</th> 
      <th>Saldo</th> 
      <th></th> 
     </tr> 
    <?php 
    do { 
     ?> 
     <tr> 
      <td><?php echo $result['id']; ?></td> 
      <td>2</td> 
      <td>3</td> 
     </tr> 
     <?php 
    } while ($result = $query->fetch()); 
    ?> 
    </table> 
    <?php 
}