PHP访问数据库,服务器地址到底怎么填
PHP访问数据库时,数据库服务器地址就是连接代码中的host参数,它告诉PHP程序数据库文件或服务在哪里运行,本地开发填localhost或0.0.1,线上环境则填云数据库的公网IP或内网域名。 很多新手在这个环节卡住,报错信息五花八门,其实弄懂地址的构成规则和常见坑,问题就解决了一大半。
数据库服务器地址是什么,PHP怎么用它
数据库服务器地址在PHP里不是单独一个配置文件,而是作为连接函数或类的一个参数出现,以最常用的MySQL为例,无论是用mysqli还是PDO,都需要指定四个核心信息:服务器地址(host)、端口(port)、用户名(username)、密码(password),服务器地址就是第一道门槛,填错了后面全白搭。
从PHP代码角度看,地址的传递方式有两种:
- 使用mysqli扩展时,地址作为
new mysqli()构造方法的第一个参数传入。 - 使用PDO扩展时,地址拼在DSN(数据源名称)字符串里,格式为
mysql:host=你的地址;port=3306;dbname=数据库名。
服务器地址本质上就是一个网络定位符,PHP脚本运行时,底层会通过TCP/IP协议去连接这个地址对应的机器和端口,如果地址写的是域名,PHP还会先发起一次DNS解析,把域名翻译成IP再连接,这就是为什么有时候网络抖动或者DNS缓存出问题,连接就会变慢甚至失败。
PHP连接数据库服务器地址怎么写
本地开发环境填什么
本地开发时,数据库和PHP代码跑在同一台机器上,地址通常填localhost或者0.0.1,这两个大多数场景下等价,但有个细微差别值得了解:localhost在部分PHP配置下会尝试走Unix套接字连接,速度更快;而0.0.1强制走TCP/IP网络协议栈,如果遇到连接超时但数据库确实在运行的情况,把localhost换成0.0.1往往能解决问题。
本地连接的具体写法:
// mysqli方式
$conn = new mysqli("localhost", "root", "你的密码", "test_db");
// PDO方式
$dsn = "mysql:host=127.0.0.1;port=3306;dbname=test_db;charset=utf8mb4";
$pdo = new PDO($dsn, "root", "你的密码");
这里有个高频问题:php连接数据库失败怎么办?第一步就是确认数据库服务真的在运行,在Linux服务器上执行
systemctl status mysql,Windows下打开服务管理器查看MySQL服务状态,服务没启动,地址填得再对也是白搭。
线上服务器地址怎么区分内网和外网
线上环境情况复杂一些,服务器地址要分场景看待:
- 代码和数据库在同一台服务器:依旧填
localhost或0.0.1,不走公网流量,速度最快也最安全。 - 代码和数据库在不同服务器但同一内网:填数据库服务器的内网IP,比如
168.x.x或x.x.x,这类地址不经过公网,延迟低且不占用公网带宽。 - 数据库在云厂商的RDS等服务上:控制台会给出两个地址内网地址和公网地址,应用服务器和数据库同区域时,务必用内网地址,不仅速度快,还能避免公网暴露带来的安全风险,公网地址只有在本地调试或跨区域连接时才用。
行业共识认为,内网连接比公网连接在延迟上能降低一个数量级,同时对数据库的安全防护压力也小得多,云厂商通常还会提供一个高可用域名,背后挂着主备两个实例,故障时自动切换,这时填域名比填固定IP更省心。
端口和地址是一对,别只填一半
服务器地址经常和端口配套出现,MySQL默认端口是3306,PostgreSQL是5432,Redis是6379,PHP连接时端口可以不写,默认用对应数据库的默认值,但一旦数据库改了端口,地址就得写成主机IP:端口号的形式。
PDO的DSN写法里端口单独作为参数,而mysqli的写法则是把端口作为构造方法的第四个参数:
// 数据库跑在3307端口
$conn = new mysqli("localhost", "root", "密码", "test_db", 3307);
// PDO写法
$dsn = "mysql:host=localhost;port=3307;dbname=test_db";
云数据库的连接地址通常不包含端口,端口在控制台单独显示,常见的有3306、3307等,修改数据库端口后,记得同步更新PHP代码里的配置,这是改完配置连不上的最常见原因之一。
特殊场景:SQLite没有服务器地址
用SQLite当数据库时,整个“服务器地址”的概念就不存在了,SQLite是嵌入式数据库,数据存在一个本地文件里,PHP连接时填的是文件路径:
$pdo = new PDO("sqlite:/var/www/html/data/app.db");
这种情况下,要保证PHP进程对那个目录有读写权限,否则会报“attempt to write a readonly database”错误,这个错误不是地址问题,是权限问题。
PHP数据库连接失败怎么办
连接失败是每个PHP开发者都会遇到的拦路虎,排查思路比死记硬背代码更重要,按下面顺序过一遍,多数问题都能定位。
第一步:检查数据库服务状态。 在服务器上执行ps aux | grep mysql或systemctl status mysqld,确认进程存在,服务没起来,一切免谈。
第二步:验证地址和端口通不通。 用telnet或者nc命令测试:
telnet 127.0.0.1 3306
如果端口不通,要么是数据库没监听,要么是防火墙挡了,Linux上检查防火墙:firewall-cmd --list-all或iptables -L -n。
第三步:确认账号的访问权限。 MySQL的账号是绑定host的,比如'root'@'localhost'和'root'@'%'是两回事,如果PHP代码用IP连接但账号只授权了localhost,就会报Access denied for user,查看账号权限:
SELECT user, host FROM mysql.user;
第四步:检查PHP错误日志和数据库日志。 数据库的error log里会记录连接失败的详细原因,包括密码错误、账号不存在、ip被拒绝等,PHP日志则能看到代码层面的警告信息。
php连接数据库失败怎么办这个问题,还有一个常被忽略的点:PHP扩展没装好。php -m命令可以查看已加载的模块,确认有mysqli或pdo_mysql,没有的话,安装对应扩展并重启PHP-FPM。
连接数据库的注意事项和进阶配置
字符集和时区设置
服务器地址连对了,不代表数据就能正常读写,字符集不匹配会导致中文乱码,时区不对会让时间数据偏差,建议在连接后立即设置:
// mysqli
$conn->set_charset("utf8mb4");
// PDO,在DSN中指定
$dsn = "mysql:host=localhost;dbname=test_db;charset=utf8mb4";
同时设置时区:SET time_zone = '+8:00',这一步做不做,决定了你存进去的时间和取出来的时间是不是同一个时间。
连接池和长连接
高并发场景下,每次请求都新建数据库连接开销很大,PHP-FPM常驻进程模式下,可以开启持久连接复用数据库连接,mysqli中使用p:localhost前缀,PDO中设置PDO::ATTR_PERSISTENT => true
,但要注意,持久连接会占用数据库的连接数,连接池配置不当反而拖垮数据库,据统计,大多数中小型项目的瓶颈在SQL查询效率而非连接开销,所以不要盲目上持久连接。
安全建议
数据库地址在代码里属于敏感信息,有几点建议:
- 不要把密码直接写在PHP文件里,用环境变量或配置文件管理,配置文件排除出版本控制。
- 最小权限原则:给PHP连接数据库的账号只授予所需库表的增删改查权限,别用root。
- 公网地址尽量不开,如果必须开,设置防火墙白名单只允许指定IP访问。
连接超时和重试机制
数据库偶尔抖动是常态,代码层面可以做超时控制和重试,mysqli连接时可以设置超时时间:
mysqli_report(MYSQLI_REPORT_STRICT);
try {
$conn = new mysqli("localhost", "user", "pass", "db", 3306, 5);
} catch (mysqli_sql_exception $e) {
// 记录日志,稍后重试
}
PDO则通过设置PDO::ATTR_TIMEOUT来控制连接超时,合理的超时设置能让应用在数据库故障时不至于长时间卡死。
Q&A:PHP连接数据库常见问题
Q1:php连接数据库服务器地址填localhost和127.0.0.1有什么区别?
两者指向的都是本机,但localhost在部分系统上会走Unix域套接字,0.0.1走TCP/IP协议,如果数据库配置了skip-networking,TCP连接会失败而套接字连接不受影响,反过来,如果PHP配置里禁用了套接字连接,就只能用0.0.1,出现连接异常时,互换这两个地址是值得尝试的排查手段。
Q2:云数据库的公网地址和内网地址怎么选?
原则很简单:应用服务器和数据库在同一地域内网互通时,一律用内网地址,内网连接延迟低、速度快,且不经过公网,安全性更高,公网地址只用于本地开发调试或者跨地域的临时连接,长期使用公网连接不仅性能差,还会让数据库暴露在公网扫描之下。
Q3:数据库改了端口,PHP代码要怎么改?
PDO的DSN中修改port参数值,mysqli构造方法的第四个参数改为新端口,改完后测试一下新端口是否可访问,有些云厂商的安全组需要额外放行新端口,同时确认数据库配置文件my.cnf或my.ini中port参数已修改并重启服务。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/600868.html




