執筆背景
どうも、直人と申します。
現在、自分はlaravelの学習を兼ねて簡単なアプリを作成しようと試みています。
その第一段階として、
昨日VirtualBoxとVagrantを使用してlaravelの開発環境を構築し終えた。
なので、
今日はMVCモデルの学習とMySQL上のデータベースにテーブルを作成し、そこから値を拾ってきて表示するところまでを終わらせよう
と考えていた。
MVCモデルについて一通り学習を終え早速テーブルを作成しようと以下のコマンドを打つ。
$ php artisan make:migration create_books_table
create_books_taqble.phpが作成されるので、ファイル内の以下の部分をデフォルトから変更した。
Schema::create('books', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('image');
$table->string('author');
$table->string('local');
$table->timestamps();
});
その後、テーブルを作成しようと
$ php artisan migrate
コマンドを実行すると、以下のエラーが発生した。
Illuminate\Database\QueryException
SQLSTATE[HY000] [1045] Access denied for user 'root'@'localhost' (using password: YES) (SQL: select * from information_schema.tables where table_schema = Homestead and table_name = migrations and table_type = 'BASE TABLE')
at vendor/laravel/framework/src/Illuminate/Database/Connection.php:670
666| // If an exception occurs when attempting to run a query, we'll format the error
667| // message to include the bindings with SQL, which will make this exception a
668| // lot more helpful to the developer instead of just the database's errors.
669| catch (Exception $e) {
> 670| throw new QueryException(
671| $query, $this->prepareBindings($bindings), $e
672| );
673| }
674|
+34 vendor frames
35 artisan:37
Illuminate\Foundation\Console\Kernel::handle()
何故かアクセスが拒否された。
これについての対処方法を以下で述べる。
結論
laravel5.8以降の.envファイル(データベースにアクセスするためのパスワードとか設定されてる)では、
#を文字として認識しない仕様であり、私が設定していたパスワードには#が使われていたため、パスワードをダブルクォーテーションで括ることでmigrateすることができた。
作業内容
以下では、実際の作業内容を綴っていきます。
PHPのバージョンの違いを疑う
ホスト側のPHPとゲスト側のPHPのバージョンが異なるために不具合が生じているのではないかと考え両者のバージョンを確認してみると異なることを確認した。
#ホスト側
$ php -v
PHP 7.1.23 (cli) (built: Feb 22 2019 22:19:32) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.1.0, Copyright (c) 1998-2018 Zend Technologies
#ゲスト側
$ php -v
PHP 7.4.4 (cli) (built: Mar 19 2020 20:12:35) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
with Zend OPcache v7.4.4, Copyright (c), by Zend Technologies
そのため、ホスト側のPHPのバージョンをアップグレードすることにした。
具体的には、brewでインストールしたのち、パスを通して再起動するということを行なっている。
$ brew install php@7.4
$ echo 'export PATH="/usr/local/opt/php@7.4/bin:$PATH"' >> ~/.bash_profile
$ echo 'export PATH="/usr/local/opt/php@7.4/sbin:$PATH"' >> ~/.bash_profile
$ brew services start php
結果、直らなかった…。
デフォルトで作成されるrootユーザを疑う
$ mysql -u root -p
上記の方法であれば、mysqlに接続することができた(パスワードは.envファイルに記載されているものと同じ)。
mysql -u root -pで入力したユーザ名とパスワードは.envファイルに記載されていた同じなのに、何故php artisan migrateコマンドからではアクセスが拒否されたのか
ということに着目し調べてみることにした。
mysqlからuserの一覧を表示すると、デフォルトで作成されたと思われるroot@0.0.0.0ユーザと自分で作ったroot@localhostの二種類が存在することが判明。
これが原因ではないかと思い、デフォルトで作成されているroot@0.0.0.0ユーザを削除してみることにした。
#変更前
mysql> SELECT Host, User FROM mysql.user;
+-----------+------------------+
| Host | User |
+-----------+------------------+
| 0.0.0.0 | root |
| localhost | root |
+-----------+------------------+
#変更後
mysql> drop user root@0.0.0.0;
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT Host, User FROM mysql.user;
+-----------+------------------+
| Host | User |
+-----------+------------------+
| localhost | root |
+-----------+------------------+
しかしながら直らなかった…。
laravel本体を疑う
さらに色々深く調べてみると以下の記事を発見。
→ https://qiita.com/kotatsu0715/items/a8d3a93c4a46ca925fc4
要約すると、
laravel5.8以降の.envファイルでは#を文字として認識しないため、パスワードに#を使っている人はダブルクォーテーションを使いましょう
というものだった。
私のデータベースのパスワードには見事に#が使われていたため、試しにダブルクォーテーションで括ってテーブルの作成を再実行してみた。
DB_PASSWORD="#hoge"
php artisan migrate
Migration table created successfully.
うまくいった!