MySQLi

MySQLi拡張機能MySQL改良版)は、PHPスクリプト言語で使用されるリレーショナルデータベースドライバであり、MySQLプロトコル互換データベースMariaDBMySQLPercona ServerTiDB )とのインターフェースを提供します[1] [2]

MySQLデータベース サーバーへの接続を検討する場合、主に 3 つのAPIオプションがあります

  • PHPのMySQL拡張機能
  • PHPのMySQLi拡張機能
  • PHP データオブジェクト (PDO)

PHPコードはコアと、コア機能に対するオプションの拡張機能で構成されています。MySQLi拡張機能やMySQL拡張機能など、PHPのMySQL関連の拡張機能は、PHP拡張フレームワークを使用して実装されています。拡張機能は通常、PHP開発者にAPIを公開し、その機能をプログラムから使用できるようにします。ただし、PHP拡張フレームワークを使用する拡張機能の中には、PHP開発者にAPIを公開しないものもあります。

たとえば、PDO MySQL ドライバ拡張機能は、PHP 開発者に API を公開しませんが、その上位の PDO レイヤーへのインターフェイスを提供します。

MySQLiは古いPHP MySQLドライバの改良版であり、さまざまな利点を提供します。[3]

PHPスクリプト言語の作者は、MySQLサーバーバージョン4.1.3以降を扱う場合はMySQLiを使用することを推奨しています(新しい機能を活用できます)。[3]

技術的な詳細

MySQLi拡張機能は、その前身に比べてさまざまな利点を提供しますが、その中で最も顕著なものは次のとおりです(PHP Webサイト[3]によると)。

  • オブジェクト指向インターフェース
  • 準備済みステートメントのサポート
  • 複数のステートメントのサポート
  • トランザクションのサポート
  • 強化されたデバッグサポート

機能の比較[3]

PHPのMySQLi拡張機能PDOPHPのMySQL拡張機能
PHPバージョン導入5.05.03.0以前
PHP 5.x に含まれていますはいはいはい
PHP 7.x に含まれていますはいはいいいえ
開発状況積極的な開発PHP 5.3 から活発に開発中PHP 5.5 以降は非推奨
PHP 7.0 で削除
新しいプロジェクトにMySQLが推奨はい - 推奨オプションはいいいえ
APIは文字セットをサポートはいはいいいえ
APIはサーバー側の準備済みステートメントをサポートしますはいはいいいえ
APIはクライアント側の準備済みステートメントをサポートしますいいえはいいいえ
APIはストアドプロシージャをサポートはいはいいいえ
APIは複数のステートメントをサポートしますはいほとんどいいえ
MySQL 4.1+ のすべての機能をサポートはいほとんどいいえ

スタートガイド[4]

デュアルインターフェース

MySQLi 拡張機能はデュアルインターフェースを備えており、手続き型プログラミングパラダイムとオブジェクト指向プログラミングパラダイムの両方をサポートします。

旧MySQL拡張機能から移行するユーザーは、手続き型インターフェースを好むかもしれません。手続き型インターフェースは旧MySQL拡張機能のインターフェースと似ています。多くの場合、関数名は接頭辞のみで異なります。一部のMySQLi関数は接続ハンドルを最初の引数として受け取りますが、旧MySQLインターフェースの対応する関数では、接続ハンドルをオプションの最後の引数として受け取ります。

新しいネイティブ関数呼び出しと古いネイティブ関数呼び出し

<?php $mysqli  =  mysqli_connect ( "example.com"  "user"  "password"  "database" ); $result  =  mysqli_query ( $mysqli  "SELECT * FROM myDatabase" ); echo  mysqli_num_rows ( $result );$mysql  =  mysql_connect ( "example.com"  "user"  "password" ); mysql_select_db ( "database" ); $result  =  mysql_query ( "SELECT * FROM myDatabase"  $mysql ); echo  mysql_num_rows ( $result ); ?>

接続

MySQLサーバーは、接続に複数のトランスポート層の使用をサポートしています。接続にはTCP/IP、Unixドメインソケット、またはWindows名前付きパイプが使用されます。

