ホームページ  >  に質問  >  本文

php - PDO和PDOStatement为什么会同时存在?这样的设计是出于什么考虑呢?

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

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

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

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

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

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

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

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

我想大声告诉你我想大声告诉你2712日前746

全員に返信(3)返信します

  • 曾经蜡笔没有小新

    曾经蜡笔没有小新2017-05-16 13:13:25

    私の理解では、1つは通常のSQLの実行に使用され、もう1つはパラメーターのバインドなどに使用できるということです...

    返事
    0
  • 仅有的幸福

    仅有的幸福2017-05-16 13:13:25

    私の個人的な理解を述べますので、間違いがあればご指摘ください。
    PDO クラスを初めて見てみる

    リーリー

    query() と prepare() の両方が PDOStatement オブジェクトを返すことがわかります。これは、PDOStatement が結果セットを操作できることを意味します。
    PDO::prepare をもう一度見てみると、マニュアルには準備済みステートメントを実行すると書かれていますが、実際には準備済みステートメント PDOStatement を取得し、PDOStatement::execute() を呼び出して実際に SQL を実行します。
    通常、一部のプロジェクトでは SQL ステートメントを実行するために準備を使用します。このアプローチは、SQL インジェクションを防止し、同じテンプレート SQL のクエリのパフォーマンスを向上させるためのものです。公式マニュアルの内容が紹介されています。
    クエリは解析 (または準備) するだけで済みます。クエリが準備されると、データベースはクエリを実行するための計画を分析、コンパイル、最適化するため、このプロセスにはかなりの時間がかかることがあります。異なるパラメーターを使用して同じクエリを何度も繰り返す必要がある場合、アプリケーションの速度が低下します。プリペアド ステートメントを使用すると、分析、コンパイル、最適化のサイクルが繰り返されることがなくなり、プリペアド ステートメントの実行速度が向上します。 .

    プリペアド ステートメントのパラメーターを引用符で囲む必要はありません。アプリケーションがプリペアド ステートメントのみを使用する場合、開発者は SQL インジェクションが発生しないことを確認できます

    (ただし、クエリはエスケープされていない入力で構築されていますが、SQL インジェクションは依然として可能です)。PDO::query と PDO::exec の違いについて投稿者が述べたことについては、次のようになります:query は select ステートメントのみを実行し、exec は実行します。 select、insert、update、delete を実行します
    PDO::query SQL ステートメントを実行し、渡された場合は PDOStatement オブジェクトを返します
    PDO::exec SQL ステートメントを実行し、影響を受ける行の数を返します。この関数は結果コレクションを返しません。
    PDOStatement::execute は PDOStatement のサブ関数であり、SQL インジェクションのセキュリティ問題を考慮せずにパラメーターのバインドをサポートすることも特徴です。もう 1 つの特徴は、テンプレート SQL と同様に、複数の実行をサポートすることです。パフォーマンス。
    1 つのステートメントのみをクエリする場合、クエリを使用する利点は、クエリによって返された結果セットを直接走査できることです。
    exec を使用して実行すると、PDOStatement の結果セットではなく、影響を受ける行の数のみが返されます。これを直接走査することはできません。クエリを使用または実行するには、公式の推奨事項に従ってください。
    私が理解しているのは大体こんな感じです。

    返事
    0
  • PHP中文网

    PHP中文网2017-05-16 13:13:25

    リーリー

    上記の 3 つのメソッドはすべて SQL を実行できます。わかりにくい場合は、3 番目のメソッドのみを使用できます。
    exec と query がそれを実現できる限り、prepare+execute も実現できます。
    そして prepare+execute は可能です。パラメータ化されたクエリの前処理など、exec と query は実装できません。たとえば、実行する SQL ステートメントに外部パラメータがない場合は、exec と query を使用することになります。簡潔に言うと、exec は影響を受ける行を直接返すことができるため、単一の書き込み操作 (INSERT/UPDATE/DELETE) ステートメントの実行には明らかに exec の方が適しています。クエリを使用する場合、影響を受ける行を取得するには rowCount() を呼び出す必要があります。 as :
    $db->query($sql)->rowCount();
    外部パラメータなしで SQL を実行して SELECT 結果を取得する場合は、exec の代わりに query を使用する必要があります。 $db->query($sql)->fetchAll();$db->query($sql)->rowCount();
    当如果你执行没有外来参数的SQL获取SELECT结果,这时则应该用query而不是exec:
    $db->query($sql)->fetchAll();入力パラメータを使用して SQL を実行する場合、SQL インジェクションを防ぐために、prepare:
    を使用する必要があります。 リーリー

    返事
    0
  • キャンセル返事