Pourquoi mon AOP déclaration -> execute retourne false?
Après près d'interminables séries de tests sur différents aspects de cette, j'ai déterminé que l'AOP connexion fonctionne (je peux exécuter une requête simple et afficher les résultats), j'ai déterminé que la déclaration est correctement préparation, et que les valeurs sont de liaison correctement. Pour une raison quelconque, la déclaration ne sera pas exécuté. Juste pour être mignon, j'ai essayé de supprimer toutes les variables liées à l'exécution d'un statique de la requête et qui ne fonctionne pas, soit.
Code:
$dbh = new PDO( "mysql:host=localhost;dbname=".$GLOBALS['data_name'], $GLOBALS['data_user'], $GLOBALS['data_pass'] );
$dbh->setAttribute (PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
$sth = $dbh->prepare( "SELECT * FROM :table WHERE :field = :value" );
if( $sth != false ) TCDebug( 'prepared' );
if( $sth->bindValue( ":table", $table ) ) TCDebug( "table true" );
if( $sth->bindValue( ":field", $field ) ) TCDebug( "field true" );
if( $sth->bindValue( ":value", $value ) ) TCDebug( "value true" );
$flag = $sth->execute();
if( $flag === true ) {
TCDebug( 'flag = true' );
} else if( $flag === false ) {
TCDebug( 'flag = false' );
}
$result = $sth->fetchAll();
foreach( $result as $c ) TCDebugArr( $c );
TCDebug( count( $result ) );
if( count( $result ) > 0 ) {
return $result;
} else {
return null;
}
Constamment echos texte de débogage de "préparé" la table de vrai' champ 'vraie' valeur true' 'flag = false' qui m'a dit que la préparation et de la liaison de travail, mais l'exécution n'est pas, $résultat est vide et la fonction retourne null.
J'ai probablement oublié quelque chose d'horriblement évident, et je suis tout à fait prêt à accrocher ma tête dans une totale n00b honte. Je vous remercie à l'avance...
Mise à JOUR
Ahh, la concaténation -- mon ami, aujourd'hui. Code de travail suit:
$dbh = new PDO( "mysql:host=localhost;dbname=".$GLOBALS['data_name'], $GLOBALS['data_user'], $GLOBALS['data_pass'] );
$dbh->setAttribute (PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
$prepare_str = "SELECT * FROM ". $table ." WHERE ". $field ." = :value";
$sth = $dbh->prepare( $prepare_str );
if( $sth != false ) TCDebug( 'prepared' );
if( $sth->bindValue( ":value", $value ) ) TCDebug( "value true" );
$flag = $sth->execute();
if( $flag === true ) {
TCDebug( 'flag = true' );
} else if( $flag === false ) {
TCDebug( 'flag = false' );
}
$result = $sth->fetchAll();
foreach( $result as $c ) TCDebugArr( $c );
TCDebug( count( $result ) );
if( count( $result ) > 0 ) {
return $result;
} else {
return null;
}
C'est sûr, dans ce cas, étant donné $table
et $field
sont générés par le système, et en aucune façon accessible via la saisie de l'utilisateur; $valeur est exposée.
Merci StackOverflow! Vous êtes mon préféré! 🙂
OriginalL'auteur somewhatsapient | 2011-06-21
Vous devez vous connecter pour publier un commentaire.
Lorsque vous avez une requête paramétrée qui ressemble à ceci:
et vous des valeurs de substitution pour
:table
,:field
, et:value
, vous obtenez quelque chose de similaire à la suivante (en fait c'est une simplication excessive, mais illustre le point):parce que
:table
et:field
obtenir le même traitement sémantique comme:value
, c'est à dire. ils sont traités comme des chaînes de caractères. Vous ne pouvez généralement pas en mesure de paramétrer les noms de table et les noms de colonnes avec des requêtes paramétrées. Vous devez repenser votre approche un peu. Vous pourriez envisager de manière dynamique de la construction de votre déclaration de la chaîne de sorte que la table et le nom de colonne parties de la requête sont des concaténations simples, plutôt que de les lier avec PDO. Mais vous devez être très prudent qui vous permet de valider/désinfecter la table et de la colonne des noms, parce que PDO ne sera pas vous protéger contre l'injection SQL à ce niveau.:table
et:field
(qui ne sont pas ouverts à la saisie de l'utilisateur et doit être en sécurité lorsque concaténés) et remplacer:value
, je suis peut-être en est-il clair?+1 sauf pour les "traités comme des chaînes et des cités". Ils sont en fait passées comme paramètres pour l'instruction préparée, bien que pour des fins d'illustration, votre exemple est correct
Génial Asaph - qu'il fixe. Assez facile à changer pour concaténer
$table
et$field
, et de le lier$value
Oui. Vous êtes correct. J'ai essayé d'être prudent dans ma formulation, surtout quand j'ai dit "vous obtenez quelque chose de similaire". Mais j'ai glissé vers le haut. Je vais modifier l' "et cité" une partie. Je vous remercie pour elle.
Oui, l'idée que vous avez présentés dans votre premier commentaire sera le travail.
OriginalL'auteur Asaph