2010-05-10 10 views
5

Le PDO de PHP permet d'exécuter simultanément plusieurs requêtes, soit par la méthode query(), soit par une instruction préparée. Les deux exemples suivants fonctionnent:Le PDO de PHP peut-il être limité à une seule requête?

// Two SQL queries 
$query = "SELECT * FROM table; DROP table;" 

// Execute via query() 
$pdo->query($query); 

// Execute via prepared statement 
$stmt = $pdo->prepare($query); 
$stmt->execute(); 

est-il à un moment aucune façon de limiter PDO à une seule requête, tout comme la fonction mysql_query() est?

Répondre

6

Ceci est une réponse plus à jour à cette question.

L'ancienne façon d'empêcher l'exécution de requêtes multiples consistait à désactiver les préparations émulées, mais cela ne s'appliquait qu'à la méthode PDO::prepare(). Dans les versions plus récentes de PHP (> = 5.5.21 et> = 5.6.5), une nouvelle constante a été introduite pour désactiver cette exécution multi-requête dans les deux PDO::prepare() et PDO::query(). (Les constantes ne sont généralement pas ajoutées dans les versions de correctif, mais cela a été fait en raison de la gravité d'un Drupal SQL injection attack provoquée par cette capacité).

La nouvelle constante est PDO::MYSQL_ATTR_MULTI_STATEMENTS et doit être mis sur la création d'objets (comme le quatrième argument du constructeur AOP) - la mise sur un objet pré-existant avec PDO::setAttribute() ne fonctionnera pas.

$pdo = new PDO('mysql:host=_;dbname=_', '', '', [PDO::MYSQL_ATTR_MULTI_STATEMENTS => false]); 
+0

Je n'ai rien trouvé sur PDO :: MYSQL_ATTR_MULTI_STATEMENTS dans la documentation PHP. mais j'ai essayé et ça marche; –

+0

Je n'étais pas au courant qu'il n'avait pas encore été documenté. Je l'ai ajouté à [la page de constantes de MySQL] (http://php.net/manual/en/ref.pdo-mysql.php) - il devrait être visible dans quelques heures. – tpunt

6

Mmm, il y a un moyen d'y parvenir en désactivant l'émulation des instructions préparées en AOP pour le faire utiliser l'API native de MySQL à la place (multi-requêtes ne sont pas pris en charge côté serveur instructions préparées):

$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); 

Toutefois, l'un des inconvénients de cette option est que le cache de requête est perdu.

+1

"À partir de 5.1.17, les instructions préparées utilisent le cache de requête sous certaines conditions" - http://dev.mysql.com/doc/refman/5.1/en/query-cache-operation.html – VolkerK

+0

Il n'y a aucun moyen de l'empêcher via la méthode query() si? –

+0

Pas que je sache, sauf si vous utilisez du code personnalisé pour filtrer la chaîne de requête. – nuqqsa