PDO 接続までの流れ一覧

#はじめに

この記事を見ればMacのローカル環境に```MySQL```をインストールして、```PDO```を使いターミナル上で実行結果を表示させるまでの流れが分かります。
(※PHPはローカル環境にインストールされている前提です。)

環境は```PHP7.3.11``` 、```MySQL8.0.23```になります。

PHPを学習する中、現代は```MAMP```や```Docker Compose```での環境構築の方法が巷に溢れているせいでなかなか```MySQL```単体をローカルに入れて使用するという機会が少ないように思います。 また、```TablePlus```などのGUIツールの発展によりターミナルで完結させる機会も減ってきていると思うので改めて復習をしました。

##1、 HomebrewでローカルにMySQLがインストール済みか確認する
```
$ brew list
```

##2、 HomebrewでローカルにMySQLをインストールする (※ローカルにMySQLがインストールされていない場合)
```
$ brew install mysql
```
※もしインストールされていた場合は以下のコマンドでアンインストールできます。

```
$ brew uninstall mysql
```
##3、 MySQLのステータスを確認する
```
$ mysql.server status 
```
すると

```
$ mysql.server status
 ERROR! MySQL is not running
```
のように表示されます。

##4、 ローカルのMySQLを起動する
```
$ mysql.server start
Starting MySQL
.. SUCCESS! 
```
これでMySQLが立ち上がりました。


##5、ローカルのMySQLにrootユーザーでログインする
```
mysql -u root
```
すると以下の画面が出てログイン完了です。

```
$ mysql -u root
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 22
Server version: 8.0.23 Homebrew

Copyright (c) 2000, 2021, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
```

##6、 データベースの作成と使用するユーザーの作成
####a、今のデータベース一覧を確認

```
mysql> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.00 sec)
```

####b、使用するDBの作成
 ※ここではappdbとします

```
mysql> CREATE DATABASE appdb;
Query OK, 1 row affected (0.01 sec)

mysql> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| appdb              |
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.00 sec)
```

これで使用するデータベースの作成ができました。

####c、使用するユーザーを作成するために現段階のユーザーの確認

```
mysql>SELECT User, host, authentication_string FROM mysql.user;
+------------------+-----------+------------------------------------------------------------------------+
| User             | host      | authentication_string                                                  |
+------------------+-----------+------------------------------------------------------------------------+
| mysql.infoschema | localhost | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED |
| mysql.session    | localhost | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED |
| mysql.sys        | localhost | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED |
| root             | localhost |                                                                        |
+------------------+-----------+------------------------------------------------------------------------+
```
###d、新しいユーザーの作成
※ここではユーザー名が```appuser```でパスワードは```apuser999```とします。

```
mysql> CREATE USER 'appuser'@'%' IDENTIFIED BY 'apuser999';
Query OK, 0 rows affected (0.01 sec)

mysql> SELECT User, host, authentication_string FROM mysql.user;
+------------------+-----------+------------------------------------------------------------------------+
| User             | host      | authentication_string                                                  |
+------------------+-----------+------------------------------------------------------------------------+
| appuser          | %         | $A$005$;OM%#t5X(A4TRbY5temRxeZKSUBuOSywlJC89/FIII8hAQw1u0EQw4ILivP9 |
| mysql.infoschema | localhost | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED |
| mysql.session    | localhost | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED |
| mysql.sys        | localhost | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED |
| root             | localhost |                                                                        |
+------------------+-----------+------------------------------------------------------------------------+
5 rows in set (0.00 sec)
```

これで```appuser```の作成ができました。

###e、```appuser```に権限の付与を行う

```
mysql> GRANT ALL ON appdb.* TO 'appuser'@'%';
Query OK, 0 rows affected (0.00 sec)

mysql> SHOW GRANTS FOR 'appuser'@'%';
+----------------------------------------------------+
| Grants for appuser@%                               |
+----------------------------------------------------+
| GRANT USAGE ON *.* TO `appuser`@`%`                |
| GRANT ALL PRIVILEGES ON `appdb`.* TO `appuser`@`%` |
+----------------------------------------------------+
2 rows in set (0.00 sec)
```
これで```appuser```に全ての権限が付与されました。

###f, appuserでログインし直す
一度MySQLからログアウトします。

```
mysql> exit
Bye
```
次は```appuser```とパスワードでログインするため
以下のように入力

```
 mysql -u appuser -p
```
するとパスワードが求められるので、パスワードを入力

