PHP Conference Japan 2024

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 服务器的连接。

参数

主机名

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

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

用户名

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

密码

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

数据库

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

端口

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

套接字

应使用的套接字或命名管道或 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("Success... %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("Success... %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_options()(在调用mysqli_real_connect()之前,但在mysqli_init()之后)设置的默认字符集。

注意:

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

注意:

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

注意:

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

注意:

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

参见

添加注释

用户贡献的注释 5 条注释

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,但当然显示是错误的。如果我们从 ISO-8859-1 到 UTF-8 使用 iconv,字符串看起来很好,即使数据库中的所有内容都具有正确的排序规则。所以最终,连接是过滤器,尽管此函数的注释提到了默认字符集,但在处理 UTF 和 PHP/MySQL 时,它几乎读起来像是一个旁注而不是一个核心问题。
chris at ocproducts dot com
7 年前
与 mysql_connect 不同,这里有一个单独的端口参数。但是,在主机参数上使用 host:port 实际上是可行的。

有一个警告。如果主机是“localhost”,则无论您使用端口参数还是我上面提到的隐式语法,端口都将被忽略。这是因为“localhost”将使其使用 Unix 套接字而不是 TCP/IP。
php at haravikk dot me
7 年前
只想为任何想要使用 MySQLi 持久连接功能的人添加一个注释;需要注意的是,PHP 每个数据库用户每个进程都会打开并保留一个连接。

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

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

但是,如果您想最大限度地减少连接数量,您可以做的是使用“访客”用户(除了登录之外没有权限)打开连接,然后使用 ->change_user() 切换到更高级别的用户,并在完成后切换回访客用户。由于所有连接都属于访客用户,因此 PHP 每个工作进程应该只维护一个连接。
paul at mtnlist dot com
11 年前
如果您想通过备用端口(3306 以外的端口)连接,例如在使用 ssh 隧道到另一台主机时,使用“localhost”作为主机名将不起作用。

使用 127.0.0.1 将起作用。显然,如果您将主机指定为“localhost”,则构造函数将忽略作为构造函数参数指定的端口。
To Top