問題描述
今天在一臺新的服務器中安裝了php7.2,mysql-5.6后。測試用php連接mysql時發(fā)現(xiàn)無論如何php都連接不上mysql數(shù)據(jù)庫里逆,排除了數(shù)據(jù)庫賬號錯誤进胯,并且php已經安裝了連接數(shù)據(jù)庫的mysqlnd擴展。
問題排查
使用php連接測試腳本原押,查看到底是什么錯誤導致php連接不上mysql的胁镐。
以下是php連接mysql的php測試腳本mysql_connect_test.php
<?php
$dbname = 'mysql';
$dbuser = 'root';
$dbpass = '1234';
$dbhost = 'localhost';
$connect=mysqli_connect($dbhost, $dbuser, $dbpass, $dbname);
// 檢查連接
if (!$connect)
{
die("連接錯誤: " . mysqli_connect_error());
}
die("連接成功...\n");
?>
注意觀察php腳本中,$dbhost的值我給的是localhost诸衔,也就是使用socket進行連接數(shù)據(jù)庫盯漂。
經過測試,發(fā)現(xiàn)PHP報錯:No such file or directory in /root/mysql_connect_test.php on line 6
報錯說db-connect-test.php中的第6行有問題笨农,下面看下第8行的代碼:
$connect=mysqli_connect($dbhost, $dbuser, $dbpass, $dbname);
mysqli_connect()
這是php連接數(shù)據(jù)庫的一個函數(shù)就缆,根據(jù)報錯提示這里面缺少文件或目錄。
mysqli_connect()
函數(shù)的參數(shù)有:host磁餐,username违崇,password,dbname诊霹,port羞延,socket。
在mysqli_connect()函數(shù)中脾还,我已經加入了host伴箩,username,password鄙漏,dbname這4個參數(shù)了嗤谚。
經過調試,發(fā)現(xiàn)當我加入socket和port參數(shù)時怔蚌,php就可以正常連接數(shù)據(jù)庫了巩步。
下面是加入了socket參數(shù)后的php腳本:
<?php
$dbname = 'mysql';
$dbuser = 'root';
$dbpass = '1234';
$dbhost = 'localhost';
$dbport = '3306';
$dbsocket = '/tmp/mysql.sock';
$connect=mysqli_connect($dbhost, $dbuser, $dbpass, $dbname, $dbport, $dbsocket);
// 檢查連接
if (!$connect)
{
die("連接錯誤: " . mysqli_connect_error());
}
die("連接成功...\n");
?>
到這里可以分析出,php連接數(shù)據(jù)庫的失敗的原因很可能是數(shù)據(jù)庫socket連接造成的桦踊。
為了證明這個結論椅野,讓PHP使用TCP/IP連接數(shù)據(jù)進行測試:
<?php
$dbname = 'mysql';
$dbuser = 'root';
$dbpass = '1234';
$dbhost = '127.0.0.1';
$connect=mysqli_connect($dbhost, $dbuser, $dbpass, $dbname);
// 檢查連接
if (!$connect)
{
die("連接錯誤: " . mysqli_connect_error());
}
die("連接成功...\n");
?>
測試結果如下,可以看到使用TCP方式連接是可以成功的籍胯。
解決問題
- 查看mysql的socket文件
可以看到mysql使用的socket是/tmp/mysql.sock
mysql> show variables like "socket";
+---------------+-----------------+
| Variable_name | Value |
+---------------+-----------------+
| socket | /tmp/mysql.sock |
+---------------+-----------------+
1 row in set (0.00 sec)
- 查看php默認使用的mysql socket
發(fā)現(xiàn)php默認使用的mysql socket是 /var/mysql/mysql.sock
[root@centos ~]# php -r 'echo phpinfo();' | grep mysql.sock
mysqli.default_socket => /var/lib/mysql/mysql.sock => /var/lib/mysql/mysql.sock
pdo_mysql.default_socket => /var/lib/mysql/mysql.sock => /var/lib/mysql/mysql.sock
經過對比竟闪,發(fā)現(xiàn)php和mysql指定的數(shù)據(jù)庫socket文件路徑不一樣,這可能也就是導致php在使用socket連接數(shù)據(jù)庫時出錯的原因杖狼。
這里先給出2個解決辦法:
- 方法一:修改mysql的配置文件炼蛤,配置socket與php的一致
[root@centos ~]# mkdir -p /var/lib/mysql
[root@centos ~]# vim /etc/my.cnf
[mysqld]
socket = /var/lib/mysql/mysql.sock
- 方法二:修改php的配置文件,配置socket與mysql的一致
更改php.ini中的 mysql.default_socket
蝶涩、mysqli.default_socket
理朋、pdo_mysql.default_socket
絮识。但在PHP72版本中,php.ini配置文件中沒有mysql.default_socket
嗽上,可以不進行設置此條配置笋除。
[root@centos ~]# vim /etc/php.ini
mysqli.default_socket = /tmp/mysql.sock
pdo_mysql.default_socket = /tmp/mysql.sock
PHP72安裝完后,會在bin目錄下生成php-config炸裆、zts-php-config兩個腳本文件,這連個腳本用于獲取所安裝的php配置的信息鲜屏。這2個腳本中的socket路徑也只默認為/var/lib/mysql/mysql.sock
修改腳這兩個文件來制定mysql socket(可選烹看,非必須修改):
[root@centos ~]# sed -i 's@--with-mysql-sock=/var/lib/mysql/mysql.sock@--with-mysql-sock=/tmp/mysql.sock@g' /bin/php-config
[root@centos ~]# sed -i 's@--with-mysql-sock=/var/lib/mysql/mysql.sock@--with-mysql-sock=/tmp/mysql.sock@g' /bin/zts-php-config
修改完配置再重啟php-fpm后,php就可以使用socket的連接方式連接數(shù)據(jù)庫了洛史。