web-dev-qa-db-fra.com

Comment puis-je utiliser des instructions préparées dans CodeIgniter

Salut à tous, j'ai besoin d'utiliser des déclarations préparées sur mon site. J'ai essayé d'utiliser ceci

$sql = "SELECT * FROM tbl_user WHERE uid=:id and activation_key=:key";
$query = $this->db->query( 
    $sql, 
    array( ':id' => $uid ,':key' => $activation_key)
);

mais ça ne fonctionne pas. Quand je change :id et :key à ? ça marche.

25
Pramod

CodeIgniter ne prend pas en charge les instructions préparées. Si vous regardez le code source de la classe Database de CI, vous verrez qu'ils résolvent les liaisons simplement en remplaçant les points d'interrogation par les données du tableau passé:

Ils ne prennent en charge la liaison de requête qu'avec des espaces réservés sans nom. Voir http://ellislab.com/codeigniter/user-guide/database/queries.html

Liaisons de requête

Les liaisons vous permettent de simplifier la syntaxe de votre requête en laissant le système assembler les requêtes pour vous. Prenons l'exemple suivant:

$sql = "SELECT * FROM some_table WHERE id = ? AND status = ? AND author = ?";
$this->db->query($sql, array(3, 'live', 'Rick'));

Les points d'interrogation de la requête sont automatiquement remplacés par les valeurs du tableau dans le deuxième paramètre de la fonction de requête.

et http://ellislab.com/forums/viewthread/105112/#528915

Même si CI ne prend pas en charge les instructions préparées, il prend en charge les liaisons de requête. Avec les instructions préparées, vous devez appeler un type de fonction prepare () puis un type de fonction execute (). Avec les liaisons de requête, vous n'avez qu'à appeler une fonction et cela fait essentiellement la même chose. Pour cette raison, j'aime mieux les liaisons de requête que les instructions préparées.

Sur un sidenote, changer ? à :foo est simplement en train de passer de liaisons sans nom à des liaisons nommées (que CI ne prend apparemment pas en charge non plus). Ce n'est pas parce que vous utilisez ou ne signifie pas que vous préparez les déclarations.

40
Gordon

Je suis tombé sur cette question car je faisais face à un problème similaire. La réponse est correcte: CI ne prend pas en charge les instructions préparées. Cependant, cela ne signifie pas que vous ne pouvez pas utiliser les instructions préparées!

Dans l'exemple suivant, j'utilise PDO comme classe de connexion, mais le code suivant fonctionnera:

$q = $this->db->conn_id->prepare('SELECT * FROM tbl_user WHERE uid=? and activation_key=?');
$q->execute(array($param1,$param2));
print_r($q->fetchAll());

Remarque le conn_id est l'objet PDO sur lequel vous pouvez exécuter vos instructions préparées.

Cependant, ce que cela ne permet pas, c'est d'obtenir la chaîne de requête autorisée par les fonctions CI natives. Vous aurez besoin de quelque chose comme Get Last Executed Query in PHP PDO pour cela.

De plus, cependant, cela ne vous empêche pas d'utiliser le générateur de requêtes pour créer vos instructions que vous pouvez ensuite utiliser dans la préparation PDO. Par exemple -

$db->where('uid = ?',null,false);
$db->where('activation_key = ?',null,false);
$q = $this->db->conn_id->prepare($db->get_compiled_select('tbl_user'));

Générerait la requête et vous permettrait de voir la requête de base si vous produisez $db->get_compiled_select('tbl_user');

8
Antony