0

オブジェクト指向アプローチで mysqli を使用することは、手続き型アプローチよりも優れているという結論に達しました。(出典: mysqli を使用したオブジェクト指向 PHP が手続き型アプローチよりも優れているのはなぜですか? )。しかし、私がやっていることが本当に以前よりも効率的であるかどうかはよくわかりません.

SQLクエリを実行する関数があります。これは私のコードブロックがどのように見えるかです:

データベース接続:

function connectDB(){
     $con = mysqli_connect(server, username, password, database);
     return $con;
}

クエリ機能:

function executeQuery($payload){
     $con = connectDB;
     $result = mysqli_query($con, $payload);
     return $result;
}

executeQueryご覧のとおり、が呼び出されるたびに新しいデータベース接続を作成しているため、これはあまり効率的ではありません。だから私はOOPを使って試してみることにしました。

データベース接続 (OOP):

function connectDB(){
     $con = new mysqli(server, username, password, database);
     return $con;
}

データベース クエリ (OOP):

function executeQuery($payload){
     $con = connectDB();
     $result = $con->query($payload);
     return $result;
}

今私には、明らかに何か間違ったことをしているように思えます。クエリが呼び出されるたびに、mysqliクラスを再インスタンス化しています。つまり、別のデータベース接続を作成していると思います。

では、これを適切かつ効率的に行うにはどうすればよいでしょうか。

4

3 に答える 3

4

では、これを適切かつ効率的に行うにはどうすればよいでしょうか。

これは、MySQLi を手続き型対 OOP の方法で使用することとはまったく関係ありません。

これに関係するのは、次の行です。

$con = connectDB();

これにより、すべてのクエリでデータベース接続が再作成されます。あなたが指摘したように、これは効率的ではありません。

これを解決するには多くの方法があります。例えば:

  • mysqliクラスを直接使用します。
  • 渡す(依存$con注入)executeQuery()
  • connectDB()と の両方でDB クラスを作成しますexecuteQuery()

mysqliネイティブ クラスをラップする理由がないので、通常は直接使用します。接続オブジェクトをグローバルに (構成ファイルで) 作成し、他のオブジェクト/関数が必要とするときに依存性注入を使用します。

于 2013-09-03T16:49:51.353 に答える
-1

あなたの手続き型アプローチはかなり簡単に解決できますが

function connectDB(){
     return mysqli_connect(server, username, password, database);
}
function executeQuery($payload){
    static $con;
    id (!$con)
    { 
        $con = connectDB();
    }
    return $con->query($payload);
}

OOPアプローチの方が確かに優れています。私は OOP の専門家ではありませんが、少なくともカプセル化を使用してすべてのダーティ ジョブを内部に隠し、次のような目的の形式のデータを取得するための簡潔な方法を提供する私のアプローチを見ることができます。

// to get a username
$name = $db->getOne('SELECT name FROM table WHERE id = ?i',$_GET['id']);
// to get an array of data
$data = $db->getAll("SELECT * FROM ?n WHERE mod=?s LIMIT ?i",$table,$mod,$limit);
// to get an array indexed by id field
$data = $db->getInd('id','SELECT * FROM ?n WHERE id IN ?a','table', array(1,2));
// to get a single dimensional array
$ids = $db->getCol("SELECT id FROM tags WHERE tagname = ?s",$tag);

// a simple code for the complex INSERT
$data = array('offers_in' => $in, 'offers_out' => $out);
$sql = "INSERT INTO stats SET pid=?i,dt=CURDATE(),?u ON DUPLICATE KEY UPDATE ?u";
$db->query($sql,$pid,$data,$data); 
于 2013-09-03T17:13:23.213 に答える
-2

正確な問題の解決策として:「クエリが実行されるたびに新しいMySQL接続をインスタンス化したくない」、

さて、次のことを考えることができます。

接続変数 ($con) を GLOBAL スコープで作成する必要があります。これにより、関数を介してアクセスしたときに、新しい変数をインスタンス化するのではなく、以前に設定したその変数を取得できるようになります。

次のように、キーワード "global" を使用してこれを行うことができます。


接続機能:

function &connectDB(){
     global $con;
     if(empty($con)) {
         $con = new mysqli(server, username, password, database);
     }
     return $con;
}

また、パフォーマンスを向上させるために、参照関数 ( &connectDB ) を使用して接続変数/リソースの複製/コピーを回避します。


クエリ実行機能

柔軟な方法で接続関数を設定したので、queryExecution 関数を設定するには、複数のソリューションを使用できます。

最初の解決策:

function executeQuery($payload){
     $con = &connectDB(); // do not forget the () , it's good practice
     return $con->query($payload);
}

このソリューションでは、「参照」を使用したため、式は次のようになります。

$con = &connectDB();

変数 $con をグローバル $con の参照/shortcut として設定します (つまり、グローバル変数 $con を指すだけです)。

また

2番目の解決策:

function executeQuery($payload){
     global $con;
     return $con->query($payload);
}

ただし、2 番目の解決策の場合: 関数 "connectDB()" は、"executeQuery()" を呼び出す前に少なくとも 1 回呼び出す必要があります。データベースとの接続が確立されていることを確認するために、

このソリューションによると、「connectDB()」を複数回呼び出しても複数の接続は作成されないことに注意してください。一度呼び出されると、接続が作成され、再度呼び出されると、以前に作成された接続が返されます。

それが役に立てば幸い :)

ちなみに、データベース接続にはOOPアプローチを使用してください。手続き型の方法よりもはるかに多くの利点があります。PDOを使用することをお勧めします。移植性がはるかに高くなります。

于 2013-09-03T17:11:52.550 に答える