Partage
  • Partager sur Facebook
  • Partager sur Twitter

Problème étrange de types dans MySQL

Avec les requêtes préparées.

Sujet résolu
    16 février 2013 à 0:13:50

    Bonjour, J’ai un soucis avec mysql dans PHP.

    C’est assez étrange, car j’utiliser PDO pour switcher entre MYSQL et SQLite et dans SQLite je n’ai pas de problèmes.

    Le code suivant fonctionne comme prévu et me sort bien les 10 derniers articles :

    $req = $GLOBALS['db_handle']->prepare("SELECT * FROM articles ORDER BY bt_date DESC LIMIT 0, 10");
    $req->execute();

    Par contre, ceci ne marche pas (notez les « ' » autour des chiffres à la fin de la requête) :

    $req = $GLOBALS['db_handle']->prepare("SELECT * FROM articles ORDER BY bt_date DESC LIMIT '0', '10'");
    $req->execute();

    Et ceci non plus :

    $req = $GLOBALS['db_handle']->prepare("SELECT * FROM articles ORDER BY bt_date DESC LIMIT ?, ?");
    $req->execute(array(0, 10));

    Ni ça :

    $req = $GLOBALS['db_handle']->prepare("SELECT * FROM articles ORDER BY bt_date DESC LIMIT ?, ?");
    $req->execute(array('0', '10'));

    Dans les cas où ça ne marche pas, j’ai ça comme erreur :

    SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''0', '10'' at line 1

    On dirait que le moteur PDO transforme les valeurs du tableau dans le execcute() en strings, alors qu’en PHP ce sont bien des (integer) : j’ai vérifié avec var_dump.

    (désolé pour les balises de code, avec cette version du SDZ ça foire, c’est horrible…). 

    • Partager sur Facebook
    • Partager sur Twitter
      16 février 2013 à 8:07:31

      Oui c'est le cas, execute considère tout les valeurs bindés comme des string:

      C'est écrit dans le man:

      http://www.php.net/manual/fr/pdostatement.execute.php

      Je cite:

      "Toutes les valeurs sont traitées comme des constantes PDO::PARAM_STR."

      Si tu veux spécifier une type précis pour tes params, utilise la fonction:

      bindParam


      -
      Edité par learningCode 16 février 2013 à 8:08:44

      • Partager sur Facebook
      • Partager sur Twitter
        16 février 2013 à 12:36:46

        Ouais, je viens de voir là aussi : https://bugs.php.net/bug.php?id=44639

        Mon problème, c’est que je ne peux pas utiliser bindParam : je met plusieurs types de variables dans le execute(), en même temps.

        Je crois qu’il faudra que je fasse quelque chose comme ça :

        $req = $GLOBALS['db_handle']->prepare("SELECT * FROM articles ORDER BY bt_date DESC LIMIT ".$someInt.", ".$someOtherInt.");
        $req->execute(array());

        En ayant au préalable testé les deux variables avec is_integer().

        • Partager sur Facebook
        • Partager sur Twitter
          16 février 2013 à 13:34:18

          Mon problème, c’est que je ne peux pas utiliser bindParam : je met plusieurs types de variables dans le execute(), en même temps.

          Je ne comprends pas ce que ça change pour toi, vu l'exemple que tu donnes ensuite. Sinon tentes de désactiver l'émulation des requêtes préparées (attribut PDO::ATTR_EMULATE_PREPARES à FALSE).

          -
          Edité par julp 16 février 2013 à 13:37:50

          • Partager sur Facebook
          • Partager sur Twitter
            16 février 2013 à 17:36:53

            Ah, je n’avais pas vu qu’on pouvait appeler bindParam plusieurs fois^^'

            Du coup j’ai fait ça et ça marche avec MySQL :

            $req = $db_handle->prepare("SELECT * FROM articles ORDER BY bt_date DESC LIMIT ?, ?");
            
            foreach ($array as $key => $val) {
            	if (is_numeric($val)) {
            		$req->bindValue($key+1, (int)$val, PDO::PARAM_INT);
            	} else {
            		$req->bindValue($key+1, $val, PDO::PARAM_STR);
            	}
            }
            
            $req->execute();
            

            (ne pas oublier de retirer le $array dans le execute aussi)

            • Partager sur Facebook
            • Partager sur Twitter

            Problème étrange de types dans MySQL

            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
            × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
            • Editeur
            • Markdown