ホスト名にlocalhostは特別な意味があります。これはUnixドメインソケットの使用に結び付けられています。ホスト名を使用してTCP/IP接続を開くことはできません。代わりに ホスト名localhostを使用する必要があります。127.0.0.1

例: localhostの特別な意味

<?php $mysqli  =  new  mysqli ( "localhost" ,  "user" ,  "password" ,  "database" ); if  ( $mysqli -> connect_errno )  {  echo  "MySQL への接続に失敗しました: ("  .  $mysqli -> connect_errno  .  ") "  .  $mysqli -> connect_error ; } echo  $mysqli -> host_info  .  " \n " ;$mysqli  =  new  mysqli ( "127.0.0.1" ,  "user" ,  "password" ,  "database" ,  3306 ); if  ( $mysqli -> connect_errno )  {  echo  "MySQLへの接続に失敗しました: ("  .  $mysqli -> connect_errno  .  ") "  .  $mysqli -> connect_error ; }echo  $mysqli -> host_info  .  " \n " ; ?>

出力

UNIXソケット経由のローカルホスト127.0.0.1(TCP/IP経由)

ステートメントの実行

ステートメントは、mysqli_query()、mysqli_real_query()、およびmysqli_multi_query()関数を使用して実行できます。mysqli_query()関数は最もよく使用され、実行中のステートメントと、その結果セット(存在する場合)のバッファリングされた取得を1回の呼び出しで組み合わせます。mysqli_query()の呼び出しは、mysqli_real_query()に続けてmysqli_store_result()を呼び出すのと同じです。

例: MySQLへの接続

<?php $mysqli  =  new  mysqli ( "example.com" ,  "user" ,  "password" ,  "database" ); if  ( $mysqli -> connect_errno )  {  echo  "MySQL への接続に失敗しました: ("  .  $mysqli -> connect_errno  .  ") "  .  $mysqli -> connect_error ; }if  ( ! $mysqli -> query ( "DROP TABLE IF EXISTS test" )  ||  ! $mysqli -> query ( "CREATE TABLE test(id INT)" )  ||  ! $mysqli -> query ( "INSERT INTO test(id) VALUES (1)" ))  {  echo  "テーブルの作成に失敗しました: ("  .  $mysqli -> errno  .  ") "  .  $mysqli -> error ; } ?>

バッファリングされた結果セット

ステートメント実行後の結果は、クライアント側でバッファリングするために一度に取得することも、行ごとに読み取ることもできます。クライアント側の結果セットのバッファリングにより、サーバーはステートメント結果に関連付けられたリソースを可能な限り早く解放できます。一般的に、クライアントは結果セットの消費に時間がかかります。そのため、バッファリングされた結果セットを使用することをお勧めします。mysqli_query() は、ステートメント実行と結果セットのバッファリングを組み合わせています。

PHPアプリケーションは、バッファリングされた結果を自由にナビゲートできます。結果セットはクライアントのメモリに保持されるため、ナビゲーションは高速です。ただし、サーバーをスケールさせるよりも、クライアントをスケールさせる方が簡単な場合が多いことにご注意ください。

例: バッファリングされた結果のナビゲーション

<?php $mysqli  =  new  mysqli ( "example.com" ,  "user" ,  "password" ,  "database" ); if  ( $mysqli -> connect_errno )  {  echo  "MySQL への接続に失敗しました: ("  .  $mysqli -> connect_errno  .  ") "  .  $mysqli -> connect_error ; }if  ( ! $mysqli -> query ( "DROP TABLE IF EXISTS test" )  ||  ! $mysqli -> query ( "CREATE TABLE test(id INT)" )  ||  ! $mysqli -> query ( "INSERT INTO test(id) VALUES (1), (2), (3)" ))  {  echo  "テーブルの作成に失敗しました: ("  .  $mysqli -> errno  .  ") "  .  $mysqli -> error ; }$res  =  $mysqli ->クエリ( "SELECT id FROM test ORDER BY id ASC" );echo  "逆順... \n " ; for  ( $row_no  =  $res -> num_rows  -  1 ;  $row_no  >=  0 ;  $row_no -- )  {  $res -> data_seek ( $row_no );  $row  =  $res -> fetch_assoc ();  echo  " id = "  .  $row [ 'id' ]  .  " \n " ; }echo  "結果セットの順序... \n " ; $res -> data_seek ( 0 ); while  ( $row  =  $res -> fetch_assoc ())  {  echo  " id = "  .  $row [ 'id' ]  .  " \n " ; } ?>

