File indexing completed on 2025-01-19 05:21:02
0001 <?php 0002 /** 0003 * Zend Framework 0004 * 0005 * LICENSE 0006 * 0007 * This source file is subject to the new BSD license that is bundled 0008 * with this package in the file LICENSE.txt. 0009 * It is also available through the world-wide-web at this URL: 0010 * http://framework.zend.com/license/new-bsd 0011 * If you did not receive a copy of the license and are unable to 0012 * obtain it through the world-wide-web, please send an email 0013 * to license@zend.com so we can send you a copy immediately. 0014 * 0015 * @category Zend 0016 * @package Zend_Db 0017 * @subpackage Statement 0018 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0019 * @license http://framework.zend.com/license/new-bsd New BSD License 0020 * @version $Id$ 0021 */ 0022 0023 0024 /** 0025 * @see Zend_Db_Statement 0026 */ 0027 // require_once 'Zend/Db/Statement.php'; 0028 0029 0030 /** 0031 * Extends for Mysqli 0032 * 0033 * @category Zend 0034 * @package Zend_Db 0035 * @subpackage Statement 0036 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0037 * @license http://framework.zend.com/license/new-bsd New BSD License 0038 */ 0039 class Zend_Db_Statement_Mysqli extends Zend_Db_Statement 0040 { 0041 0042 /** 0043 * Column names. 0044 * 0045 * @var array 0046 */ 0047 protected $_keys; 0048 0049 /** 0050 * Fetched result values. 0051 * 0052 * @var array 0053 */ 0054 protected $_values; 0055 0056 /** 0057 * @var array 0058 */ 0059 protected $_meta = null; 0060 0061 /** 0062 * @param string $sql 0063 * @return void 0064 * @throws Zend_Db_Statement_Mysqli_Exception 0065 */ 0066 public function _prepare($sql) 0067 { 0068 $mysqli = $this->_adapter->getConnection(); 0069 0070 $this->_stmt = $mysqli->prepare($sql); 0071 0072 if ($this->_stmt === false || $mysqli->errno) { 0073 /** 0074 * @see Zend_Db_Statement_Mysqli_Exception 0075 */ 0076 // require_once 'Zend/Db/Statement/Mysqli/Exception.php'; 0077 throw new Zend_Db_Statement_Mysqli_Exception("Mysqli prepare error: " . $mysqli->error, $mysqli->errno); 0078 } 0079 } 0080 0081 /** 0082 * Binds a parameter to the specified variable name. 0083 * 0084 * @param mixed $parameter Name the parameter, either integer or string. 0085 * @param mixed $variable Reference to PHP variable containing the value. 0086 * @param mixed $type OPTIONAL Datatype of SQL parameter. 0087 * @param mixed $length OPTIONAL Length of SQL parameter. 0088 * @param mixed $options OPTIONAL Other options. 0089 * @return bool 0090 * @throws Zend_Db_Statement_Mysqli_Exception 0091 */ 0092 protected function _bindParam($parameter, &$variable, $type = null, $length = null, $options = null) 0093 { 0094 return true; 0095 } 0096 0097 /** 0098 * Closes the cursor and the statement. 0099 * 0100 * @return bool 0101 */ 0102 public function close() 0103 { 0104 if ($this->_stmt) { 0105 $r = $this->_stmt->close(); 0106 $this->_stmt = null; 0107 return $r; 0108 } 0109 return false; 0110 } 0111 0112 /** 0113 * Closes the cursor, allowing the statement to be executed again. 0114 * 0115 * @return bool 0116 */ 0117 public function closeCursor() 0118 { 0119 if ($stmt = $this->_stmt) { 0120 $mysqli = $this->_adapter->getConnection(); 0121 while ($mysqli->more_results()) { 0122 $mysqli->next_result(); 0123 } 0124 $this->_stmt->free_result(); 0125 return $this->_stmt->reset(); 0126 } 0127 return false; 0128 } 0129 0130 /** 0131 * Returns the number of columns in the result set. 0132 * Returns null if the statement has no result set metadata. 0133 * 0134 * @return int The number of columns. 0135 */ 0136 public function columnCount() 0137 { 0138 if (isset($this->_meta) && $this->_meta) { 0139 return $this->_meta->field_count; 0140 } 0141 return 0; 0142 } 0143 0144 /** 0145 * Retrieves the error code, if any, associated with the last operation on 0146 * the statement handle. 0147 * 0148 * @return string error code. 0149 */ 0150 public function errorCode() 0151 { 0152 if (!$this->_stmt) { 0153 return false; 0154 } 0155 return substr($this->_stmt->sqlstate, 0, 5); 0156 } 0157 0158 /** 0159 * Retrieves an array of error information, if any, associated with the 0160 * last operation on the statement handle. 0161 * 0162 * @return array 0163 */ 0164 public function errorInfo() 0165 { 0166 if (!$this->_stmt) { 0167 return false; 0168 } 0169 return array( 0170 substr($this->_stmt->sqlstate, 0, 5), 0171 $this->_stmt->errno, 0172 $this->_stmt->error, 0173 ); 0174 } 0175 0176 /** 0177 * Executes a prepared statement. 0178 * 0179 * @param array $params OPTIONAL Values to bind to parameter placeholders. 0180 * @return bool 0181 * @throws Zend_Db_Statement_Mysqli_Exception 0182 */ 0183 public function _execute(array $params = null) 0184 { 0185 if (!$this->_stmt) { 0186 return false; 0187 } 0188 0189 // if no params were given as an argument to execute(), 0190 // then default to the _bindParam array 0191 if ($params === null) { 0192 $params = $this->_bindParam; 0193 } 0194 // send $params as input parameters to the statement 0195 if ($params) { 0196 array_unshift($params, str_repeat('s', count($params))); 0197 $stmtParams = array(); 0198 foreach ($params as $k => &$value) { 0199 $stmtParams[$k] = &$value; 0200 } 0201 call_user_func_array( 0202 array($this->_stmt, 'bind_param'), 0203 $stmtParams 0204 ); 0205 } 0206 0207 // execute the statement 0208 $retval = $this->_stmt->execute(); 0209 if ($retval === false) { 0210 /** 0211 * @see Zend_Db_Statement_Mysqli_Exception 0212 */ 0213 // require_once 'Zend/Db/Statement/Mysqli/Exception.php'; 0214 throw new Zend_Db_Statement_Mysqli_Exception("Mysqli statement execute error : " . $this->_stmt->error, $this->_stmt->errno); 0215 } 0216 0217 0218 // retain metadata 0219 if ($this->_meta === null) { 0220 $this->_meta = $this->_stmt->result_metadata(); 0221 if ($this->_stmt->errno) { 0222 /** 0223 * @see Zend_Db_Statement_Mysqli_Exception 0224 */ 0225 // require_once 'Zend/Db/Statement/Mysqli/Exception.php'; 0226 throw new Zend_Db_Statement_Mysqli_Exception("Mysqli statement metadata error: " . $this->_stmt->error, $this->_stmt->errno); 0227 } 0228 } 0229 0230 // statements that have no result set do not return metadata 0231 if ($this->_meta !== false) { 0232 0233 // get the column names that will result 0234 $this->_keys = array(); 0235 foreach ($this->_meta->fetch_fields() as $col) { 0236 $this->_keys[] = $this->_adapter->foldCase($col->name); 0237 } 0238 0239 // set up a binding space for result variables 0240 $this->_values = array_fill(0, count($this->_keys), null); 0241 0242 // set up references to the result binding space. 0243 // just passing $this->_values in the call_user_func_array() 0244 // below won't work, you need references. 0245 $refs = array(); 0246 foreach ($this->_values as $i => &$f) { 0247 $refs[$i] = &$f; 0248 } 0249 0250 $this->_stmt->store_result(); 0251 // bind to the result variables 0252 call_user_func_array( 0253 array($this->_stmt, 'bind_result'), 0254 $this->_values 0255 ); 0256 } 0257 return $retval; 0258 } 0259 0260 0261 /** 0262 * Fetches a row from the result set. 0263 * 0264 * @param int $style OPTIONAL Fetch mode for this fetch operation. 0265 * @param int $cursor OPTIONAL Absolute, relative, or other. 0266 * @param int $offset OPTIONAL Number for absolute or relative cursors. 0267 * @return mixed Array, object, or scalar depending on fetch mode. 0268 * @throws Zend_Db_Statement_Mysqli_Exception 0269 */ 0270 public function fetch($style = null, $cursor = null, $offset = null) 0271 { 0272 if (!$this->_stmt) { 0273 return false; 0274 } 0275 // fetch the next result 0276 $retval = $this->_stmt->fetch(); 0277 switch ($retval) { 0278 case null: // end of data 0279 case false: // error occurred 0280 $this->_stmt->reset(); 0281 return false; 0282 default: 0283 // fallthrough 0284 } 0285 0286 // make sure we have a fetch mode 0287 if ($style === null) { 0288 $style = $this->_fetchMode; 0289 } 0290 0291 // dereference the result values, otherwise things like fetchAll() 0292 // return the same values for every entry (because of the reference). 0293 $values = array(); 0294 foreach ($this->_values as $key => $val) { 0295 $values[] = $val; 0296 } 0297 0298 $row = false; 0299 switch ($style) { 0300 case Zend_Db::FETCH_NUM: 0301 $row = $values; 0302 break; 0303 case Zend_Db::FETCH_ASSOC: 0304 $row = array_combine($this->_keys, $values); 0305 break; 0306 case Zend_Db::FETCH_BOTH: 0307 $assoc = array_combine($this->_keys, $values); 0308 $row = array_merge($values, $assoc); 0309 break; 0310 case Zend_Db::FETCH_OBJ: 0311 $row = (object) array_combine($this->_keys, $values); 0312 break; 0313 case Zend_Db::FETCH_BOUND: 0314 $assoc = array_combine($this->_keys, $values); 0315 $row = array_merge($values, $assoc); 0316 return $this->_fetchBound($row); 0317 break; 0318 default: 0319 /** 0320 * @see Zend_Db_Statement_Mysqli_Exception 0321 */ 0322 // require_once 'Zend/Db/Statement/Mysqli/Exception.php'; 0323 throw new Zend_Db_Statement_Mysqli_Exception("Invalid fetch mode '$style' specified"); 0324 break; 0325 } 0326 return $row; 0327 } 0328 0329 /** 0330 * Retrieves the next rowset (result set) for a SQL statement that has 0331 * multiple result sets. An example is a stored procedure that returns 0332 * the results of multiple queries. 0333 * 0334 * @return bool 0335 * @throws Zend_Db_Statement_Mysqli_Exception 0336 */ 0337 public function nextRowset() 0338 { 0339 /** 0340 * @see Zend_Db_Statement_Mysqli_Exception 0341 */ 0342 // require_once 'Zend/Db/Statement/Mysqli/Exception.php'; 0343 throw new Zend_Db_Statement_Mysqli_Exception(__FUNCTION__.'() is not implemented'); 0344 } 0345 0346 /** 0347 * Returns the number of rows affected by the execution of the 0348 * last INSERT, DELETE, or UPDATE statement executed by this 0349 * statement object. 0350 * 0351 * @return int The number of rows affected. 0352 */ 0353 public function rowCount() 0354 { 0355 if (!$this->_adapter) { 0356 return false; 0357 } 0358 $mysqli = $this->_adapter->getConnection(); 0359 return $mysqli->affected_rows; 0360 } 0361 0362 }