同じクエリを単純に繰り返すよりも、ステートメントを準備してから複数回実行する方がはるかに効率的であることを理解しています。
正しい。サーバー側の準備済みステートメント (mysqli が使用するもの) は、クエリ全体ではなく、後続の実行時にバインドされた引数のみをデータベースに送信するためです。また、データベース サーバーはクエリを再解析する必要はありませんが、準備されたクエリを再利用できます。したがって、これにより、データの取得に違いが生じる可能性があります。したがって、理論的には、これはより効率的です。
http://php.net/manual/en/mysqli.quickstart.prepared-statements.phpを参照してください。
実際には、それほど大きな違いは期待しないでください。それは確かに、これを呼び出して大きな違いを生むクエリの量と複雑さに依存します。迷ったらベンチマーク。
また、SQL インジェクションから保護するという追加の利点もあります。
以下のクラスは主キーでサウンドオブジェクトを取得します。このクラスの複数のインスタンスを同じスクリプトに含める必要がある場合、プリペアド ステートメントのメリットは得られますか?
いいえ。新しいインスタンスを作成してそのステートメントを準備するたびに、mysqli がサーバーにクエリを発行するためです。実行呼び出しに加えて。だからあなたは何も勝ちません。次のようなものを使用する方が簡単です
$query = sprintf('SELECT name, musickey FROM sounds WHERE id = %d', $id);
ID ごとに 1 つのインスタンスが本当に必要な場合は、それをクエリ全体として実行します。
準備済みステートメントでこれを行う場合は、1 回準備するが ID を複数回渡すことができる 1 つのインスタンスのみが必要です。
これはストアド プロシージャの良い候補でしょうか?
アプリケーション ロジックをストアド プロシージャに入れると、アプリケーションの移植性が低下します。ある時点でデータベース システムを変更したい場合は、ストアド プロシージャを再作成する必要があります。これについて情報に基づいた選択を行うのはあなた次第です。データベース システムを変更する必要がない場合は、実行可能かもしれません。ロジックをアプリケーション内に保持することを好みます。
オブジェクト指向の PHP も初めてです。
OOP の 1 つの側面は、クライアントからの情報(および複雑さ) をカプセル化して隠すことです。そのため、そこに公共の財産を持つことは最善の考えではありません。また、コンストラクターで作業を行うことは、コンストラクターの目的ではありません。コンストラクターは、オブジェクトを有効な状態にするだけです。そして、準備は必要になるまで延期したいクエリを実行するためです。
とはいえ、考えてみてください
interface FindById
{
public function findById($id);
}
class SoundFinder implements FindById
{
private $mysqli;
private $statement;
private $query = "SELECT name, musickey FROM sounds WHERE id = ?";
public function __construct(mysqli $mysqli)
{
$this->mysqli = $mysqli;
}
private function prepare()
{
$this->statement = $mysqli->prepare($this->query)
}
public function findById($id)
{
if (!$this->statement) {
$this->prepare();
}
$this->statement->bind_param("i", $this->id);
$this->statement->execute();
$this->statement->bind_result($name, $musickey);
$this->statement->free_result();
return array($name, $musickey);
}
}
次に、次のように使用できます。
$connection = new mysqli(/* your connection data */);
$soundFnder = new SoundFinder($connection);
$sound42 = $soundFinder->findById(42);
$sound314 = $soundFinder->findById(314);