扩展mysqli_result

时间:2011-06-01 01:38:28

标签: php oop mysqli

我扩展了PHP的mysqli类,它运行正常。但是如何在查询时让它返回自定义结果对象(或插入/更新/删除等的布尔值)?

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 个答案:

答案 0 :(得分:4)

菲尔的回答没问题,但可以通过检查mysqli::field_count来扩展MySQLi_Result。 查看mysqli::field_count的{​​{3}}

  

当使用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
{
    ...
}

答案 1 :(得分:2)

最简单的做法可能是将MySQLiResult课程视为mysqli_result的装饰师。例如

class MySQLiResult
{
    private $result;

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

然后,您可以将方法调用代理到内部结果,并在需要时进行装饰(添加功能)。