```
$ mysql -u appuser -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 25
Server version: 8.0.23 Homebrew

Copyright (c) 2000, 2021, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
```
ログインできました

##7、データベースの切り替えとテーブルの作成
####a、デフォルトでは何も指定はされていないので```appdb```に切り替える

```
mysql> SELECT database();
+------------+
| database() |
+------------+
| NULL       |
+------------+
1 row in set (0.00 sec)

mysql> USE appdb;
Database changed

mysql> SELECT database();
+------------+
| database() |
+------------+
| appdb      |
+------------+
1 row in set (0.00 sec)
```
###b、テーブルの作成
今回は```users```テーブルを作成し、人の名前を取り出せるような形にします。
(カラム名は```id```,```name```とします。)

```
mysql> CREATE TABLE users(id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(10));
Query OK, 0 rows affected (0.01 sec)

mysql> SHOW TABLES;
+-----------------+
| Tables_in_appdb |
+-----------------+
| users           |
+-----------------+
1 row in set (0.00 sec)

mysql> SHOW columns from users;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int         | NO   | PRI | NULL    | auto_increment |
| name  | varchar(10) | YES  |     | NULL    |                |
+-------+-------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)
```

usersテーブルが作成できました

###c、レコードを入れる
まとめて入れる方法もありますが、今回は1つ1つ入れていきます。

```
mysql> INSERT INTO users(name) VALUES ('Tanaka');
Query OK, 1 row affected (0.01 sec)

mysql> INSERT INTO users(name) VALUES ('Yamada');
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO users(name) VALUES ('Watanabe');
Query OK, 1 row affected (0.00 sec)

mysql> SELECT * FROM users;
+----+----------+
| id | name     |
+----+----------+
|  1 | Tanaka   |
|  2 | Yamada   |
|  3 | Watanabe |
+----+----------+
3 rows in set (0.00 sec)
```
これでテータの入力が完了しました

##8、PHPファイルを作成し、PDO接続を行う
```app.php``` ファイルを作成し、以下のように記載

```app.php
<?php
$dsn = 'mysql:host=127.0.0.1;dbname=appdb';
$user = 'appuser';
$password = 'apuser999';

try {
    $dbh = new PDO($dsn, $user, $password);
    echo "接続成功\n";
} catch(PDOException $e) {
    echo $e->getMessage();
    exit;
}

$sql = 'SELECT * FROM users';
$stmt = $dbh->prepare($sql);
$stmt->execute();
$users = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($users as $user) {
    echo $user['name'] . "さん\n";
}
```
実行

```
$php app.php
SQLSTATE[HY000] [2054] The server requested authentication method unknown to the client
```

とするとエラーがでてしまいます。

どうやら
```MySQL8.0.4```以降 のログイン認証方式は ```caching_sha2_password``` がデフォルトで
PHPのMySQL接続ライブラリが ```caching_sha2_password```　に未対応で接続不可らしいです。
そこで、認証方式を ```mysql_native_password``` に戻してあげます。
以下の記事が参考になりました。
https://qiita.com/ucan-lab/items/3ae911b7e13287a5b917

なのでまたrootユーザーでMySQLにログインします。

```
$ mysql -u root
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 28
Server version: 8.0.23 Homebrew

Copyright (c) 2000, 2021, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
```
プラグインを表示し、```mysql_native_password```に更新

```
mysql> SELECT user, host, plugin FROM mysql.user;
+------------------+-----------+-----------------------+
| user             | host      | plugin                |
+------------------+-----------+-----------------------+
| appuser          | %         | caching_sha2_password |
| mysql.infoschema | localhost | caching_sha2_password |
| mysql.session    | localhost | caching_sha2_password |
| mysql.sys        | localhost | caching_sha2_password |
| root             | localhost | caching_sha2_password |
+------------------+-----------+-----------------------+
5 rows in set (0.00 sec)

mysql> ALTER USER 'appuser'@'%' IDENTIFIED WITH mysql_native_password BY 'apuser999';
Query OK, 0 rows affected (0.01 sec)
```

※補足 
```php 7.4```以上であればこの作業は不要だそうです。(php更新しとくべきだった・・・)
https://mita2db.hateblo.jp/entry/2020/01/11/160736

そしてログアウトして再度実行すると

```
mysql> exit
Bye

$ php app.php
接続成功
Tanakaさん
Yamadaさん
Watanabeさん
```

無事接続と出力が完了です。