MediaWiki  master
DatabaseMysqli.php
Go to the documentation of this file.
1 <?php
23 namespace Wikimedia\Rdbms;
24 
25 use mysqli;
26 use mysqli_result;
27 use Wikimedia\AtEase\AtEase;
28 use Wikimedia\IPUtils;
29 
47  protected function doQuery( $sql ) {
48  AtEase::suppressWarnings();
49  $res = $this->getBindingHandle()->query( $sql );
50  AtEase::restoreWarnings();
51 
52  return $res instanceof mysqli_result ? new MysqliResultWrapper( $this, $res ) : $res;
53  }
54 
63  protected function mysqlConnect( $server, $user, $password, $db ) {
64  if ( !function_exists( 'mysqli_init' ) ) {
65  throw $this->newExceptionAfterConnectError(
66  "MySQLi functions missing, have you compiled PHP with the --with-mysqli option?"
67  );
68  }
69 
70  // Other than mysql_connect, mysqli_real_connect expects an explicit port number
71  // e.g. "localhost:1234" or "127.0.0.1:1234"
72  // or Unix domain socket path
73  // e.g. "localhost:/socket_path" or "localhost:/foo/bar:bar:bar"
74  // colons are known to be used by Google AppEngine,
75  // see <https://cloud.google.com/sql/docs/mysql/connect-app-engine>
76  //
77  // We need to parse the port or socket path out of $realServer
78  $port = null;
79  $socket = null;
80  $hostAndPort = IPUtils::splitHostAndPort( $server );
81  if ( $hostAndPort ) {
82  $realServer = $hostAndPort[0];
83  if ( $hostAndPort[1] ) {
84  $port = $hostAndPort[1];
85  }
86  } elseif ( substr_count( $server, ':/' ) == 1 ) {
87  // If we have a colon slash instead of a colon and a port number
88  // after the ip or hostname, assume it's the Unix domain socket path
89  list( $realServer, $socket ) = explode( ':', $server, 2 );
90  } else {
91  $realServer = $server;
92  }
93 
94  $mysqli = mysqli_init();
95  // Make affectedRows() for UPDATE reflect the number of matching rows, regardless
96  // of whether any column values changed. This is what callers want to know and is
97  // consistent with what Postgres, SQLite, and SQL Server return.
98  $flags = MYSQLI_CLIENT_FOUND_ROWS;
99  if ( $this->getFlag( self::DBO_SSL ) ) {
100  $flags |= MYSQLI_CLIENT_SSL;
101  $mysqli->ssl_set(
102  $this->sslKeyPath,
103  $this->sslCertPath,
104  $this->sslCAFile,
105  $this->sslCAPath,
106  $this->sslCiphers
107  );
108  }
109  if ( $this->getFlag( self::DBO_COMPRESS ) ) {
110  $flags |= MYSQLI_CLIENT_COMPRESS;
111  }
112  if ( $this->getFlag( self::DBO_PERSISTENT ) ) {
113  $realServer = 'p:' . $realServer;
114  }
115 
116  if ( $this->utf8Mode ) {
117  // Tell the server we're communicating with it in UTF-8.
118  // This may engage various charset conversions.
119  $mysqli->options( MYSQLI_SET_CHARSET_NAME, 'utf8' );
120  } else {
121  $mysqli->options( MYSQLI_SET_CHARSET_NAME, 'binary' );
122  }
123  $mysqli->options( MYSQLI_OPT_CONNECT_TIMEOUT, 3 );
124 
125  $ok = $mysqli->real_connect( $realServer, $user, $password, $db, $port, $socket, $flags );
126 
127  return $ok ? $mysqli : null;
128  }
129 
133  protected function closeConnection() {
134  $conn = $this->getBindingHandle();
135 
136  return $conn->close();
137  }
138 
142  public function insertId() {
143  $conn = $this->getBindingHandle();
144 
145  return (int)$conn->insert_id;
146  }
147 
151  public function lastErrno() {
152  if ( $this->conn instanceof mysqli ) {
153  return $this->conn->errno;
154  } else {
155  return mysqli_connect_errno();
156  }
157  }
158 
162  protected function fetchAffectedRowCount() {
163  $conn = $this->getBindingHandle();
164 
165  return $conn->affected_rows;
166  }
167 
173  protected function mysqlFieldType( $res, $n ) {
174  $field = $res->fetch_field_direct( $n );
175 
176  return $field->type;
177  }
178 
183  protected function mysqlError( $conn = null ) {
184  if ( $conn === null ) {
185  return mysqli_connect_error();
186  } else {
187  return $conn->error;
188  }
189  }
190 
196  protected function mysqlRealEscapeString( $s ) {
197  $conn = $this->getBindingHandle();
198 
199  return $conn->real_escape_string( (string)$s );
200  }
201 
205  protected function getBindingHandle() {
206  return parent::getBindingHandle();
207  }
208 }
209 
213 class_alias( DatabaseMysqli::class, 'DatabaseMysqli' );
DBO_PERSISTENT
const DBO_PERSISTENT
Definition: defines.php:14
Wikimedia\Rdbms\DatabaseMysqli\getBindingHandle
getBindingHandle()
Definition: DatabaseMysqli.php:205
Wikimedia\Rdbms\DatabaseMysqli\mysqlFieldType
mysqlFieldType( $res, $n)
Definition: DatabaseMysqli.php:173
Wikimedia\Rdbms\DatabaseMysqli\lastErrno
lastErrno()
Definition: DatabaseMysqli.php:151
Wikimedia\Rdbms
Definition: ChronologyProtector.php:24
Wikimedia\Rdbms\Database\$server
string null $server
Server that this instance is currently connected to.
Definition: Database.php:83
DBO_SSL
const DBO_SSL
Definition: defines.php:17
Wikimedia\Rdbms\DatabaseMysqli
Database abstraction object for PHP extension mysqli.
Definition: DatabaseMysqli.php:42
$res
$res
Definition: testCompression.php:57
Wikimedia\Rdbms\DatabaseMysqli\doQuery
doQuery( $sql)
Definition: DatabaseMysqli.php:47
Wikimedia\Rdbms\Database\getFlag
getFlag( $flag)
Returns a boolean whether the flag $flag is set for this connection.
Definition: Database.php:864
Wikimedia\Rdbms\DatabaseMysqli\closeConnection
closeConnection()
Definition: DatabaseMysqli.php:133
Wikimedia\Rdbms\DatabaseMysqli\fetchAffectedRowCount
fetchAffectedRowCount()
Definition: DatabaseMysqli.php:162
Wikimedia\Rdbms\MysqliResultWrapper
Definition: MysqliResultWrapper.php:7
DBO_COMPRESS
const DBO_COMPRESS
Definition: defines.php:18
$s
foreach( $mmfl['setupFiles'] as $fileName) if( $queue) if(empty( $mmfl['quiet'])) $s
Definition: mergeMessageFileList.php:206
Wikimedia\Rdbms\DatabaseMysqli\insertId
insertId()
Definition: DatabaseMysqli.php:142
Wikimedia\Rdbms\DatabaseMysqli\mysqlError
mysqlError( $conn=null)
Definition: DatabaseMysqli.php:183
Wikimedia\Rdbms\DatabaseMysqli\mysqlConnect
mysqlConnect( $server, $user, $password, $db)
Definition: DatabaseMysqli.php:63
Wikimedia\Rdbms\Database\$user
string null $user
User that this instance is currently connected under the name of.
Definition: Database.php:85
Wikimedia\Rdbms\Database\newExceptionAfterConnectError
newExceptionAfterConnectError( $error)
Definition: Database.php:1842
Wikimedia\Rdbms\Database\$flags
int $flags
Current bit field of class DBO_* constants.
Definition: Database.php:106
Wikimedia\Rdbms\Database\$password
string null $password
Password used to establish the current connection.
Definition: Database.php:87
Wikimedia\Rdbms\Database\$conn
object resource null $conn
Database connection.
Definition: Database.php:77
Wikimedia\Rdbms\DatabaseMysqlBase
Database abstraction object for MySQL.
Definition: DatabaseMysqlBase.php:44
Wikimedia\Rdbms\DatabaseMysqli\mysqlRealEscapeString
mysqlRealEscapeString( $s)
Escapes special characters in a string for use in an SQL statement.
Definition: DatabaseMysqli.php:196