2011-06-01 52 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