2013-02-23 100 views
2

如何更改我的PDO包装类,以便如果我期望单行结果与我的查询它使用fetch(),并且如果它期望多个结果它使用fetchAll()。如何在PDO包装类中同时使用fetch()和fetchAll()?

现在,如果我只有一个结果,我仍然通过结果数组必须循环,并且似乎非常unpracticable给我。

查询模型:

public function doccEdit() { 

    $id = mysql_real_escape_string($_GET['id']); 

    $this->result = $GLOBALS['db']->select("creditcards", "id = ?", $id); 

    print_r($this->result); 

} 

在包装类:

public function run($sql, $bind="") { 
    $this->sql = trim($sql); 
    $this->bind = $this->cleanup($bind); 
    $this->error = ""; 

    try { 
     $pdostmt = $this->prepare($this->sql); 
     if($pdostmt->execute($this->bind) !== false) { 
      if(preg_match("/^(" . implode("|", array("select", "describe", "pragma")) . ") /i", $this->sql)) 
       return $pdostmt->fetchall(PDO::FETCH_OBJ); 
      elseif(preg_match("/^(" . implode("|", array("delete", "insert", "update")) . ") /i", $this->sql)) 
       return $pdostmt->rowCount(); 
     } 
    } catch (PDOException $e) { 
     $this->error = $e->getMessage();  
     $this->debug(); 
     return false; 
    } 
} 
+1

你为什么不只是总是使用fetchall()?如果只有一排,你会得到一个...... – Ben 2013-02-23 14:09:33

+0

因为我认为我可以避免循环。使用fetchall,即使只有一个结果,我也必须使用循环。 – 2013-02-23 14:15:50

+0

mysql_real_escape_string在这里做什么?你是否正确地格式化了“creditcards”? – 2013-02-23 14:32:13

回答

2

不要试图自动化一切

在你的代码魔术少,越容易支持和较少痛苦的麻烦。
不要试图将所有的逻辑加入到单一的方法中。这是一堂课!您可以根据需要创建尽可能多的方法。

当您需要rowCount() - 选择它明确!这并不难。
但是当你在几个月后偶然发现这个代码时,你会知道这个值是什么意思。

当您需要单列 - 用一个方法来获得一个单行。 当你需要很多行时 - 使用一种方法来获得很多行。
它很简单,非常明确!

当你2个月后转回到你的代码,你将有完全不知道,你是怎么预期。所以 - 总是写明确。

这里是我的mysqli wrapper class的摘录给你一个想法:

public function query() 
{ 
    return $this->rawQuery($this->prepareQuery(func_get_args())); 
} 
/** 
* Helper function to get scalar value right out of query and optional arguments 
* 
* Examples: 
* $name = $db->getOne("SELECT name FROM table WHERE id=1"); 
* $name = $db->getOne("SELECT name FROM table WHERE id=?i", $id); 
* 
* @param string $query - an SQL query with placeholders 
* @param mixed $arg,... unlimited number of arguments to match placeholders in the query 
* @return string|FALSE either first column of the first row of resultset or FALSE if none found 
*/ 
public function getOne() 
{ 
    $query = $this->prepareQuery(func_get_args()); 
    if ($res = $this->rawQuery($query)) 
    { 
     $row = $this->fetch($res); 
     if (is_array($row)) { 
      return reset($row); 
     } 
     $this->free($res); 
    } 
    return FALSE; 
} 

/** 
* Helper function to get single row right out of query and optional arguments 
* 
* Examples: 
* $data = $db->getRow("SELECT * FROM table WHERE id=1"); 
* $data = $db->getOne("SELECT * FROM table WHERE id=?i", $id); 
* 
* @param string $query - an SQL query with placeholders 
* @param mixed $arg,... unlimited number of arguments to match placeholders in the query 
* @return array|FALSE either associative array contains first row of resultset or FALSE if none found 
*/ 
public function getRow() 
{ 
    $query = $this->prepareQuery(func_get_args()); 
    if ($res = $this->rawQuery($query)) { 
     $ret = $this->fetch($res); 
     $this->free($res); 
     return $ret; 
    } 
    return FALSE; 
} 

/** 
* Helper function to get single column right out of query and optional arguments 
* 
* Examples: 
* $ids = $db->getCol("SELECT id FROM table WHERE cat=1"); 
* $ids = $db->getCol("SELECT id FROM tags WHERE tagname = ?s", $tag); 
* 
* @param string $query - an SQL query with placeholders 
* @param mixed $arg,... unlimited number of arguments to match placeholders in the query 
* @return array|FALSE either enumerated array of first fields of all rows of resultset or FALSE if none found 
*/ 
public function getCol() 
{ 
    $ret = array(); 
    $query = $this->prepareQuery(func_get_args()); 
    if ($res = $this->rawQuery($query)) 
    { 
     while($row = $this->fetch($res)) 
     { 
      $ret[] = reset($row); 
     } 
     $this->free($res); 
    } 
    return $ret; 
} 

