mysqli::__construct

mysqli::connect

mysqli_connect

(PHP 5, PHP 7, PHP 8)

mysqli::__construct -- mysqli::connect -- mysqli_connect打开与 MySQL 服务器的新连接

描述

面向对象风格

public mysqli::__construct(
    ?string $hostname = null,
    ?string $username = null,
    #[\SensitiveParameter] ?string $password = null,
    ?string $database = null,
    ?int $port = null,
    ?string $socket = null
)
public mysqli::connect(
    ?string $hostname = null,
    ?string $username = null,
    #[\SensitiveParameter] ?string $password = null,
    ?string $database = null,
    ?int $port = null,
    ?string $socket = null
): bool

过程化风格

mysqli_connect(
    ?string $hostname = null,
    ?string $username = null,
    #[\SensitiveParameter] ?string $password = null,
    ?string $database = null,
    ?int $port = null,
    ?string $socket = null
): mysqli|false

打开与 MySQL 服务器的连接。

参数

hostname

可以是主机名或 IP 地址。当传递 null 时,该值将从 mysqli.default_host 中获取。如果可能,将使用管道而不是 TCP/IP 协议。如果一起提供了主机名和端口号,例如 localhost:3308,则使用 TCP/IP 协议。

使用 p: 在主机名前缀打开一个持久连接。 mysqli_change_user() 会自动在从连接池中打开的连接上调用。

username

MySQL 用户名或 null 以根据 mysqli.default_user ini 选项来假设用户名。

password

MySQL 密码或 null 以根据 mysqli.default_pw ini 选项来假设密码。

database

执行查询时要使用的默认数据库或 null

port

要尝试连接到 MySQL 服务器的端口号或 null 以根据 mysqli.default_port ini 选项来假设端口。

socket

要使用的套接字或命名管道,或 null 以根据 mysqli.default_socket ini 选项来假设套接字。

注意:

指定 socket 参数不会明确确定在连接到 MySQL 服务器时要使用的连接类型。连接到 MySQL 数据库的方式由 hostname 参数决定。

返回值

mysqli_connect() 返回一个表示与 MySQL 服务器连接的对象,如果失败则返回 false

mysqli::connect() 在成功时返回 true,失败时返回 false。在 PHP 8.1.0 之前,在成功时返回 null

错误/异常

如果启用了 mysqli 错误报告 (MYSQLI_REPORT_ERROR) 并且请求的操作失败,则会生成警告。如果此外,模式设置为 MYSQLI_REPORT_STRICT,则会抛出 mysqli_sql_exception 而不是警告。

变更日志

版本 描述
8.1.0 mysqli::connect() 现在返回 true 而不是 null,以指示成功。
7.4.0 所有参数现在都是可空的。

示例

示例 #1 mysqli::__construct() 示例

面向对象风格

<?php

/* 在尝试建立连接之前,你应该为 mysqli 启用错误报告 */
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

$mysqli = new mysqli('localhost', 'my_user', 'my_password', 'my_db');

/* 在建立连接后设置所需的字符集 */
$mysqli->set_charset('utf8mb4');

printf("成功... %s\n", $mysqli->host_info);

过程化风格

<?php

/* 在尝试建立连接之前,你应该为 mysqli 启用错误报告 */
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

$mysqli = mysqli_connect('localhost', 'my_user', 'my_password', 'my_db');

/* 在建立连接后设置所需的字符集 */
mysqli_set_charset($mysqli, 'utf8mb4');

printf("成功... %s\n", mysqli_get_host_info($mysqli));

上面的示例将输出类似于以下内容:

Success... localhost via TCP/IP

示例 #2 扩展 mysqli 类

<?php

class FooMysqli extends mysqli {
public function
__construct($host, $user, $pass, $db, $port, $socket, $charset) {
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
parent::__construct($host, $user, $pass, $db, $port, $socket);
$this->set_charset($charset);
}
}

$db = new FooMysqli('localhost', 'my_user', 'my_password', 'my_db', 3306, null, 'utf8mb4');

示例 #3 手动错误处理

如果禁用错误报告,开发人员有责任检查和处理故障

面向对象风格

<?php

error_reporting
(0);
mysqli_report(MYSQLI_REPORT_OFF);
$mysqli = new mysqli('localhost', 'my_user', 'my_password', 'my_db');
if (
$mysqli->connect_errno) {
throw new
RuntimeException('mysqli 连接错误: ' . $mysqli->connect_error);
}

/* 在建立连接后设置所需的字符集 */
$mysqli->set_charset('utf8mb4');
if (
$mysqli->errno) {
throw new
RuntimeException('mysqli 错误: ' . $mysqli->error);
}

过程化风格

<?php

error_reporting
(0);
mysqli_report(MYSQLI_REPORT_OFF);
$mysqli = mysqli_connect('localhost', 'my_user', 'my_password', 'my_db');
if (
mysqli_connect_errno()) {
throw new
RuntimeException('mysqli 连接错误: ' . mysqli_connect_error());
}

