非常につまらないことで半日以上無駄にしたので、愚痴のつもりで書きます。
##要約
.envに設定値を書くときは、""でクォートしておけ!特に記号が含まれる文字列は!
※おそらくPHPとRubyに適用される話だと思います。その他の環境についてはわかりません。
##語り
他社さんにDBを構築してもらって、接続用のIDとパスワードを受け取りました。
今回、このパスワードに # が含まれていました。
DB_PASSWORD=hoge#fuga
という設定を.env に記入して php artisan migrate を実行したところ、エラーが発生。
SQLSTATE[HY000] [1045] Access denied for user 'USERNAME'@'XXX.XXX.XXX.XXX' (using password: YES) (SQL: ...省略)
おかしいなと思い mysql コマンドで接続を試みたところ、特に問題なし。設定ミスや伝達ミスの線は消えました。
.env の設定値を見直しても問題なし。この時点で何だこりゃ?となるわけです。
試しにconfig/database.php 内にパスワードを書いてみたところ、問題なく php artisan migrate が実行できました。こりゃ .env から読み込むところがおかしいんだろう、おそらく#以降がコメント扱いなっておるんじゃろうと推測しました。
で、.env の記述を
DB_PASSWORD="hoge#fuga"
としてやったら .env 側の設定だけで php artisan migrate が動いた、というわけです。
ここまでで半日経ってます。
※まぁ、こればかりやってたわけじゃないですが
##.envってどう処理されてるの?
Laravel は PHP dotenv というライブラリを使って .env を読み込んでいるようです。
https://github.com/vlucas/phpdotenv
このページを見ただけでは、#の扱いがよくわかりません。
サンプルが良くないですよね....
別のページでは#の前に空白があればコメントになるという記述も見かけました。
連続する文字列の中の#はコメントとして扱われない、ということですね。
結果的にはこの情報が間違っているわけですが、古い情報なので当時は正しかったのかもしれません。
リンクはしませんが....
PHP dotenv は Ruby dotenv の PHP版という立ち位置のようです。
https://github.com/bkeepers/dotenv
こちらのページには、#を含む文字列はクォートすればいいんだな、と判断できるサンプルが書かれています。
説明はこのように行うように心がけたいものです。
また、Laravel 添付の .env.example にも課題があるのではないかと思います。
設定値を "" でクォートしているものは .env内で定義した設定値を参照している箇所のみなので、
ここから .env に入った人は「設定値はベタ書きでいいんだ」と思うことでしょう。
かく言う自分も他の人が書いた .env を環境に合わせて設定していただけなので、今回のハマりを招いてしまったわけです。これが "" で囲まれているパスワードを置き換えるのであれば、なんの問題もなかったわけです。
※私自身の知識にはなんの増加もないことになりますが、そんなことより早く仕事を終わらせたいときだってありますよね
※そこは今回の自分の仕事の範囲じゃないんじゃよ...
ここから導かれる対策は2つ
・設定値に#を含めないようにせよ
・設定値はとにかく "" でクォートしておけ
前者の対応は論外なので、後者を推奨。
もちろん、何でもかんでもクォートしていると面倒だし、不要なところは省略していいと思うんですが、自分のようにうっかり # を書き込む羽目になってしまったような人のために、fool proof な書き方になっている方が良いですよね、って話です。
お付き合いありがとうございました。