上記の例では次のように出力されます:

逆順... id = 3 id = 2 id = 1結果セットの順序... id = 1 id = 2 id = 3

バッファリングされていない結果セット

クライアントメモリのリソースが不足しており、サーバーの負荷を低く抑えるためにサーバーのリソースをできるだけ早く解放する必要がない場合は、バッファリングされていない結果を使用できます。すべての行が読み込まれるまで、バッファリングされていない結果をスクロールすることはできません。

例: バッファリングされていない結果のナビゲーション

<?php $mysqli -> real_query ( "SELECT id FROM test ORDER BY id ASC" ); $res  =  $mysqli -> use_result ();echo  "結果セットの順序... \n " ; while  ( $row  =  $res -> fetch_assoc ())  {  echo  " id = "  .  $row [ 'id' ]  .  " \n " ; } ?>

結果セット値のデータ型

mysqli_query()、mysqli_real_query()、およびmysqli_multi_query()関数は、準備されていないステートメントを実行するために使用されます。MySQLクライアント・サーバー・プロトコルレベルでは、COM_QUERYコマンドとテキストプロトコルがステートメントの実行に使用されます。テキストプロトコルでは、MySQLサーバーは結果セットのすべてのデータを送信前に文字列に変換します。この変換は、SQL結果セットの列のデータ型に関係なく行われます。MySQLクライアントライブラリは、すべての列の値を文字列として受け取ります。列をネイティブ型に戻すためのクライアント側でのキャストは行われません。代わりに、すべての値はPHP文字列として提供されます。

例: テキストプロトコルはデフォルトで文字列を返します

<?php $mysqli  =  new  mysqli ( "example.com" ,  "user" ,  "password" ,  "database" ); if  ( $mysqli -> connect_errno )  {  echo  "MySQL への接続に失敗しました: ("  .  $mysqli -> connect_errno  .  ") "  .  $mysqli -> connect_error ; }if  ( ! $mysqli -> query ( "DROP TABLE IF EXISTS test" )  ||  ! $mysqli -> query ( "CREATE TABLE test(id INT, label CHAR(1))" )  ||  ! $mysqli -> query ( "INSERT INTO test(id, label) VALUES (1, 'a')" ))  {  echo  "テーブルの作成に失敗しました: ("  .  $mysqli -> errno  .  ") "  .  $mysqli -> error ; }$res  =  $mysqli -> query ( "SELECT id, label FROM test WHERE id = 1" ); $row  =  $res -> fetch_assoc ();printf ( "id = %s (%s) \n " ,  $row [ 'id' ],  gettype ( $row [ 'id' ])); printf ( "label = %s (%s) \n " ,  $row [ 'label' ],  gettype ( $row [ 'label' ])); ?>

上記の例では次のように出力されます:

id = 1 (文字列)ラベル = a (文字列)

mysqlndライブラリを使用している場合、MYSQLI_OPT_INT_AND_FLOAT_NATIVE接続オプションを設定することで、整数型および浮動小数点型の列をPHPの数値型に戻すことができます。設定されている場合、mysqlndライブラリは結果セットのメタデータ列の型をチェックし、PHPのデータ型の値の範囲が許す限り、数値型のSQL列をPHPの数値型に変換します。これにより、例えばSQLのINT型列は整数型として返されます。

例: mysqlndと接続オプションを使用したネイティブデータ型