/* 在建立连接后设置所需的字符集 */
mysqli_set_charset($mysqli, 'utf8mb4');
if (
mysqli_errno($mysqli)) {
throw new
RuntimeException('mysqli 错误: ' . mysqli_error($mysqli));
}

备注

注意:

MySQLnd 始终假设服务器默认字符集。此字符集在连接握手/身份验证期间发送,mysqlnd 将使用它。

Libmysqlclient 使用在 my.cnf 中设置的默认字符集,或者通过在调用 mysqli_real_connect() 之前,但在调用 mysqli_init() 之后,显式调用 mysqli_options() 来设置。

注意:

面向对象风格:如果连接失败,仍然会返回一个对象。要检查连接是否失败,请使用 mysqli_connect_error() 函数或 mysqli->connect_error 属性,如前面的示例所示。

注意:

如果需要设置选项,例如连接超时,则必须使用 mysqli_real_connect()

注意:

使用不带参数的构造函数与调用 mysqli_init() 相同。

注意:

错误“无法创建 TCP/IP 套接字 (10106)” 通常意味着 variables_order 配置指令不包含字符 E。在 Windows 上,如果环境未被复制,SYSTEMROOT 环境变量将不可用,PHP 将无法加载 Winsock。

另请参阅

添加注释

用户贡献的注释 13 个注释

fugyl13 at gmail dot com
10 年前
请注意,在所有 >=Windows 7 服务器上,主机名“localhost”将创建一个非常昂贵的查找(约 1 秒)。

这是因为从 Windows 7 开始,hosts 文件不再预先配置
127.0.0.1 localhost
了。

因此,如果您注意到连接创建时间过长,请尝试使用“127.0.0.1”代替。
andres at 21brains dot com
10 年前
请在建立连接后使用 set_charset("utf8"),以避免出现奇怪的字符串问题。我不知道为什么文档没有警告你这些问题。

我们花了很长时间才弄清楚到底发生了什么,因为我们使用的是 mb_detect_encoding,它表示所有内容都是 UTF-8,但当然显示结果是错误的。如果我们使用 iconv 从 ISO-8859-1 转换为 UTF-8,字符串看起来就正常了,即使数据库中的所有内容都具有正确的排序规则。所以最终,连接才是过滤器,虽然此函数的注释提到了默认字符集,但这几乎读起来像是一个旁注,而不是处理 UTF 和 PHP/MySQL 时的一个核心问题。
php at haravikk dot me
6 年前
只是想为任何想要使用 MySQLi 持久连接功能的人添加一个注释;重要的是要注意,PHP 为每个数据库用户打开并保留一个连接,并为每个进程保留一个连接。

这意味着如果您托管多个应用程序,每个应用程序都有自己的数据库用户(这是良好的做法),那么您最终将使 PHP 可能持有的连接数量成倍增加。

例如,如果您将 PHP 配置为最多有八个工作进程,并且您经常使用四个不同的数据库用户,那么您的 MySQL 服务器需要接受至少 32 个连接,否则它将耗尽。

但是,如果您想最小化连接数量,您可以做的是打开使用“访客”用户(除了登录之外没有任何权限)的连接,然后使用 ->change_user() 切换到更有权限的用户,然后在完成后切换回访客用户。由于所有连接都属于访客用户,因此 PHP 应该只为每个工作进程维护一个连接。
chris at ocproducts dot com
7 年前
有一个单独的端口参数,与 mysql_connect 不同。但是,在主机参数中使用 host:port 实际上是有效的。

有一个警告。如果主机是'localhost',那么端口将被忽略,无论您使用端口参数还是我上面提到的隐式语法。这是因为'localhost' 将使其使用 unix 套接字而不是 TCP/IP。
paul at mtnlist dot com
11 年前
如果您想通过备用端口(而不是 3306)连接,例如当您使用 ssh 隧道连接到另一个主机时,使用“localhost”作为主机名将不起作用。

使用 127.0.0.1 将有效。显然,如果您将主机指定为“localhost”,构造函数将忽略作为构造函数参数指定的端口。
arnold at nijboer dot it
1 年前
public mysqli::__construct(
    string $hostname = ini_get("mysqli.default_host"),
    string $username = ini_get("mysqli.default_user"),
    string $password = ini_get("mysqli.default_pw"),
    string $database = "",
    int $port = ini_get("mysqli.default_port"),
    string $socket = ini_get("mysqli.default_socket")
)

mysqli 构造函数会查看主 PHP.ini 值。
如果您使用的是某种本地 ini 覆盖,请将 ini_get 添加到您的 php 脚本中
$mysqli = new mysqli(ini_get("mysqli.default_host"),ini_get("mysqli.default_user"),ini_get("mysqli.default_pw"))
PaulieG
8 年前
应该注意的是,在 PHP 7(至少 v7.0.2)上,在连接到'localhost' 时将空字符串 '' 传递给端口参数将完全阻止连接成功。

