1
votes

Vérifiez la requête PDO pour le résultat, puis réutilisez les données

Je suis nouveau dans PDO et je suis en train de mettre à jour une application de mysql_query vers PDO. C'est sûrement une question stupide - mais j'espère que quelqu'un pourra m'aider à comprendre.

J'ai besoin de voir si une requête PDO contient des données: - si ce n'est pas le cas, lancez une erreur - si c'est le cas, récupérez ces données

Je pourrais le faire facilement avec mysql_num_rows, mais c'est obsolète comme nous le savons tous.

Le problème est qu'une fois que j'ai vérifié s'il y a toutes les données, je ne peux plus les récupérer.

La vérification fonctionne correctement, mais lorsque vous essayez de récupérer le résultat réel, il est vide. Je peux bien sûr exécuter à nouveau la requête après la vérification - mais je préfère éviter d'avoir à exécuter une requête deux fois.

try
{
    $result = $pdo2->prepare("SELECT first_name FROM users WHERE email = :email;");
    $result->bindValue(':email', $email);
    $result->execute();
    $test = $result; // Duplicating the variable
    $data = $test->fetchAll(); // Running the check on the duplicated variable
}
catch (PDOException $e)
{
        $error = 'Error fetching user: ' . $e->getMessage();
        echo $error;
        exit();
}

if (!$data) {
    echo "No data!";
} else {
    echo "Data found!";
}           

$row = $result->fetch(); // Still doesn't return the result!
    echo "First name: " . $row['first_name'];

Comment puis-je résoudre ce problème? J'ai essayé d'assigner $ result à une autre variable ($ test = $ result), puis d'exécuter la vérification des données sur la variable $ test à la place - mais même ainsi, la variable $ result TOUJOURS ne renvoie aucune donnée après avoir exécuté la vérification ( voir les lignes commentées):

try
{
    $result = $pdo2->prepare("SELECT first_name FROM users WHERE email = :email;");
    $result->bindValue(':email', $email);
    $result->execute();
    $data = $result->fetchAll();
}
catch (PDOException $e)
{
        $error = 'Error fetching user: ' . $e->getMessage();
        echo $error;
        exit();
}

if (!$data) {
    echo "No data!";
} else {
    echo "Data found!";
}           

$row = $result->fetch();
    echo "First name: " . $row['first_name'];

Cela me fait vraiment la tête ... Je pense qu'il y a une solution simple quelque part, je ne peux pas la voir. S'il vous plaît aider!


5 commentaires

Vous avez déjà récupéré toutes les données lorsque vous avez utilisé fetchAll , il ne reste donc plus rien à récupérer lorsque vous essayez d'utiliser fetch . fetchAll sera un tableau qui peut contenir une ou plusieurs lignes de données (puisque votre requête n'a pas limité le résultat à 1 ligne).


Vous pouvez également utiliser $ data = $ test-> fetchAll (PDO :: FETCH_ASSOC): . afin de ne renvoyer qu'un tableau associatif avec vos noms de colonnes. Voir ici pour plus d'informations


Tout comme un FYI, vous pouvez passer votre variable directement dans l'appel d'exécution et éviter un appel séparé à lier. $ result-> execute ([': email' => $ email]);


L'équivalent PDO de mysql_num_rows () est $ result-> rowCount ()


L'affectation d'objets à différentes variables ne fait pas de copie, donc tout ce que vous faites à une variable affecte l'autre. Seuls les tableaux sont copiés, pas les objets.


3 Réponses :


0
votes

Comme vous utilisez un bloc try / catch , vous pouvez lever vos propres exceptions et attraper celles lancées par PDO - vous pouvez donc faire quelque chose comme ceci:

try{

    $sql='SELECT first_name FROM users WHERE email = :email;';
    $stmt = $pdo2->prepare( $sql );

    if( !$stmt )throw new Exception('Failed to prepare sql statement');
    $result=$stmt->execute( array( ':email' => $email ) );

    if( !$result )throw new Exception('Failed to get any results');
    $rows = $stmt->rowCount();

    if( $rows == 0 )throw new Exception('Empty recordset');

    while( $rs=$stmt->fetch( PDO::FETCH_OBJ ) ){
        echo $rs->firstname;
    }

}catch ( PDOException $e ){
    exit( 'Error fetching user: ' . $e->getMessage() );
}


0 commentaires

2
votes

$ result-> fetch () ne récupère que les lignes qui n'ont pas déjà été récupérées. Puisque vous avez tout récupéré avec $ result-> fetchAll () , il ne reste plus rien.

Si vous voulez la première ligne, vous pouvez utiliser:

if (!$result->rowCount()) {
    echo "No data";
} else {
    echo "Data found!";
}

Si vous souhaitez traiter toutes les lignes, utilisez:

foreach ($data as $row)

Au lieu de tout récupérer, vous pouvez utiliser la méthode rowCount () .

$row = data[0];

Il y a des mises en garde concernant l'utilisation de rowCount () avec les requêtes SELECT dans PDO, mais je pense que c'est généralement fonctionne avec MySQL.


0 commentaires

0
votes

Vous pouvez toujours récupérer des lignes individuelles et pour la première ligne, vérifier si les données sont renvoyées et traiter sinon. Entrez ensuite une boucle do ... while () qui traite les données puis lit la ligne suivante à la fin de la boucle ...

try
{
    $result = $pdo2->prepare("SELECT first_name FROM users WHERE email = :email;");
    $result->bindValue(':email', $email);
    $result->execute();
    $row = $result->fetch();  // Fetch first row of data

    if (!$row) {
        echo "No data!";
    } else {
        echo "Data found!";

        do { 
            echo "First name: " . $row['first_name'];
        }
        while ($row = $result->fetch());
    }           
}
catch (PDOException $e)
{
        $error = 'Error fetching user: ' . $e->getMessage();
        echo $error;
        exit();
}


0 commentaires