2010-02-28 4 views
0
$allUsersResult = mysql_query("SELECT * FROM users"); 

// the purpose of this line was to grab the first row for use 
// separately in a different area than the while loop 
$user = mysql_fetch_assoc($allUsersResult); 


while($users = mysql_fetch_assoc($allUsersResult)){ 

// the first row is not available here 

} 

Alors, est-ce un bug ou est-ce ma faute de le faire mal?Est-ce un bug PHP ou MySQL?

PS: ce n'est que par exemple. Je n'utilise pas à la fois l'utilisateur $ et la boucle while l'un à côté de l'autre comme ceci, ils sont utilisés à différents endroits dans le script.

+7

En général, si vous vous demandez s'il s'agit d'un bug PHP/MySQL, ce n'est probablement pas le cas. :) –

+8

En général, si vous vous demandez si c'est un bogue dans un morceau de code très utilisé, ou dans votre propre code, tous les signes pointent vers vous. C'est l'une des leçons difficiles à apprendre, à cesser de chercher quelqu'un d'autre à blâmer, et à penser «qu'est-ce que je fais de mal? –

+0

Pour tous ceux qui pourraient trébucher sur cette page dans le futur: Mettez mysql_data_seek ($ allUsersResult, 0); avant votre boucle pour mettre la première rangée dans votre résultat comme suggéré par jasonbar. – Chad

Répondre

13

Vous devez déposer

$allUsers = mysql_fetch_assoc($allUsersResult); 

Il prend votre première ligne de résultat.

Réponse à la nouvelle question: Non. Ce n'est pas un défaut de conception en PHP. C'est un défaut dans la conception de votre programme. Vous devez repenser ce que vous faites.

Pourquoi avez-vous besoin de la première valeur séparée? Est-ce que vous comptez sur lui pour être une rangée spécifique de votre table tout le temps? Si vous modifiez votre schéma de table, très possible que les résultats vous seront retournés en utilisant un autre ordre trié. Peut-être que si vous nous dites ce que vous essayez de faire, nous pouvons vous donner quelques suggestions de conception.

+0

OK, alors que dois-je faire si j'ai besoin d'utiliser les deux? Dois-je exécuter la requête deux fois? – Chad

+0

@Chad: Je ne sais pas vraiment ce que tu veux dire. Vous avez déjà le premier résultat? Je suppose que vous pourriez ajouter mysql_data_seek ($ allUsersResults, 0) avant votre boucle ..? Votre nom de variable est un peu déroutant car '$ allUsers' n'aura pas réellement" tous les utilisateurs ". – jasonbar

+0

Le nom $ allUsers implique qu'il récupère la totalité de la table - ce n'est pas le cas, il ne prend qu'une ligne. Vous pouvez simplement définir $ allUsers = array(); puis dans la boucle while faites $ allUsers [] = $ users pour copier chaque ligne dans un tableau. – GoatRider

10

C'est de votre faute. En appelant d'abord le $allUsers = mysql_fetch_assoc($allUsersResult);, vous récupérez déjà la première ligne du jeu de résultats. Il suffit donc de supprimer cette ligne, et cela devrait fonctionner comme prévu.

modifier: Par demande en commentaire.

$user = mysql_fetch_assoc($allUsersResult); 
if ($user) // check if we actually have a result 
{ 
    // do something special with first $user 

    do 
    { 
     // do the general stuff with user 
    } 
    while($user = mysql_fetch_assoc($allUsersResult)); 
} 
+0

ok, et si j'ai besoin de la première rangée avant de faire une boucle, comment le feriez-vous (sans mettre tout le résultat dans votre propre tableau d'abord) – Chad

+0

Edited ma réponse pour avoir un exemple d'un tel cas. – poke

+0

Cela suppose que les deux opérations se déroulent au même endroit dans votre code. Considérez ceci: votre requête mysql est sur page.php et vous avez besoin du premier utilisateur dans page.php mais vous avez besoin de tous les résultats (while loop) sur page2.php, qui est inclus dans page.php après avoir demandé la première ligne . Il semble que mysql_data_seek() soit nécessaire pour remettre la première ligne. – Chad

0

Ce qui est considéré comme un mauvais code par certains IDE (deux instructions sur une ligne). Mieux:

$allUsersResult = mysql_query("SELECT * FROM users"); 
$user = mysql_fetch_assoc($allUsersResult); 

while($user){ 

    // do stuff 
    doStuff($user) 

    // at last: get next result 
    $user = mysql_fetch_assoc($allUsersResult) 


} 
+0

cela crée juste une boucle infinie – Chad

+0

@Chad Non, ce n'est pas le cas. – deceze

+0

C'est moche, désordonné et si mon IDE me disait que c'était un meilleur style, j'irais chercher un autre IDE. – symcbean

-1

Je vais aller de l'avant et de répondre à ma propre question sur celui-ci:

$allUsersResult = mysql_query("SELECT * FROM users"); 

    // transfer all rows to your own array immediately 
    while($user = mysql_fetch_assoc($allUsersResult)){ 
     $allUsers[] = $user; 
    } 

    // use first row however you like anywhere in your code 
    $firstRow = $allUsers[0]; 

    // use all rows however you like anywhere in your code 
    foreach($allUsers as $user){ 
     // do whatever with each row ($user). Hey look they're all here! :) 
    } 
+0

Le seul inconvénient est que vous devez faire la partie de transfert pour chaque requête différente (mais bien sûr, vous pouvez créer une fonction pour gérer cela pour vous). S'il y a un meilleur moyen s'il vous plaît faites le moi savoir. – Chad

+0

Tchad, vous avez demandé des commentaires ici. Cela semble être une façon beaucoup plus simple et plus directe d'aborder la situation que vous décrivez. Cela prend beaucoup plus de sens que d'obtenir la première ligne, puis de réinitialiser le pointeur de résultat interne. (Il est probable que j'aurais choisi ceci ou similaire, ne sachant toujours pas la situation complète). Je suis content que vous ayez décidé d'examiner la conception de votre programme et de le modifier pour mieux l'adapter à votre situation. – jasonbar

+0

@jasonbar C'est la seule façon que je connaissais de le faire tout le long, et je m'attendais à obtenir exactement cela comme une réponse de presque tout le monde. Je pense que cela devrait être possible avec certaines fonctions PHP intégrées. – Chad

0

Lorsque vous utilisez mysql_fetch_assoc(), vous récupérez essentiellement la ligne, puis faire avancer le pointeur interne +1 .

Pour mieux expliquer, voici votre code:

$allUsersResult = mysql_query("SELECT * FROM users"); 
//Result is into $allUsersResult... Pointer at 0 


$user = mysql_fetch_assoc($allUsersResult); 
// $user now holds first row (0), advancing pointer to 1 


// Here, it will fetch second row as pointer is at 1... 
while($users = mysql_fetch_assoc($allUsersResult)){ 

// the first row is not available here 

} 

Si vous voulez récupérer la première ligne à nouveau, vous n'avez pas besoin pour exécuter la requête à nouveau, il suffit de réinitialiser le pointeur à 0 fois vous avez lu la première ligne ...

$allUsersResult = mysql_query("SELECT * FROM users"); 
//Result is into $allUsersResult... Pointer at 0 


$user = mysql_fetch_assoc($allUsersResult); 
// $user now holds first row (0), advancing pointer to 1 

// Resetting pointer to 0 
mysql_data_seek($allUsersResult, 0); 

// Here, it will fetch all rows starting with the first one 
while($users = mysql_fetch_assoc($allUsersResult)){ 
    // And the first row IS available 
} 

PHP Documentation: mysql_data_seek()