2011-06-01 28 views
2

我已經擴展了PHP的mysqli類,它工作正常。但是,如何在查詢時讓它返回一個自定義結果對象(或者一個用於插入/更新/刪除等的布爾值)?擴展mysqli_result

namespace MyApp; 
class MySQLi extends \mysqli { 
    public function query($query, $resultmode = null) { 
     // This needs to return a MySQLiResult or a boolean 
    } 
} 
class MySQLiResult extends \mysqli_result { 
} 

這樣做我可以返回一個MySQLiResult對象,但我無法弄清楚如何返回非一個布爾值,選擇基於查詢:

public function query($query, $resultmode = null) { 
    $this->real_query($query); 
    return new MySQLiResult($this); 
} 

更新:

這是我最終使用的:

class MySQLi extends \mysqli { 

    public function query($query, $resultmode = null) { 
     $result = parent::query($query, $resultmode); 
     return is_bool($result) ? $result : new MySQLiResult($result); 
    } 

} 


class MySQLiResult { 

    private $result; 

    public function __construct(mysqli_result $result) { 
     $this->result = $result; 
    } 

    public function __call($name, $arguments) { 
     return call_user_func_array(array($this->result, $name), $arguments); 
    } 

    public function __set($name, $value) { 
     $this->result->$name = $value; 
    } 

    public function __get($name) { 
     return $this->result->$name; 
    } 

} 

回答

2

可能是最簡單的事情就是把你的MySQLiResult作爲mysqli_result的裝飾者來對待。例如,

class MySQLiResult 
{ 
    private $result; 

    public function __construct(\mysqli_result $result) 
    { 
     $this->result = $result; 
    } 
} 

然後,您可以將方法調用代理到內部結果並在需要時進行裝飾(添加功能)。

+0

真,我試圖避免這樣做,雖然。 – Petah 2011-06-01 01:49:27

+0

@Petah你仍然可以擴展'mysqli_result',但是如果沒有先得到一個正常的結果然後再適應它,我就無法看到返回你的類。 – Phil 2011-06-01 01:55:12

+0

那麼你可以,如果你使用'$ this-> real_query($ query);返回新的MySQLiResult($ this);'但是不會爲非基於選擇的查詢返回布爾值。 – Petah 2011-06-01 02:02:49

3

Phil的回答是可以的,但可以通過檢查mysqli::field_count來擴展MySQLi_Result。 結帳documentationmysqli::field_count

使用mysqli_store_result()函數時以確定是否應查詢已經產生了非空結果集與否不知道查詢的性質,此功能是有用的。

這正是我們所需要的。

public MySQL extends MySQLi 
{ 
    public function query($query) 
    { 
     if ($this->real_query($query)) { 
      if ($this->field_count > 0) { 
       return new MySQL_Result($this); 
      } 
      return true; 
     } 

     throw new MySQL_Exception($this->error, $this->errno); 
    } 
} 

現在你可以從MySQLi_Result延長你的結果類,並實現了一些有用的接口,如SeekableIterator這樣你就可以在你的結果集使用foreach

class MySQL_Result extends MySQLi_Result implements Countable, SeekableIterator, ArrayAccess 
{ 
    ... 
} 
+0

從PHP v5.4 + mysqli_result實現Traversable接口,所以人們已經能夠使用foreach循環語法(比如'foreach($ mysqli- > query($ SQL)as $ row){...}' – sbrbot 2016-07-29 09:56:44