/** 
* Helper function to get all the rows of resultset right out of query and optional arguments 
* 
* Examples: 
* $data = $db->getAll("SELECT * FROM table"); 
* $data = $db->getAll("SELECT * FROM table LIMIT ?i,?i", $start, $rows); 
* 
* @param string $query - an SQL query with placeholders 
* @param mixed $arg,... unlimited number of arguments to match placeholders in the query 
* @return array enumerated 2d array contains the resultset. Empty if no rows found. 
*/ 
public function getAll() 
{ 
    $ret = array(); 
    $query = $this->prepareQuery(func_get_args()); 
    if ($res = $this->rawQuery($query)) 
    { 
     while($row = $this->fetch($res)) 
     { 
      $ret[] = $row; 
     } 
     $this->free($res); 
    } 
    return $ret; 
} 

看 - 从功能名称,你可以随时告诉从而导致预期:

$name = $db->getOne('SELECT name FROM table WHERE id = ?i',$_GET['id']); 
$data = $db->getAll("SELECT * FROM ?n WHERE mod=?s LIMIT ?i",$table,$mod,$limit); 

不要被像返回的行数这样的陷阱愚弄。
在结果集中可能有一个诚实的一行,你打算用fetchAll填充。因此,它会返回一维数组,而不是多维的,你将有大量的视频效果您

-1

页既然你作为公认的没有标注答案。我想我会回答你的问题。我自己找到答案的同时也找到了答案。我同意“你的常识”,因为它们应该是两个独立的功能。然而,在直接回答你的问题,这是我(PDO例如,而不是库MySQLi):

function select($sql,$params=NULL,$fetchType=NULL){ 
    try{ 
     $qry = $this->db->prepare($sql); 
     $qry->execute($params); 
     if($qry->rowCount() > 1){ 
      if($fetchType == 'OBJ'){//returns object 
       $results = $qry->fetchAll(PDO::FETCH_OBJ); 
      }elseif($fetchType == 'NUM'){//-numerical array 
       $results = $qry->fetchAll(PDO::FETCH_NUM); 
      }else{//default - associative array 
       $results = $qry->fetchAll(PDO::FETCH_ASSOC); 
      } 
     } 
     else{ 
      if($fetchType == 'OBJ'){//returns object 
       $results = $qry->fetch(PDO::FETCH_OBJ); 
      }elseif($fetchType == 'NUM'){//-numerical array 
       $results = $qry->fetch(PDO::FETCH_NUM); 
      }else{//default - associative array 
       $results = $qry->fetch(PDO::FETCH_ASSOC); 
      } 
     } 

     if($results){ 
      return $results; 
     }else{ 
      return NULL; 
     } 
    } 
    catch(PDOException $err){ 
     $this->logError($err); 
    } 
} 

不过,我发现,如果我查询表中的所有行,但只有一个行的表它会返回一个1-d数组而不是2-d数组。我处理结果的代码不适用于这两种类型的数组。我可以每次处理,但是我发现如上所述,将它们分成不同的功能更容易,所以如果我知道只有一个答案,我可以称其为适当的功能。这是我现在有:

function select($sql,$params=NULL,$fetchType=NULL){ 
    try{ 
     $qry = $this->db->prepare($sql); 
     $qry->execute($params); 

     if($fetchType == 'OBJ'){//returns object 
      $results = $qry->fetch(PDO::FETCH_OBJ); 
     }elseif($fetchType == 'NUM'){//-numerical array 
      $results = $qry->fetch(PDO::FETCH_NUM); 
     }else{//default - associative array 
      $results = $qry->fetch(PDO::FETCH_ASSOC); 
     } 

     if($results){ 
      return $results; 
     }else{ 
      return NULL; 
     } 
    } 
    catch(PDOException $err){ 
     $this->logError($err); 
    } 
} 

function selectAll($sql,$params=NULL,$fetchType=NULL){ 
    try{ 
     $qry = $this->db->prepare($sql); 
     $qry->execute($params); 

     if($fetchType == 'OBJ'){//returns object 
      $results = $qry->fetchAll(PDO::FETCH_OBJ); 
     }elseif($fetchType == 'NUM'){//-numerical array 
      $results = $qry->fetchAll(PDO::FETCH_NUM); 
     }else{//default - associative array 
      $results = $qry->fetchAll(PDO::FETCH_ASSOC); 
     } 

     if($results){ 
      return $results; 
     }else{ 
      return NULL; 
     } 
    } 
    catch(PDOException $err){ 
     $this->logError($err); 
    } 
} 
+0

我只能忍受这么多重复的代码。你一定需要学习如何使用函数。 – 2013-09-06 19:40:52

+0

有没有办法将一个函数的名字保存在一个变量中? (用“fetchAll”交换“获取”)? – Joao 2013-10-03 14:08:59

+0

有没有一个理由去做 – 2013-10-03 14:28:09

相关问题