MediaWiki REL1_35
DatabaseMysqli.php
Go to the documentation of this file.
1<?php
23namespace Wikimedia\Rdbms;
24
25use mysqli;
26use mysqli_result;
27use stdClass;
28use Wikimedia\AtEase\AtEase;
29use Wikimedia\IPUtils;
30
44 protected function doQuery( $sql ) {
45 AtEase::suppressWarnings();
46 $res = $this->getBindingHandle()->query( $sql );
47 AtEase::restoreWarnings();
48
49 return $res;
50 }
51
58 protected function mysqlConnect( $realServer, $dbName ) {
59 if ( !function_exists( 'mysqli_init' ) ) {
61 "MySQLi functions missing, have you compiled PHP with the --with-mysqli option?"
62 );
63 }
64
65 // PHP 8.1.0+ throws exceptions by default. Turn that off for consistency.
66 mysqli_report( MYSQLI_REPORT_OFF );
67
68 // Other than mysql_connect, mysqli_real_connect expects an explicit port number
69 // e.g. "localhost:1234" or "127.0.0.1:1234"
70 // or Unix domain socket path
71 // e.g. "localhost:/socket_path" or "localhost:/foo/bar:bar:bar"
72 // colons are known to be used by Google AppEngine,
73 // see <https://cloud.google.com/sql/docs/mysql/connect-app-engine>
74 //
75 // We need to parse the port or socket path out of $realServer
76 $port = null;
77 $socket = null;
78 $hostAndPort = IPUtils::splitHostAndPort( $realServer );
79 if ( $hostAndPort ) {
80 $realServer = $hostAndPort[0];
81 if ( $hostAndPort[1] ) {
82 $port = $hostAndPort[1];
83 }
84 } elseif ( substr_count( $realServer, ':/' ) == 1 ) {
85 // If we have a colon slash instead of a colon and a port number
86 // after the ip or hostname, assume it's the Unix domain socket path
87 list( $realServer, $socket ) = explode( ':', $realServer, 2 );
88 }
89
90 $mysqli = mysqli_init();
91 // Make affectedRows() for UPDATE reflect the number of matching rows, regardless
92 // of whether any column values changed. This is what callers want to know and is
93 // consistent with what Postgres, SQLite, and SQL Server return.
94 $connFlags = MYSQLI_CLIENT_FOUND_ROWS;
95 if ( $this->getFlag( self::DBO_SSL ) ) {
96 $connFlags |= MYSQLI_CLIENT_SSL;
97 $mysqli->ssl_set(
98 $this->sslKeyPath,
99 $this->sslCertPath,
100 $this->sslCAFile,
101 $this->sslCAPath,
102 $this->sslCiphers
103 );
104 }
105 if ( $this->getFlag( self::DBO_COMPRESS ) ) {
106 $connFlags |= MYSQLI_CLIENT_COMPRESS;
107 }
108 if ( $this->getFlag( self::DBO_PERSISTENT ) ) {
109 $realServer = 'p:' . $realServer;
110 }
111
112 if ( $this->utf8Mode ) {
113 // Tell the server we're communicating with it in UTF-8.
114 // This may engage various charset conversions.
115 $mysqli->options( MYSQLI_SET_CHARSET_NAME, 'utf8' );
116 } else {
117 $mysqli->options( MYSQLI_SET_CHARSET_NAME, 'binary' );
118 }
119 $mysqli->options( MYSQLI_OPT_CONNECT_TIMEOUT, 3 );
120
121 if ( $mysqli->real_connect(
122 $realServer,
123 $this->user,
124 $this->password,
125 $dbName,
126 $port,
127 $socket,
128 $connFlags
129 ) ) {
130 return $mysqli;
131 }
132
133 return null;
134 }
135
139 protected function closeConnection() {
140 $conn = $this->getBindingHandle();
141
142 return $conn->close();
143 }
144
148 public function insertId() {
149 $conn = $this->getBindingHandle();
150
151 return (int)$conn->insert_id;
152 }
153
157 public function lastErrno() {
158 if ( $this->conn instanceof mysqli ) {
159 return $this->conn->errno;
160 } else {
161 return mysqli_connect_errno();
162 }
163 }
164
168 protected function fetchAffectedRowCount() {
169 $conn = $this->getBindingHandle();
170
171 return $conn->affected_rows;
172 }
173
178 protected function mysqlFreeResult( $res ) {
179 $res->free_result();
180
181 return true;
182 }
183
188 protected function mysqlFetchObject( $res ) {
189 $object = $res->fetch_object();
190 if ( $object === null ) {
191 return false;
192 }
193
194 return $object;
195 }
196
201 protected function mysqlFetchArray( $res ) {
202 $array = $res->fetch_array();
203 if ( $array === null ) {
204 return false;
205 }
206
207 return $array;
208 }
209
214 protected function mysqlNumRows( $res ) {
215 return $res->num_rows;
216 }
217
222 protected function mysqlNumFields( $res ) {
223 return $res->field_count;
224 }
225
231 protected function mysqlFetchField( $res, $n ) {
232 $field = $res->fetch_field_direct( $n );
233
234 // Add missing properties to result (using flags property)
235 // which will be part of function mysql-fetch-field for backward compatibility
236 $field->not_null = $field->flags & MYSQLI_NOT_NULL_FLAG;
237 $field->primary_key = $field->flags & MYSQLI_PRI_KEY_FLAG;
238 $field->unique_key = $field->flags & MYSQLI_UNIQUE_KEY_FLAG;
239 $field->multiple_key = $field->flags & MYSQLI_MULTIPLE_KEY_FLAG;
240 $field->binary = $field->flags & MYSQLI_BINARY_FLAG;
241 $field->numeric = $field->flags & MYSQLI_NUM_FLAG;
242 $field->blob = $field->flags & MYSQLI_BLOB_FLAG;
243 $field->unsigned = $field->flags & MYSQLI_UNSIGNED_FLAG;
244 $field->zerofill = $field->flags & MYSQLI_ZEROFILL_FLAG;
245
246 return $field;
247 }
248
254 protected function mysqlFieldName( $res, $n ) {
255 $field = $res->fetch_field_direct( $n );
256
257 return $field->name;
258 }
259
265 protected function mysqlFieldType( $res, $n ) {
266 $field = $res->fetch_field_direct( $n );
267
268 return $field->type;
269 }
270
276 protected function mysqlDataSeek( $res, $row ) {
277 return $res->data_seek( $row );
278 }
279
284 protected function mysqlError( $conn = null ) {
285 if ( $conn === null ) {
286 return mysqli_connect_error();
287 } else {
288 return $conn->error;
289 }
290 }
291
297 protected function mysqlRealEscapeString( $s ) {
298 $conn = $this->getBindingHandle();
299
300 return $conn->real_escape_string( (string)$s );
301 }
302
306 protected function getBindingHandle() {
307 return parent::getBindingHandle();
308 }
309}
310
314class_alias( DatabaseMysqli::class, 'DatabaseMysqli' );
Database abstraction object for MySQL.
Database abstraction object for PHP extension mysqli.
mysqlConnect( $realServer, $dbName)
mysqlRealEscapeString( $s)
Escapes special characters in a string for use in an SQL statement.
object resource null $conn
Database connection.
Definition Database.php:73
newExceptionAfterConnectError( $error)
getFlag( $flag)
Returns a boolean whether the flag $flag is set for this connection.
Definition Database.php:819