PHPでデータベースに接続をするときに、抽象化レイヤーの「PDO」を使う方も多いかと思います。

が、(私含め)使い慣れていないとしょっちゅうエラーが出るややこしい部分でもあるので、よくあるエラーを備忘録として書き残しておこうかと思います。

環境について

この備忘録作成時点の私の環境について。

・OS : MacOS

・PHP: 8.3

・DB: MySQL(PHP ver8.2

よくお会いするエラー

⚫︎エラー1:

SQLSTATE[HY000] [2002] No such file or directory

⚫︎エラー2:

SQLSTATE[HY000] [2002] Connection refused

⚫︎エラー3:

SQLSTATE[HY000] [1045] Access denied for user 'user'@'localhost' (using password: YES)

⚫︎エラー4(おまけ):

SQLSTATE[HY000] [1049] Unknown database 'my_database'

私がよく遭遇するのはこの辺りでしょうか。

これについてそれぞれの(その時点の)コードと、解決方法を備忘録として残しとくので、もし同じようなエラーに遭遇した方の助けになれば幸いです。

正常動作したコードとポイント

// PDOでDBに接続するための準備
$dsn = 'mysql:dbname=sample;host=localhost;charset=utf8;unix_socket=/Applications/MAMP/tmp/mysql/mysql.sock';
$user = 'root';
$pass = 'root';

try{
    $db = new PDO($dsn, $user, $pass);
    echo '接続成功!';
}catch(PDOException $e){
    echo $e->getMessage();
}

この状態だと、例外処理の「接続成功!」が表示されました。

ちなみに環境によっては、「rootユーザー」や「パスワード」を変更しているかと思いますが、今回は「root」としています。

DB名:sample

User名:root

パス:root

という状態で、PDOでDBに接続している。って感じです。

そのあたりは適宜読み換えてください。

後述するエラーになるポイントを先にまとめるとこんな感じです。

大体これ(私の場合)

・host="localhost"で接続する際に必要となるUNIX socketが設定されていない。dsnにぶっ込んでない。

・host="127.0.0.1"でTCP/IPで接続しようとするとエラー。なので「host=localhost」にしちゃう。

そもそも設定したユーザー名・パスワード・DBじゃない。

SQLSTATE[HY000] [2002] No such file or directoryについて

これが出た時点のコードは以下。

// PDOでDBに接続するための準備
$dsn = 'mysql:dbname=sample;host=localhost;charset=utf8';
$user = 'root';
$pass = 'root';

try{
    $db = new PDO($dsn, $user, $pass);
    echo '接続成功!';
}catch(PDOException $e){
    echo $e->getMessage();
}

エラー内容にもあるように「ファイルが見つかりません。」系のエラーですよね。

調べてみると、UNIX socket のパスが違うかもってことか。となりました。

ってことでとりあえず、UNIX socketのパスを見てみる。

$ mysqladmin -u root -p version

(省略)

UNIX socket		/Applications/MAMP/tmp/mysql/mysql.sock

このパスと違えば接続できないわな。と納得し、php.iniを調べてみるが、上記のパスになってる。ん〜。

答え的には「UNIX socketをdsnに設定してない」ことが原因で、それをすれば解決するパターンでした。

SQLSTATE[HY000] [2002] Connection refusedについて

この時点でのコードは以下の感じ。

// PDOでDBに接続するための準備
$dsn = 'mysql:dbname=sample;host=127.0.0.1;charset=utf8';
$user = 'root';
$pass = 'root';

try{
    $db = new PDO($dsn, $user, $pass);
    echo '接続成功!';
}catch(PDOException $e){
    echo $e->getMessage();
}

接続が拒否された。という内容のエラー。ざっくり過ぎて何が原因か分かりにくい。

これに関しては色々調べたけど「環境変数が違う」とか「MySQLのアドレスが違う」とかあって。

とりあえず、IPアドレスを調べてみたりする。。

cat /etc/hosts
##
# Host Database
#
# localhost is used to configure the loopback interface
# when the system is booting.  Do not change this entry.
##
127.0.0.1	localhost
255.255.255.255	broadcasthost
::1             localhost

IPアドレス調べても127.0.0.1で合ってるからなぁ。。。って感じだったので今回は「host=localhost」に戻しました。

そして結局エラー1と同様、「UNIX socket」をdsnに突っ込むことで先に進めたので、UNIX socketのパスを明示的にしてあげたほうがいいのかな。って感じでした。

(以前やった時は、設定さえちゃんとなっていれば「unix_socket=パス」は不要だったんだけどな・・・。バージョンによるものとかかな)

エラー3と4ついて

このエラーが出る時点のコードは以下の感じ。

// PDOでDBに接続するための準備
$dsn = 'mysql:dbname=my_database;host=localhost;charset=utf8;unix_socket=/Applications/MAMP/tmp/mysql/mysql.sock';
$user = 'user';
$pass = 'password';

try{
    $db = new PDO($dsn, $user, $pass);
    echo '接続成功!';
}catch(PDOException $e){
    echo $e->getMessage();
}

ここまでくれば大体わかりそうなもんですが、一応。

単純に「設定しているユーザー名/パスワード/DBの名前が違うぞ。」というエラーです。

なのでこの辺りはあなたの環境に合わせて適宜変更していただければ解決するはずです

ちなみに環境によっては

$dsn = 'mysql:dbname= my_database; host= localhost; charset= utf8; unix_socket= /Applications/MAMP/tmp/mysql/mysql.sock';

のように、(わかりにくいですが)スペースが入っていることでエラーになることもあるようなので、この辺りも注意が必要。

まとめ

正直、LaravelとかのFW使っていると、DBへの接続もこんなに煩雑ではないので。

ついつい忘れてしまいがちなのですが、PDOなりを使用してDBに接続する時にこんな感じのエラーで上手くいかない!

ってことも多々あるので、今回は備忘録がてら残してみました。

ゆたんぽ

PDO→DBは初心者には訳わからなくなる部分ですよね。。

ぬこ先生

誰かの役に立ってくれたら嬉しいニャ