Laravel の .env の値は config() 経由で使う
TL;DR
env()
は コントローラー, モデル, etc.. 内で直接使わない。config/*.php
にenv()
の値を入れてconfig()
から参照する。
例
<?php // config/my-app.php return [ // configに.envの内容を入れる。 'my-env' => env('MY_ENV'), ];
<?php // コントローラー内など // config() を使用。 $my_env = config('my-app.my-env'); // これはダメなパターン。 $my_env = env('MY_ENV');
何故 env() を使ってはいけないのか
本番環境でconfig:cache
コマンドを実行した際、.env
ファイルを読み込まないから。
.env
ファイルはIlluminate\Foundation\Bootstrap\LoadEnvironmentVariables
クラスのbootstrap()
で読み込まれるのですが、読み込む前にconfigのキャッシュの有無を確認し、キャッシュがあった場合は.env
ファイルを読み込まない仕様になっています。
当該部分のLaravelのコードを引用。
<?php // 省略 public function bootstrap(Application $app) { if ($app->configurationIsCached()) { return; } $this->checkForSpecificEnvironmentFile($app); try { (new Dotenv($app->environmentPath(), $app->environmentFile()))->load(); } catch (InvalidPathException $e) { // } catch (InvalidFileException $e) { die('The environment file is invalid: '.$e->getMessage()); } } // 省略
大体の場合の本番環境では、高速化の為に設定を一纏めにするconfig:cache
コマンドを実行すると思うのですが、前述の通りキャッシュがあると.env
が読み込まれないので、env()
を直接叩いてると開発時やテスト時には動くけど本番環境で死ぬ。といった事になります。(実際なった)
実際に試す
適当なコントローラーを用意してdd
を使って値をダンプするだけ。
<?php class HogeController extends Controller { public function getHoge() { dd( env('MY_ENV'), config('my-app.my-env') ); } }
まずはキャッシュ無しでアクセス。
"Foo" "Foo"
テスト環境や開発環境と同じ様にキャッシュを作成していないのでどちらも同じ値が取得できます。
次にキャッシュさせてアクセス。artisan
のconfig:cache
を実行してbootstrap/cache/config.php
を作成します。
php artisan config:cache
で、先ほどと同じ様にアクセスしてみる。
null "Foo"
.env
ファイルが読み出されていないのでenv()
で取得した所で値が入ってる訳もなくnull
を返します。
と言う訳で最初に書いた通り、env()
は直接使わずにconfig()
に.env
の値を入れて使いましょう。
iTunesの音楽とプレイリストをWALKMANに入れる
一ヶ月ほど前、iPodの容量不足に伴い音楽プレイヤーをiPodからWALKMANのNW-A47に完全に移行しました。
iTunesの音楽やプレイリストをWALKMANに移行する方法は調べれば大量に出てくるものの、その方法でやると管理が面倒…ってのが沢山だったのと、色々躓く所があったので、自分的に管理がしやすい方法を書きます。
音楽ファイルの移行
音楽ファイル(flac, alac, mp3, aac など)をWALKMANに転送します。
ジャケットの設定
ファイルを転送する前にしておきたいのがジャケット(iTunesではアートワーク)の設定。WALKMANでジャケットが表示されなくても良いと言う方はやる必要無し。
iTunesではCDを取り込むと自動でジャケットを検索して設定してくれる便利な機能がありますが、この機能は実際にファイルにジャケットを設定してる訳ではなく、ジャケットを取得して別ファイルに保存してiTunesで表示する時のみジャケットを出しているだけです。(この方が音楽ファイルのサイズを削減出来る。)
なのでこのまま転送するとWALKMANではジャケットが表示されません。
そして更に厄介なのがWALKMANでジャケットを表示する場合はジャケットの形式がベースラインJPEGである必要がある事。手動で設定した画像がPNGやプログレッシブJPEGだと表示されません。
これを解決する為には手動でジャケットを設定する必要があります。
iTunesで購入した曲に関しては最初からベースラインJPEGでジャケットが設定されています のでやる必要がありません。CDから取り込んだ曲、インターネットからダウンロードした曲などのみ設定します。
方法は色々あるのですが、楽なのが既に入ってるジャケットを変換する方法。iTunesが勝手に持ってきた時や既にジャケットを手動で設定した時はこれが楽です。
話が逸れますが、音楽はiTunesにあるのにジャケットが自動で取得されなかった場合はブックマークレットを使って取得すると楽です。
話を戻してジャケットの設定。
アルバムを指2本クリックして「アルバムの詳細」を開き、ジャケットをデスクトップに放り投げて変換したものを再度設定するだけ。
- ジャケットの取り出しと削除。
これで保存するとWALKMANでもジャケットが表示されるようになります。
ファイルの移動
SONYのサイトには
iTunesの楽曲リストから転送したい楽曲を選択して、ウォークマンの[MUSIC]フォルダーにドラッグ&ドロップするだけです。
と書いてあります。
実際出来るのですが、これでやると曲の数が増えるとファイルを探しにくくなる、曲名と番号が被った際に入れられなくなる等の問題が起きます。
と言う訳で、iTunesライブラリから直接持ってきて整理しやすくします。
ファイルは全て/MUSIC/Music/
へ入れました。コピーすると/MUSIC/Music/アーティスト名/アルバム名/音楽ファイル
の構成になります。/MUSIC/
へ直接入れると既にあるディレクトリ(MUSICCLIP
とNWWM_REC
)と混ざると厄介なのと、後述のプレイリストのファイルも探しにくくなるためです。
WALKMANでは音楽ファイルを/MUSIC/
ディレクトリから8階層まで辿ってくれます。無駄にサブディレクトリを掘りすぎると8階層を超えるので、ディレクトリの掘りすぎにだけ注意が必要です。(上記の方法では4階層。音楽の管理がiTunes単一ならそこまで深く掘る必要はないですが…)
参考までに自分の場合の構成。Music
にiTunesから持ってきた音楽ファイル、Playlist
には後述のプレイリストファイルを格納。
実際に移行します。
まず始めにiTunes Mediaの位置を確認します。この位置はプレイリストを入れる時に必要になるので、プレイリストを入れる場合は適当な場所にメモしておきます。
iTunesの環境設定の詳細を開く。
"iTunes Media"フォルダの場所
をコピーしておきます。FinderでiTunes Mediaを開く。
Command + Shift + G
でパスを入力すると楽です。移動したら音楽ファイルが入っている
Music
ディレクトリへ。アーティスト名/アルバム名/音楽ファイル
の構造で入っています。タブや新しいウィンドウでWALKMANを開く。
WALKMAN側の音楽ファイルを入れるディレクトリに移動し、ファイルをコピー。自分の場合は
Music
ディレクトリを掘ってそこへ入れたので、/MUSIC/Music/
へコピーしました。
コピーした後の/MUSIC/Music/
これでファイル移動は完了。
プレイリストを移行
既にiTunesにあるプレイリストを変換して内容をそのまま持ってきます。
プレイリストのエクスポート
iTunesでプレイリストを開いてm3u
形式でエクスポートし、適当な作業ディレクトリに保存します。
ファイル -> ライブラリ -> プレイリストを書き出し
をクリック保存。フォーマットはM3Uを選択します。
- ちなみにWALKMANで表示されるプレイリスト名はこのファイル名となります。
文字コードの変換とパスの置き換え
プレイリストをエクスポートしてそのままWALKMANに入れても文字コードや音楽ファイルのパスが合わないので何も表示されません。
エディターなり何なりで開いて変換と置き換えでも出来ますが、自分は面倒なので適当なスクリプトを書いてプレイリストを更新する度に手動で実行しています。
プレイリストの文字コードをUTF-8へ変換 & パスを置き換えるスクリプト。ruby convert-playlist.rb
でsrc
に存在する10分以内に更新されたm3u
ファイルをdist
へコピーして全て変換 & 置き換え。
itunes_path
とreplace_to
は自分のを入れてください。また、replace_to
は音楽ファイルが絶対パスになるようなパスに。相対パスだとプレイリストファイルの位置によって音楽ファイルを読み込まなくなります。
convert-playlist.rb
#!/usr/bin/env ruby # frozen_string_literal: true require 'pp' require 'fileutils' # Copy settings src_dir_path = File.join(__dir__, 'src') dist_dir_path = File.join(__dir__, 'dist') ext = '*.m3u' # 10min (60sec * 10min) interval = 60 * 10 # Replace settings itunes_path = '/Volumes/UNTITLED/Music/iTunes/iTunes Media/Music/' replace_to = '/MUSIC/Music/' encode_from = Encoding::UTF8_MAC itunes_path_regexp = Regexp.new(itunes_path) puts "Copy playlist files from #{src_dir_path} to #{dist_dir_path}" Dir .glob(File.join(src_dir_path, ext)) .sort .select { |playlist_file| last_mod = File.mtime(playlist_file) Time.now - last_mod <= interval } .tap { |playlist_files| pp playlist_files puts FileUtils.cp(playlist_files, dist_dir_path) } puts 'Replace the playlist file contents' Dir .glob(File.join(dist_dir_path, ext)) .sort .tap { |playlist_files| pp playlist_files } .each { |playlist_file| puts "Read #{playlist_file}" playlist_content = File.read(playlist_file).encode(Encoding::UTF_8, encode_from) puts 'Replace paths' # Replace new lines and paths. new_playlist_content = playlist_content.gsub(/\r/, "\n").gsub(itunes_path_regexp, replace_to) puts 'Override playlist file' File.open(playlist_file, 'w') do |f| f.write(new_playlist_content) end puts }
m3uファイルの移動
/MUSIC/
フォルダの下にm3u
ファイルをコピー。絶対パスで書いている限り、8階層以内ならどこに置いても同じです。
自分の場合は前述の通り音楽ファイルとの混合を防ぐ為、/MUSIC/Playlist/
へ入れました。
WALKMANをPCから取り出す
PCから取り出します。外すとWALKMANがデータベースを作成します。
音楽、プレイリストが全てコピー出来ていれば完了です。