Comment appliquer bindValue méthode dans la clause LIMIT?
Voici un aperçu de mon code:
$fetchPictures = $PDO->prepare("SELECT *
FROM pictures
WHERE album = :albumId
ORDER BY id ASC
LIMIT :skip, :max");
$fetchPictures->bindValue(':albumId', $_GET['albumid'], PDO::PARAM_INT);
if(isset($_GET['skip'])) {
$fetchPictures->bindValue(':skip', trim($_GET['skip']), PDO::PARAM_INT);
} else {
$fetchPictures->bindValue(':skip', 0, PDO::PARAM_INT);
}
$fetchPictures->bindValue(':max', $max, PDO::PARAM_INT);
$fetchPictures->execute() or die(print_r($fetchPictures->errorInfo()));
$pictures = $fetchPictures->fetchAll(PDO::FETCH_ASSOC);
- Je obtenir
Vous avez une erreur dans votre syntaxe SQL;
consultez le manuel qui correspond à
votre serveur MySQL version pour le
droit de la syntaxe à utiliser près de "15', 15' à
ligne 1
Il semble que PDO est l'ajout de guillemets simples pour mes variables dans la LIMITE de la partie du code SQL. Je l'ai regardé, j'ai trouvé ce bug qui je pense est lié:
http://bugs.php.net/bug.php?id=44639
Est que ce que je suis en train de regarder? Ce bug a été ouvert depuis avril 2008!
Que sommes-nous censés faire en attendant?
J'ai besoin de construire une partie de la pagination, et devez vous assurer que les données sont propres, sql injection-sûr, avant l'envoi de l'instruction sql.
Vous devez vous connecter pour publier un commentaire.
Je me souviens avoir eu ce problème avant. Convertir la valeur d'un nombre entier, avant de la transmettre à la fonction de liaison. Je pense que cela résout.
(int) trim($_GET['skip'])
, essayezintval(trim($_GET['skip']))
.bindParam
?La solution la plus simple serait de basculer le mode d'émulation off. Vous pouvez le faire soit comme une option de connexion ou tout simplement en ajoutant la ligne suivante
Il ne sera pas seulement de résoudre votre problème avec bind param, mais vous permet également d'envoyer des valeurs dans le execute(), qui permet de rendre votre code de façon spectaculaire tireur de
SQLSTATE[IM001]: Driver does not support this function: This driver doesn't support setting attributes
...Pourquoi est-il jamais si simple pour me 🙂 Alors que je suis sûr que cela va obtenir la plupart des gens là-bas, dans mon cas, j'ai fini par avoir à utiliser quelque chose de similaire à la accepté de répondre. Juste un heads-up pour les futurs lecteurs!PDO::ATTR_EMULATE_PREPARES Enables or disables emulation of prepared statements. Some drivers do not support native prepared statements or have limited support for them
. C'est une nouvelle pour moi, mais encore une fois je suis juste de commencer avec PDO. Généralement utiliser mysqli, mais pensé que je voudrais essayer d'élargir mes horizons.setAttribute
pour la déclaration($stm, $stmt) non pas pour l'objet pdo.À la recherche sur le rapport de bug, on peut travailler:
mais êtes-vous sûr que vos données entrantes est correcte? Parce que dans le message d'erreur, il semble y avoir seulement un devis après le nombre (par opposition au nombre entier d'être entourées de guillemets). Ce pourrait être aussi une erreur avec la réception de vos données. Pouvez-vous faire un
print_r($_GET);
trouver?- Ce juste que sommaire.
Il existe quatre options pour paramétrer la LIMITE de/les valeurs de DÉCALAGE:
Désactiver
PDO::ATTR_EMULATE_PREPARES
comme mentionné ci-dessus.Qui empêche les valeurs transmises par
->execute([...])
de toujours afficher des chaînes de caractères.Commutateur manuel
->bindValue(..., ..., PDO::PARAM_INT)
paramètre de la population.Mais qui est moins pratique qu'un ->execute liste[].
Simplement faire une exception ici et juste interpoler plaine entiers lors de la préparation de la requête SQL.
Le casting est important. Plus souvent vous voir
->prepare(sprintf("SELECT ... LIMITE de %d", $num))
utilisés à de telles fins.Si vous n'êtes pas à l'aide de MySQL, mais par exemple SQLite ou Postgresql; vous pouvez également associer des paramètres liés directement en SQL.
De nouveau, MySQL/MariaDB ne prennent pas en charge les expressions de la clause LIMIT. Pas encore de.
{$_GET->int["limit"]}
pour de tels cas.pour
LIMIT :init, :end
Vous devez lier de cette façon. si vous aviez quelque chose comme
$req->execute(Array());
il l'habitude de travailler comme il jetaitPDO::PARAM_STR
à tous les revendeurs dans le tableau et pour leLIMIT
vous avez absolument besoin d'un nombre Entier.bindValue ou BindParam que vous le souhaitez.
Puisque personne n'a expliqué pourquoi ce qui se passe, je vais ajouter une réponse. La raison, c'est se comporter de cette été est parce que vous êtes à l'aide de
trim()
. Si vous regardez le manuel PHP pourtrim
, le type de retour eststring
. Vous êtes ensuite essayer de la passer enPDO::PARAM_INT
. Quelques méthodes pour contourner ce problème sont:filter_var($integer, FILTER_VALIDATE_NUMBER_INT)
à assurez-vous que vous êtes de passage à un entier.intval()
(int)
is_int()
Il y a beaucoup plus de moyens, mais c'est essentiellement la cause.
bindValue de décalage et de limiter l'utilisation de PDO::PARAM_INT et il fonctionnera
//AVANT (Présent d'erreur)
$query = " .... LIMITE :p1, 30;";
...
$stmt->bindParam(':p1', $limiteInferior);
//APRÈS (correction d'une Erreur)
$query = " .... LIMITE :p1, 30;";
...
$limiteInferior = (int)$limiteInferior;
$stmt->bindParam(':p1', $limiteInferior, PDO::PARAM_INT);
PDO::ATTR_EMULATE_PREPARES
m'a donné l'Ma solution est de définir un
$limit
variable une chaîne de caractères, puis de les combiner dans l'instruction prepare comme dans l'exemple suivant:Je n'ai la suite de la mine où $info est mon tableau en tenant mes paramètres liés:
Ceci est basé en partie sur Sebas du code.