2013-02-23 98 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

相關問題