php - PDO和PDOStatement为什么会同时存在?这样的设计是出于什么考虑呢?
我想大声告诉你
我想大声告诉你 2017-05-16 13:11:25
0
3
741

问题描述:
都知道自PHP 5.1.0 起,PDO就算是PHP的标配的一部分了,PDO提供了3个类PDOPDOStatementPDOExceptionPDOException这个类就不用说了,功能和定位啥的看名字都很清楚。

那么问题来了:为什么会同时存在PDOPDOStatement这两个类?

为什么会有这样的疑问,先看下图(图片截取自@PHP官网手册):

图片是PDOPDOStatement类所声明的方法,可以看出,这两个类提供的方法虽然绝大部分不同,但是明显核心方法有重叠或重复,比如:

  • PDO::query()PDO::exec()都是执行一条SQL语句,只是返回不同

  • PDOStatement::execute() 也是执行一条SQL语句,只是语句被预处理过

PDOStatement::execute()还好说,而PDO::query()PDO::exec() 同时存在的必要性又是什么呢?而且还会造成使用和理解上面的不畅。

好吧,就算有同时存在的必要性
那么还是有一点为什么要同时存在这两个类呢?而不是一个类(假如只有 PDO类)就将这两个类所能做的事情一起做了呢?
PDO 类和 PDOStatement 类之间是什么关系呢?

如果 PDO 类用来执行SQL和管理链接,而 PDOStatement 类只用来处理结果集,那么感觉就舒服顺畅多了。

希望有大牛能给予解释 PHPPDO 这么设计的考虑是什么,真诚感谢~

我想大声告诉你
我想大声告诉你

répondre à tous(3)
曾经蜡笔没有小新

Je crois comprendre que l'un est utilisé pour exécuter du SQL ordinaire et l'autre peut être utilisé pour la liaison de paramètres, etc....

仅有的幸福

Je vais vous dire ma compréhension personnelle. Veuillez me corriger s'il y a des erreurs.
Premier aperçu de la classe AOP

PDO::prepare — Prepares a statement for execution and returns a statement object
PDO::query — Executes an SQL statement, returning a result set as a PDOStatement object

Vous pouvez voir que query() et prepare() renvoient un objet PDOStatement, ce qui signifie que PDOStatement peut exploiter l'ensemble de résultats.
En regardant à nouveau PDO::prepare, le manuel indique qu'il exécute une instruction préparée. En fait, il obtient une instruction préparée PDOStatement, puis exécute réellement SQL en appelant PDOStatement::execute().
Habituellement, certains de nos projets utilisent prepare pour exécuter des instructions SQL. Ceci est fait pour empêcher l'injection SQL et améliorer les performances des requêtes du même modèle SQL. Le contenu du manuel officiel est introduit :
La requête doit seulement être analysée (ou préparée). une fois, mais peut être exécuté plusieurs fois avec des paramètres identiques ou différents. Lorsque la requête est préparée, la base de données analysera, compilera et optimisera son plan d'exécution de la requête. Pour les requêtes complexes, ce processus peut prendre suffisamment de temps pour être visible. ralentir une application s'il est nécessaire de répéter la même requête plusieurs fois avec des paramètres différents. En utilisant une instruction préparée, l'application évite de répéter le cycle d'analyse/compilation/optimisation Cela signifie que les instructions préparées utilisent moins de ressources et s'exécutent donc plus rapidement. .

Les paramètres des instructions préparées n'ont pas besoin d'être cités ; le pilote gère automatiquement cela. Si une application utilise exclusivement des instructions préparées, le développeur peut être sûr qu'aucune injection SQL ne se produira (cependant, si d'autres parties du fichier sont utilisées). les requêtes sont en cours de construction avec des entrées sans échappement, l'injection SQL est toujours possible). exécute select, insert, update,deletePDO::query exécute une instruction SQL et, si elle est transmise, renvoie un objet PDOStatement
PDO::exec exécute une instruction SQL et renvoie le nombre de lignes affectées. Cette fonction ne renvoie pas de collection de résultats.
PDOStatement::execute a été introduit plus tôt. Il s'agit d'une sous-fonction sous PDOStatement. Une fonctionnalité est qu'elle prend en charge les paramètres de liaison sans prendre en compte les problèmes de sécurité de l'injection SQL. Une autre fonctionnalité est qu'elle prend en charge plusieurs exécutions, de la même manière que le modèle SQL. performance.
Si vous n'interrogez qu'une seule instruction, l'avantage d'utiliser la requête est que l'ensemble de résultats renvoyé par la requête peut être parcouru directement.
Si vous utilisez exec pour l'exécuter, il renverra uniquement le nombre de lignes affectées, pas le jeu de résultats PDOStatement. Vous ne pouvez pas le parcourir directement. Suivez les recommandations officielles pour utiliser la requête ou l'exécuter.
C'est à peu près ce que je comprends.

Ty80
1.exec
2.query
3.prepare+execute

Les trois méthodes ci-dessus peuvent toutes exécuter SQL. Si vous trouvez cela déroutant, vous ne pouvez utiliser que la troisième méthode.
Parce que tant que exec et query peuvent y parvenir, préparer+exécuter peut également y parvenir.
Et préparer+exécuter peut le faire. pour y parvenir, comme le prétraitement des requêtes paramétrées, exec et query ne peuvent pas être implémentés.
Exec et query apparaissent davantage pour plus de commodité. Par exemple, parfois les instructions SQL que nous exécutons n'ont pas de paramètres externes, alors l'utilisation de exec et query sera plus. concis, évidemment, exec est plus approprié pour exécuter une seule instruction d'opération d'écriture (INSERT/UPDATE/DELETE), car exec peut renvoyer directement les lignes affectées. Si vous utilisez une requête, vous devez appeler rowCount() pour obtenir les lignes affectées, telles que. as :
$db->query($sql)->rowCount();$db->query($sql)->rowCount();
当如果你执行没有外来参数的SQL获取SELECT结果,这时则应该用query而不是exec:
$db->query($sql)->fetchAll();Lorsque vous exécutez SQL sans paramètres externes pour obtenir le résultat SELECT, vous devez utiliser query au lieu d'exec :
$db->query($sql)->fetchAll();

Si vous exécutez SQL avec des paramètres d'entrée, afin d'empêcher l'injection SQL, vous devez utiliser prepare:🎜
$sql = "SELECT * FROM `io_post` WHERE `id` IN (?, ?, ?)";
$params = array(1, 3, 5); //$params是一个参数数组,元素按顺序一一对应$sql中的问号?占位符
$stmt = $db->prepare($sql);
$stmt->execute($params); //execute会自动对参数数组的每个元素进行bindValue
$stmt->fetchAll(); //如SELECT结果集
$stmt->rowCount(); //如INSERT/UPDATE/DELETE受影响的行
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!