3 * Zend Framework (http://framework.zend.com/)
5 * @link http://github.com/zendframework/zf2 for the canonical source repository
6 * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
7 * @license http://framework.zend.com/license/new-bsd New BSD License
10 namespace Zend\Db\Adapter\Driver\Mysqli
;
13 use Zend\Db\Adapter\Driver\ResultInterface
;
14 use Zend\Db\Adapter\Exception
;
16 class Result
implements
22 * @var \mysqli|\mysqli_result|\mysqli_stmt
24 protected $resource = null;
29 protected $isBuffered = null;
35 protected $position = 0;
38 * Number of known rows
41 protected $numberOfRows = -1;
44 * Is the current() operation already complete for this pointer position?
47 protected $currentComplete = false;
52 protected $nextComplete = false;
57 protected $currentData = false;
63 protected $statementBindValues = array('keys' => null, 'values' => array());
68 protected $generatedValue = null;
73 * @param mixed $resource
74 * @param mixed $generatedValue
75 * @param bool|null $isBuffered
76 * @throws Exception\InvalidArgumentException
79 public function initialize($resource, $generatedValue, $isBuffered = null)
81 if (!$resource instanceof \mysqli
&& !$resource instanceof \mysqli_result
&& !$resource instanceof \mysqli_stmt
) {
82 throw new Exception\
InvalidArgumentException('Invalid resource provided.');
85 if ($isBuffered !== null) {
86 $this->isBuffered
= $isBuffered;
88 if ($resource instanceof \mysqli ||
$resource instanceof \mysqli_result
89 ||
$resource instanceof \mysqli_stmt
&& $resource->num_rows
!= 0) {
90 $this->isBuffered
= true;
94 $this->resource = $resource;
95 $this->generatedValue
= $generatedValue;
102 * @throws Exception\RuntimeException
104 public function buffer()
106 if ($this->resource instanceof \mysqli_stmt
&& $this->isBuffered
!== true) {
107 if ($this->position
> 0) {
108 throw new Exception\
RuntimeException('Cannot buffer a result set that has started iteration.');
110 $this->resource->store_result();
111 $this->isBuffered
= true;
116 * Check if is buffered
120 public function isBuffered()
122 return $this->isBuffered
;
126 * Return the resource
130 public function getResource()
132 return $this->resource;
140 public function isQueryResult()
142 return ($this->resource->field_count
> 0);
150 public function getAffectedRows()
152 if ($this->resource instanceof \mysqli ||
$this->resource instanceof \mysqli_stmt
) {
153 return $this->resource->affected_rows
;
156 return $this->resource->num_rows
;
164 public function current()
166 if ($this->currentComplete
) {
167 return $this->currentData
;
170 if ($this->resource instanceof \mysqli_stmt
) {
171 $this->loadDataFromMysqliStatement();
172 return $this->currentData
;
174 $this->loadFromMysqliResult();
175 return $this->currentData
;
180 * Mysqli's binding and returning of statement values
182 * Mysqli requires you to bind variables to the extension in order to
183 * get data out. These values have to be references:
184 * @see http://php.net/manual/en/mysqli-stmt.bind-result.php
186 * @throws Exception\RuntimeException
189 protected function loadDataFromMysqliStatement()
192 // build the default reference based bind structure, if it does not already exist
193 if ($this->statementBindValues
['keys'] === null) {
194 $this->statementBindValues
['keys'] = array();
195 $resultResource = $this->resource->result_metadata();
196 foreach ($resultResource->fetch_fields() as $col) {
197 $this->statementBindValues
['keys'][] = $col->name
;
199 $this->statementBindValues
['values'] = array_fill(0, count($this->statementBindValues
['keys']), null);
201 foreach ($this->statementBindValues
['values'] as $i => &$f) {
204 call_user_func_array(array($this->resource, 'bind_result'), $this->statementBindValues
['values']);
207 if (($r = $this->resource->fetch()) === null) {
208 if (!$this->isBuffered
) {
209 $this->resource->close();
212 } elseif ($r === false) {
213 throw new Exception\
RuntimeException($this->resource->error
);
217 for ($i = 0, $count = count($this->statementBindValues
['keys']); $i < $count; $i++
) {
218 $this->currentData
[$this->statementBindValues
['keys'][$i]] = $this->statementBindValues
['values'][$i];
220 $this->currentComplete
= true;
221 $this->nextComplete
= true;
227 * Load from mysqli result
231 protected function loadFromMysqliResult()
233 $this->currentData
= null;
235 if (($data = $this->resource->fetch_assoc()) === null) {
240 $this->currentData
= $data;
241 $this->currentComplete
= true;
242 $this->nextComplete
= true;
252 public function next()
254 $this->currentComplete
= false;
256 if ($this->nextComplete
== false) {
260 $this->nextComplete
= false;
268 public function key()
270 return $this->position
;
276 * @throws Exception\RuntimeException
279 public function rewind()
281 if ($this->position
!== 0) {
282 if ($this->isBuffered
=== false) {
283 throw new Exception\
RuntimeException('Unbuffered results cannot be rewound for multiple iterations');
286 $this->resource->data_seek(0); // works for both mysqli_result & mysqli_stmt
287 $this->currentComplete
= false;
296 public function valid()
298 if ($this->currentComplete
) {
302 if ($this->resource instanceof \mysqli_stmt
) {
303 return $this->loadDataFromMysqliStatement();
306 return $this->loadFromMysqliResult();
312 * @throws Exception\RuntimeException
315 public function count()
317 if ($this->isBuffered
=== false) {
318 throw new Exception\
RuntimeException('Row count is not available in unbuffered result sets.');
320 return $this->resource->num_rows
;
328 public function getFieldCount()
330 return $this->resource->field_count
;
334 * Get generated value
338 public function getGeneratedValue()
340 return $this->generatedValue
;