<?php $mysqli  =  mysqli_init (); $mysqli -> options ( MYSQLI_OPT_INT_AND_FLOAT_NATIVE  1 ); $mysqli -> real_connect ( "example.com"  "user"  "password"  "database" );if  ( $mysqli -> connect_errno )  {  echo  "MySQLへの接続に失敗しました: ("  .  $mysqli -> connect_errno  .  ") "  .  $mysqli -> connect_error ; }if  ( ! $mysqli -> query ( "DROP TABLE IF EXISTS test" )  ||  ! $mysqli -> query ( "CREATE TABLE test(id INT, label CHAR(1))" )  ||  ! $mysqli -> query ( "INSERT INTO test(id, label) VALUES (1, 'a')" ))  {  echo  "テーブルの作成に失敗しました: ("  .  $mysqli -> errno  .  ") "  .  $mysqli -> error ; }$res  =  $mysqli -> query ( "SELECT id, label FROM test WHERE id = 1" ); $row  =  $res -> fetch_assoc ();printf ( "id = %s (%s) \n " ,  $row [ 'id' ],  gettype ( $row [ 'id' ])); printf ( "label = %s (%s) \n " ,  $row [ 'label' ],  gettype ( $row [ 'label' ])); ?>

上記の例では次のように出力されます:

id = 1 (整数)ラベル = a (文字列)

準備された声明

MySQLデータベースは、プリペアドステートメントをサポートしています。プリペアドステートメントまたはパラメータ化されたステートメントは、同じステートメントを高い効率で繰り返し実行するために使用されます。

基本的なワークフロー

準備済みステートメントの実行は、準備と実行の2つの段階で構成されます。準備段階では、ステートメントテンプレートがデータベースサーバーに送信されます。サーバーは構文チェックを実行し、後で使用するためにサーバー内部のリソースを初期化します。

MySQL サーバーは、? を使用した匿名の位置プレースホルダーの使用をサポートしています。

[5]の例を参照。

ストアドプロシージャ[6]

MySQLデータベースはストアドプロシージャをサポートしています。ストアドプロシージャは、データベースカタログに格納されるサブルーチンです。アプリケーションはストアドプロシージャを呼び出して実行できます。ストアドプロシージャを実行するには、CALL SQL文を使用します。

パラメータ

ストアドプロシージャは、MySQLのバージョンに応じて、IN、INOUT、OUTパラメータを持つことができます。MySQLiインターフェースでは、これらのパラメータの種類について特別な概念はありません。

INパラメータ

CALLステートメントには入力パラメータが指定されています。値が正しくエスケープされていることを確認してください。

[6]の例を参照。

複数のステートメント[7]

MySQLでは、1つのステートメント文字列に複数のステートメントを含めるオプションがあります。複数のステートメントを一度に送信すると、クライアントとサーバー間のラウンドトリップが削減されますが、特別な処理が必要になります。

複数のステートメントまたは複数のクエリは、mysqli_multi_query() で実行する必要があります。ステートメント文字列の各ステートメントはセミコロンで区切られます。その後、実行されたステートメントによって返されるすべての結果セットを取得する必要があります。

MySQL サーバーでは、結果セットを返すステートメントと結果セットを返さないステートメントを 1 つの複数のステートメントに含めることができます。

[7]の例を参照

トランザクションのAPIサポート[8]

MySQLサーバーは、使用するストレージエンジンに応じてトランザクションをサポートします。MySQL 5.5以降、デフォルトのストレージエンジンはInnoDBです。InnoDBは完全なACIDトランザクションをサポートしています。

トランザクションはSQLまたはAPI呼び出しを使用して制御できます。自動コミットモードの有効化と無効化、およびトランザクションのコミットとロールバックには、API呼び出しを使用することをお勧めします。

例はこちら。[8]

メタデータ[9]

MySQLの結果セットにはメタデータが含まれます。メタデータは、結果セットに含まれる列を記述します。MySQLから送信されるすべてのメタデータは、MySQLiインターフェースを介してアクセスできます。この拡張機能は、受信した情報に一切変更を加えないか、ごくわずかな変更しか加えません。MySQLサーバーのバージョン間の差異は一致していません。

メタデータは、mysqli_result インターフェイスを介してアクセスされます。

詳細はこちらをご覧ください。[9]

MySQLi拡張機能と永続的な接続[3]

