在面向对象的设置中有效地使用mysqli

时间:2013-09-03 16:44:21

标签: php performance oop mysqli

我得出的结论是,在OO方法中使用mysqli比使用程序方法更好。 (资料来源:Why is object oriented PHP with mysqli better than the procedural approach?)。但我不太确定我所做的事情是否真的比以前更有效率。

我有一个运行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类,我认为这意味着我正在建立另一个数据库连接。

那么我该如何正确有效地做到这一点?

3 个答案:

答案 0 :(得分:4)

  

那么我该如何正确有效地做到这一点?

这与在程序与OOP方式中使用MySQLi无关。

这与以下几行有关:

$con = connectDB();

这将在每个查询上重新创建数据库连接。正如你所指出的那样,效率不高。

有很多方法可以解决这个问题。例如:

  • 直接使用mysqli课程。
  • $con传递给executeQuery()Dependency Injection
  • 使用connectDB()executeQuery()创建一个数据库类。

我通常直接使用mysqli,因为我认为没有理由包装本机类。我在全局(在配置文件中)创建连接对象,并在其他对象/函数需要时使用依赖注入。

答案 1 :(得分:-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专业人员,但您可以查看my approach,至少使用封装来隐藏内部的所有脏工作,并提供简洁的方法来获取所需格式的数据,如下所示:

// 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); 

答案 2 :(得分:-2)

作为您确切问题的解决方案:“您不希望每次执行查询时都实例化新的MySQL连接”,

好吧,我们可以考虑以下几点:

您需要在GLOBAL范围内建立连接变量($ con),这样当通过任何函数访问时,您可以获取之前设置的THAT变量,而不是实例化新变量。

我们可以使用关键字“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);
}

在这个解决方案中我们使用了“reference”,所以表达式为:

$con = &connectDB();

将变量$ con设置为全局$ con的引用 /快捷方式(即:仅指向全局变量$ con)

第二个解决方案:

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

但是对于第二个解决方案:函数“connectDB()”必须在调用“executeQuery()”之前至少调用一次,以确保已经与数据库建立了连接,

请记住,根据此解决方案,多次调用“connectDB()”不会创建多个连接,一旦调用连接,就会创建连接,如果再次调用,它将返回PREVIOUSLY创建的连接。

希望有所帮助:)

顺便说一句:保持OOP方法进行数据库连接,它比程序方法有更多的好处, &安培;我建议使用PDO,它更便携。