2011-06-22 3 views
2

La fonction codeigniter suivante prend un paramètre (chaîne) et renvoie l'ID (entier) de la ligne. Cela fonctionne bien si je transmets des valeurs de chaîne, mais si l'entier 0 est passé, il renvoie l'ID de la première ligne dans la base de données. En principe, il doit retourner le user_id seulement si le user_name existe dans la base de données. Comme il n'y a pas de nom d'utilisateur appelé 0, il devrait retourner false. Quelqu'un peut-il dire pourquoi il se comporte ainsi et comment il peut être réparé?Question à propos de la fonction PHP return

Merci.

public function get_user_id($user_name) 
    { 
     $this -> db -> select('user_id'); 
     $this -> db -> from('users'); 
     $this -> db -> where('user_name', $user_name); 
     $this -> db -> limit(1); 

     $query = $this->db->get(); 

     if ($query->num_rows > 0) 
     { 
      $row = $query->row(); 
      return $row->user_id; 
     }  
    return false;  
    } 

Par exemple:

$user_name = "test"; //works fine, returns id. 
$user_name = "0"; //works fine, doesnt return anything 
$user_name = 0;  //Problem. returns ID of first row. 
+0

Le problème est sur l'instruction sql générée, vous devez le passer en tant que chaîne à la WHERE() – Gerep

Répondre

2

Vous devrait ajouter un test du k ind if ($user_name == "") return false; pour attraper ceci.

Apparemment where avec le second argument 0 correspond toujours, par ex. SQL se traduit WHERE user_name, plutôt que WHERE user_name = "" et WHERE user_name est sténographie pour WHERE user_name != "" - à l'opposé de ce que vous vouliez :-)

exécution de ce test au début vous enregistre une requête de base de données complète lorsque vous êtes passé un argument qui entraînera nécessairement false.

0

Vous pouvez utiliser http://php.net/strval pour forcer la variable à une chaîne:

$this -> db -> where('user_name', strval($user_name)); 

Vous pouvez aussi essayer:

$this -> db -> where('user_name', "$user_name"); 
1

vous pouvez essayer de lancer user_name $ à chaîne avant de passer comme param:

$user_name = (string)$user_name; 
0

Il est susceptible d'être un problème de type, et comment le CodeIgniter ou peut-être SQL traite avec l'entier.

Puisque vous connaissez le nom d'utilisateur va être une chaîne, tout jeter à une chaîne. Je crois que ce qui suit devrait régler tous les problèmes ici;

$this -> db -> where('user_name', (string) $user_name); 

Si vous prévoyez des objets peuvent également être transmis à cet objet, vous feriez mieux de faire une condition:

if(is_object($user_name)) { 
    $user_name = $user_name->__toString(); 
} else { 
    $user_name = (string) $user_name; 
} 

Put, bien sûr, au début de la fonction, avant de sélectionner la base de données.

0

Cela m'a buggé plusieurs fois, mais vous savez, quelques informations de la documentation MySQL.

« est connue et documentée fonctionnalité de MySQL. Lorsque l'on compare les numéros à chaînes, ils sont comparés en tant que nombres flottants. Toute chaîne qui ne commence pas par un chiffre est converti implicitement numéro 0. Par conséquent, les résultats que vous S'il vous plaît, comparez toujours nombres aux nombres et aux cordes aux cordes si vous voulez empêcher des résultats non désirés.

Lire http://dev.mysql.com/doc/refman/5.0/en/type-conversion.html pour les détails. Donc, le casting est la manière concrète d'assurer une comparaison correcte dans la requête ...ou à partir de MySQL ... il n'y a pas d'autre solution que de s'assurer que les littéraux de chaînes sont cités.