请注意,在所有 >=Windows 7 服务器上,主机名“localhost”将创建一个非常昂贵的查找(约 1 秒)。
这是因为从 Windows 7 开始,hosts 文件不再预配置
127.0.0.1 localhost
了。
因此,如果您注意到连接创建时间过长,请尝试使用“127.0.0.1”代替。
(PHP 5、PHP 7、PHP 8)
mysqli::__construct -- mysqli::connect -- mysqli_connect — 打开到 MySQL 服务器的新连接
面向对象风格
$hostname
= null
,$username
= null
,$password
= null
,$database
= null
,$port
= null
,$socket
= null
$hostname
= null
,$username
= null
,$password
= null
,$database
= null
,$port
= null
,$socket
= null
过程化风格
$hostname
= null
,$username
= null
,$password
= null
,$database
= null
,$port
= null
,$socket
= null
打开到 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 而不是警告。
示例 #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。
请注意,在所有 >=Windows 7 服务器上,主机名“localhost”将创建一个非常昂贵的查找(约 1 秒)。
这是因为从 Windows 7 开始,hosts 文件不再预配置
127.0.0.1 localhost
了。
因此,如果您注意到连接创建时间过长,请尝试使用“127.0.0.1”代替。
如果您想避免奇怪的字符串问题,请务必在建立连接后使用 set_charset("utf8")。我不知道为什么文档没有警告您这类问题。
我们很难找出发生了什么事,因为我们使用了 mb_detect_encoding,它说所有内容都是 UTF-8,但当然显示是错误的。如果我们从 ISO-8859-1 到 UTF-8 使用 iconv,字符串看起来很好,即使数据库中的所有内容都具有正确的排序规则。所以最终,连接是过滤器,尽管此函数的注释提到了默认字符集,但在处理 UTF 和 PHP/MySQL 时,它几乎读起来像是一个旁注而不是一个核心问题。
与 mysql_connect 不同,这里有一个单独的端口参数。但是,在主机参数上使用 host:port 实际上是可行的。
有一个警告。如果主机是“localhost”,则无论您使用端口参数还是我上面提到的隐式语法,端口都将被忽略。这是因为“localhost”将使其使用 Unix 套接字而不是 TCP/IP。
只想为任何想要使用 MySQLi 持久连接功能的人添加一个注释;需要注意的是,PHP 每个数据库用户每个进程都会打开并保留一个连接。
这意味着,如果您托管多个应用程序,每个应用程序都有自己的数据库用户(这是最佳实践),那么您最终将使 PHP 可能保持打开的连接数量成倍增加。
例如,如果您将 PHP 配置为最多八个工作进程,并且您定期使用四个不同的数据库用户,那么您的 MySQL 服务器需要接受至少 32 个连接,否则它将耗尽。
但是,如果您想最大限度地减少连接数量,您可以做的是使用“访客”用户(除了登录之外没有权限)打开连接,然后使用 ->change_user() 切换到更高级别的用户,并在完成后切换回访客用户。由于所有连接都属于访客用户,因此 PHP 每个工作进程应该只维护一个连接。
如果您想通过备用端口(3306 以外的端口)连接,例如在使用 ssh 隧道到另一台主机时,使用“localhost”作为主机名将不起作用。
使用 127.0.0.1 将起作用。显然,如果您将主机指定为“localhost”,则构造函数将忽略作为构造函数参数指定的端口。