如何在while循环上有分支获取条件


How to have branching fetch conditions on while loop?

我有相同的大块代码while循环,其条件需要fetch_assoc()在MySqli连接上,但fetch()在PDO连接上。我想删除两次包含相同代码块的冗余。写成长格式,它的形状是:

if ($connection_type == 'mysqli')   
    while ($row = $resultObject->fetch_assoc()) {
        [big routine]
    }
} elseif ($connection_type == 'pdo') {
    while ($row = $resultObject->fetch()) { 
        [same big routine]
    }
}

我发现我可以,事实上,组合条件,但只是因为我目前只有2种连接可能性(MySqli和PDO),所以这不是理想的,如果-不知怎的-我希望在未来使用第三个连接条件:

while (($connection_type == 'mysqli') ? $row = $resultObject->fetch_assoc() : $row = $resultObject->fetch()) {
    [big routine]
}

有更有效的方法吗?这个解决方案是否存在不明显的缺陷?如果涉及超过2种不同的连接条件,该怎么办呢(显然,我在这里展望未来)

在我看来,处理这个问题最简单的方法是抽象掉两个api之间的差异。

例如:

<?php
interface DBResult {
    public function fetch();
}
class MysqliDbResult implements DBResult {
    private $stmt;
    public function __construct(mysqli_stmt $stmt){
        $this->stmt = $stmt;
    }
    public function fetch(){
        return $this->stmt->fetch_assoc();
    }
}
class PdoDbResult implements DBResult {
    private $stmt;
    public function __construct(PDOStatement $stmt){
        $this->stmt = $stmt;
    }
    public function fetch(){
        return $this->stmt->fetch('PDO::FETCH_ASSOC);
    }
}

当您从数据库连接实例化一个新类型的结果时,您可以将其包装在适当的DBResult实现中。

// is resultObject pdo or mysqli .... I don't care ...
while ($row = $resultObject->fetch()) { 
    [same big routine]
}

这听起来像是适配器模式的完美用例。您将创建一个具有fetch方法的类,该方法的作用类似于内部mysqli或PDO实例的适配器。您也可以一次性地对函数执行此操作。

function fetch($resultObject, $connection_type) {
    switch ($connection_type) {
        case 'mysqli':
            return $resultObject->fetch_assoc();
        case 'pdo':
            return $resultObject->fetch();
        case '....':
            //more cases
    }
}
while ($row = fetch($resultObject, $connection_type)) { 
    big_routine($row);
}