对于while循环,我有相同的大块代码,其条件需要MySqli连接上的fetch_assoc(),但PDO连接上需要fetch()。我想删除两次包含相同代码块的冗余。以长形式写出来,它采用了这种形式:
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种不同连接条件的案件呢(我明显地看着这里的道路。)
答案 0 :(得分:3)
在我的选择中,处理这个问题的最简单方法是抽象出两个apis之间的差异。
类似的东西:
<?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]
}
答案 1 :(得分:1)
这听起来像是Adapter Pattern的完美用例。您将创建一个具有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);
}