持続接続のサポートは、PHP 5.3 で MySQLi 拡張モジュールに導入されました。PDO MYSQL と ext/mysql では既にサポートされていました。持続接続の背後にある考え方は、クライアントプロセスとデータベース間の接続を、クライアントプロセスが何度も作成・破棄するのではなく、再利用できるようにすることです。これにより、未使用の接続はキャッシュされ、再利用の準備が整うため、必要なたびに新しい接続を作成するオーバーヘッドが削減されます。

MySQL拡張機能とは異なり、MySQLiには持続的な接続を開くための個別の関数は用意されていません。持続的な接続を開くには、接続時にホスト名の先頭に「p:」を付加する必要があります。

持続的接続の問題は、クライアントが予測できない状態のままにしておく可能性があることです。例えば、クライアントが予期せず終了する前にテーブルロックが有効化される可能性があります。この持続的接続を再利用する新しいクライアントプロセスは、接続を「そのまま」取得します。新しいクライアントプロセスが持続的接続を有効活用するには、クリーンアップ作業が必要となり、プログラマの負担が増加します。

MySQLi拡張機能の永続接続には、クリーンアップ処理コードが組み込まれています。MySQLiによって実行されるクリーンアップには、以下の処理が含まれます。

  • アクティブなトランザクションをロールバックする
  • 一時テーブルを閉じて削除する
  • テーブルのロックを解除
  • セッション変数をリセットする
  • 準備されたステートメントを閉じる(PHP では常に発生します)
  • ハンドラーを閉じる
  • GET_LOCK() で取得したロックを解除する

これにより、クライアント プロセスが永続的な接続を使用する前に、接続プールから返されたときに永続的な接続がクリーンな状態になることが保証されます。

MySQLi 拡張機能は、C-API 関数 mysql_change_user() を自動的に呼び出すことによってこのクリーンアップを実行します。

自動クリーンアップ機能にはメリットとデメリットがあります。メリットは、クリーンアップコードが自動的に呼び出されるため、開発者がクリーンアップコードの追加を気にする必要がなくなることです。しかし、デメリットは、クリーンアップを実行するコードは接続プールから接続が返されるたびに実行されるため、コードの実行速度が若干低下する可能性があることです。

MYSQLI_NO_CHANGE_USER_ON_PCONNECT を定義して PHP をコンパイルすることにより、自動クリーンアップ コードをオフにすることができます。

注記:MySQLi 拡張機能は、MySQL ネイティブ ドライバーまたは MySQL クライアント ライブラリのいずれかを使用するときに永続的な接続をサポートします。

参考文献

  1. ^ 「PHP: 入門 - マニュアル」www.php.net . 2024年8月6日閲覧
  2. ^ 「PHP用MySQL/MariaDB/Perconaへの接続」Virtuozzo . 2023年11月22日閲覧
  3. ^ abcde 「概要 - マニュアル」. PHP . 2014年8月11日閲覧
  4. ^ 「PHP: クイックスタートガイド - マニュアル」In2.php.net . 2014年8月11日閲覧
  5. ^ 「PHP: 準備済みステートメント - マニュアル」In2.php.net . 2014年8月11日閲覧
  6. ^ ab Jonathon (2013年5月24日). 「PHP: ストアドプロシージャ - マニュアル」. In2.php.net . 2014年8月11日閲覧
  7. ^ ab eric dot noel at gmail dot com (2014年3月31日). 「PHP: 複数ステートメント - マニュアル」. In2.php.net . 2014年8月11日閲覧
  8. ^ ab 「PHP: トランザクションのAPIサポート - マニュアル」In2.php.net . 2014年8月11日閲覧
  9. ^ ab "PHP: メタデータ - マニュアル". In2.php.net . 2014年8月11日閲覧

さらに読む

  • MySQLi 準備済みステートメントのチュートリアル
  • PHP.net の MySQLi ドキュメント
  • MySQLiでMySQL拡張機能をエミュレートする
Retrieved from "https://en.wikipedia.org/w/index.php?title=MySQLi&oldid=1309548021"