为了解决这个问题,请使用'null'。
匿名
14 年前
如果你遇到这样的错误
无法连接到 'localhost' 上的 MySQL 服务器 (10061)
并且你使用了命名管道/套接字连接(或者不确定你是如何安装 MySQL 服务器的),请尝试以下连接命令

<?php
mysqli_connect
('.', $user_name, $password, $database_name, null, 'mysql');
?>

当使用命名管道时,'.' 作为主机名是绝对必要的。'localhost' 将不起作用。'mysql' 是管道/套接字的标准名称。
Ben
9 年前
连接到 mysql 的更安全、更独立于语言的方法是使用 READ_DEFAULT_FILE 选项。这将工作负载移交给 mysql 库,允许配置文件本身超出语言范围。

配置文件本身类似于这样
[client]
user=user_u
password=user_password
host=dbhost
port=3306
database=the_database
default-character-set=utf8

以下代码片段(在 OO mysql_i 格式中)

$sqlconf='/var/private/my.cnf';
$sql = new mysqli;
$sql->init();
$sql->options(MYSQLI_READ_DEFAULT_FILE,$sqlconf);
$sql->real_connect();
linguafranca2003 at yahoo dot com
9 年前
mysqli 可以以令人惊讶的方式成功,具体取决于授予用户的权限。例如,

GRANT USAGE ON *.* TO 'myuser'@'localhost' IDENTIFIED BY PASSWORD 'mypassword';
GRANT ALL PRIVILEGES ON `database_a`.* TO 'myuser'@'localhost';
CREATE DATABASE database_b;

<?php
$db
= new mysqli('localhost', 'myuser', 'mypassword', 'database_b');

if (
$db->connect_error) {
die(
'Connect Error (' . $db->connect_errno . ') '
. $mysqli->connect_error);
}

printf("SQLSTATE: %s\n", $this->db->sqlstate);
printf("Warning Count: %s\n", $db->warning_count);
$db->close();
?>

将输出

SQLSTATE: 00000
Warning Count: 0

所以,一切都很好 - 你已经连接到数据库并执行 mysqli 方法。 除了,生活并不美好,因为你实际上并没有使用 database_b,因为 myuser 对它没有任何权限。 在你尝试执行后续操作之前,你不会发现这一点,那时你会得到一个错误,“MYSQL 错误:没有选择数据库”,你会发现自己在挠头,想“你是什么意思,当然我选择了数据库;我在调用构造函数时选择了”。

因此,你可能希望在连接到 mysql 后执行额外的检查,以确认你实际上不仅连接到 mysql 服务器,而且连接到实际的数据库

<?php
$db
= new mysqli('localhost', 'myuser', 'mypassword', 'database_b');

if (
$db->connect_error) {
die(
'Connect Error (' . $db->connect_errno . ') '
. $mysqli->connect_error);
} elseif (
$result = $db->query("SELECT DATABASE()")) {
$row = $result->fetch_row();
if (
$row[0] != 'database_b') {
//oops! 我们连接到 mysql,但没有连接到 database_b
}
}
?>
webmaster at aryes dot fr
9 年前
我的一个朋友遇到了 CMS Piwigo 的突然错误。我发现
- 他有一个主机规则来使用 PHP 5.6。
- 主机使用 5.6.6,使用 phpinfo(); 验证。
- CMS 将数据库名称参数声明为 null。

该画廊 CMS 无法连接到 MySQL,只留下了关于它的警告消息。

我们尝试恢复到 PHP 5.5,CMS 再次运行。

然后我们切换回 5.6.6 并更改了这些行

$dbname = null;

$mysqli = new mysqli($host, $user, $password, $dbname, $port, $socket);



$dbname = ''; // 使用空字符串,而不是 null

$mysqli = new mysqli($host, $user, $password, $dbname, $port, $socket);

它运行了!

因此,如果你犯了同样的错误,在手册要求使用空字符串的地方使用了 null,你应该考虑修正你的代码。
powtac at gmx de
6 年前
注意,mysqli_connect() 不返回资源!它返回 mysqli 类的实例 (https://php.net/manual/class.mysqli.php) 旧的 mysql_connect() 函数确实返回了一个资源。
oleg at mastak dot fi
11 年前
如果你想连接到 Windows 上的本地命名管道,并且你得到错误“php_network_getaddresses: getaddrinfo failed: No such host is known.”,即使你使用“.”作为主机,请检查你是否使用的是 mysqlnd 驱动程序:如果这是真的,那么你可能需要更新到 php 5.4 版本

Windows 的命名管道支持在 PHP 5.4.0 版本中添加。
@ https://php.net/manual/en/mysqlnd.overview.php

希望这能节省你一些时间。
To Top