- 投稿日:2020-10-12T23:12:55+09:00
【PHP】strstr() と strtr() の合わせ技で、文字列内の複数文字を置換する
こんな時に使えます
とあるDBのテーブル内で、複数の要素(例でいうと、職業とステータス)が、
ひとつの文字列に連結されてしまっている場合に、
・分離して
・区切りに使われている記号を取り除いて
・取得ができる。
実例
$sample_text = "勇者[HP300]"分離する
$sample_text_extract = strstr($sample_text, '['); // 変数の中身は、[HP300]という文字列【解説】
strstr()
https://www.php.net/manual/ja/function.strstr.php第一引数:対象の文字列
第二引数:検索したい文字
返り値: 検索したい文字を含んだ、文末までの文字列区切りに使われている文字を取り除く
$replace = [ '[' => '', ']' => '' ]; $sample_text_trimmed = strtr($sample_text_extract, $replace); // 変数の中身は、HP300 という文字列【解説】
strtr()
https://www.php.net/manual/ja/function.strtr.php第一引数:対象の文字列
第二引数:置換before/after(※配列形式で複数指定可)※公式ドキュメントでは、小文字を大文字に置換するやり方が紹介されています。
バイト数の大きいものが優先される等ルールがあるようです。<?php $trans = array("h" => "-", "hello" => "hi", "hi" => "hello"); echo strtr("hi all, I said hello", $trans); ?> // 結果: hello all, I said hi引数を二つだけ渡す場合は、二番目の引数を array('from' => 'to', ...) 形式の配列にしなければなりません。 返される値は文字列で、もとの文字列中にある配列のキーと同じ部分を対応する値で置換したものとなります。 一番長いキーから順に調べます。一度部分文字列の置換を行うと、 置換後の文字列がさらに置換の対象となることはありません。
筆者コメント
私は、例のように、
・文字列が記号で囲まれて
・かつ他の文字列と連結して、
・ひとつのカラムに保存されている
というデータを取り出す必要性があり、この合わせ技を使いました。
他にもいろんな使い方ができそうですので、何かのヒントになれば幸いです。
- 投稿日:2020-10-12T21:45:22+09:00
LaravelでMVCを利用してとりあえず表示させてみる
【概要】
1.ルーティングの設定
2.コントローラーの設定
3.ビューの設定
4.開発環境
1.ルーティングの設定
routes/web.phpRoute::get('hoge', 'App\Http\Controllers\HogeController@index' );ここで、Route::get('hoge', 'HogeController@index' );とすると、
”Target class [HogeController] does not exist”となってしまうので、最初からパスをコーディングしました。
2.コントローラーの設定
app/Http/Controllers/HogeControllers.php<?php namespace App\Http\Controllers; use Illuminate\Http\Request; class HogeController extends Controller { public function index() #---❶ { return view('hoge.index'); #---❷ } }❶:ここでindexアクションを定義しています。
❷:hogeフォルダのindex.phpファイルに返り値としてレンダリングするようにしています。
3.ビューの設定
resources/views/hoge/index.php<html> <head> <title>Hoge/Index</title> </head> <body> <h1>Index</h1> <p>HOGEHOGE</p> </body> </html>簡単なHTML文しか書いていません。
「blade」テンプレートエンジンはまた後日説明します。
1~3を通じて下記が表記できます。
http://localhost:8000/hoge4.開発環境
PHP 7.4.10
Laravel 8.9.0
Apache 2.4.41
- 投稿日:2020-10-12T17:44:43+09:00
【PDO】複文禁止オプションの注意点(ATTR_EMULATE_PREPARES)
環境
OS:CentOS 7.3
PHP:7.1.21
mariadb:10.1.22概要
PDOで PDO::ATTR_EMULATE_PREPARES を
false
にすると、
(機能のひとつとして)セミコロンでつなげたSQL(複文)を禁止できるようですが、
コメント(--) の部分は複文として検知してくれないようです。※ 以下、query() メソッド使用。
$sql .= "select * from table1;\n"; $sql .= "select * from table2;\n"; //検知してくれる OK You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'select * from table2' at line 2$sql .= "select * from table1;\n"; $sql .= "-- select * from table2;\n"; //検知しなかった???$sql .= "select * from table1;\n"; $sql .= "-- select * from table2;\n"; $sql .= "select * from table3;\n"; //これは検知するけど3行目なんだ・・・ You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'select * from table3' at line 3まとめ
複文禁止といっても「有効なSQLの複文」を禁止するみたいで、
コメント行は有効なSQLでないということなのでしょう。コメント(--) を使ったSQLインジェクションがありますが、
PDO::ATTR_EMULATE_PREPARES の設定だけでは不十分ということですね。コメント使用の攻撃に対しては、
プリペアドステートメントを併用して防ぎましょう。
- 投稿日:2020-10-12T17:23:48+09:00
Moodle 3.9 マニュアル - コースカテゴリ
コースカテゴリーは、すべてのMoodleサイト参加者のためのコースを編成します。新しいMoodleサイトのデフォルトのコースカテゴリは「その他」です(これは名前を変更できます)。コースの作成者、管理者、またはマネージャは、すべてのコースをその他のカテゴリに入れることができます。ただし、教師と生徒は、説明的なカテゴリに分類されていると、クラスを見つけやすくなります。
カテゴリ内のコースのリストには、デフォルトで教師と各コースの概要が表示されます。カテゴリ内のコース数が9(10以上)を超える場合、教師と要約のない短いリストが表示されます。
内容
1 カテゴリの追加
2 カテゴリの編集または移動
3 サブカテゴリの追加
4 カテゴリを非表示
5 カテゴリの並べ替え
6 カテゴリの深さの設定
7 コースカテゴリでのユーザーの役割の割り当て
8 関連項目
8.1 スクリーンキャスト1 カテゴリの追加
ほとんどの人は、学部や大学ごと、またはトピックごとにコースを編成しています。後でコースを移動する時間を節約するために、多数のコースに入る前に、必ず少数のユーザーで組織スキームをテストしてください。
カテゴリの追加は非常に簡単です。
・[管理]> [サイト管理]> [コース]> [カテゴリの追加]に移動します
・必要な詳細を入力し、[カテゴリの作成]をクリックします。
・または、[管理]> [サイト管理]> [コース]> [コースとカテゴリの管理]に移動し、[新しいカテゴリの作成]リンクをクリックすることもできます。
・カテゴリページを表示している場合(またはコースカテゴリレベルで管理者権限しかない場合)は、ページの右上にある[コースの管理]ボタンをクリックしてから、[新しいカテゴリの作成]リンクをクリックします。カテゴリが表示されている場合、ユーザーがカテゴリに入ると、コースのリストの上にコースカテゴリの説明が表示されます。
2 カテゴリの編集または移動
・コースカテゴリの詳細は、[管理]> [サイト管理]> [コース]> [コースとカテゴリの管理]で名前の横にあるアクションアイコンをクリックして編集できます。 「編集」を選択します。
・移動するカテゴリの横にある上/下矢印をクリックすると、カテゴリを上下に移動できます。名前の左側にあるチェックボックスをオンにしてから、ドロップダウンから[選択したカテゴリを移動する]を選択すると、カテゴリを一括移動できます。3 サブカテゴリの追加
・コースのサブカテゴリがあると便利な場合があります。たとえば、カテゴリ「科学」があり、サブカテゴリ「生物学」、「化学」、「物理学」が必要な場合があります。
・名前の左側にあるチェックボックスをオンにして、ドロップダウンメニューから[選択したカテゴリを移動する]を選択すると、あるカテゴリを別のカテゴリのサブカテゴリにすることができます。次のアクションアイコンをクリックすると、新しい空のサブカテゴリを作成できます。 [管理]> [サイト管理]> [コース]> [コースとカテゴリの管理]でその名前に変更します。 [新しいサブカテゴリを作成する]を選択します。4 カテゴリを非表示にする
・カテゴリは、[管理]> [サイト管理]> [コース]> [コースとカテゴリの管理]を選択し、非表示にするカテゴリの「目」アイコンをクリックすると、簡単に非表示または表示できます。非表示のカテゴリは、サイト管理者または「非表示のコースを表示する」機能を持つ管理者にのみ表示されます。
5 カテゴリの並べ替え
カテゴリは、[管理]> [サイト管理]> [コース]> [コースとカテゴリの管理]から、名前またはID番号の昇順/降順で並べ替えることができます。
カテゴリ内のコースも並べ替えることができます。新しいコースの追加を参照してください。
6 カテゴリの深さを設定する
[管理]> [サイト管理]> [フロントページ]> [フロントページの設定]から、フロントページの[カテゴリのリスト]または[コンボリスト]に表示されるカテゴリの数を制限できます。より深いレベルのカテゴリがリンクとして表示され、ユーザーはそれらを展開できます。
7 コースカテゴリでのユーザーの役割の割り当て
カテゴリレベルでマネージャを割り当てるには、カテゴリレベルでマネージャの役割を割り当てるを参照してください。
カテゴリ全体で教師または生徒の役割を登録するには、カテゴリの登録を参照してください。
8 関連項目
8.1 スクリーンキャスト
Moodleフォーラムディスカッションの使用:
- 投稿日:2020-10-12T17:16:39+09:00
【Laravel】いろいろ見たけどリポジトリパターンの実装ができなかった初心者のためにとりあえず実装するまでをシンプルに書く
3行で
- UserのModelに紐づいたリポジトリパターンを実装する
- コントローラではModelにタッチしないということを意識する
- 5つのファイルをいじる
リポジトリファイルを作る
ディレクトリ
/app
の中にRepositories
というディレクトリを作り、さらにその中にUser
というディレクトリを作り、この中にファイルを2つ作ります(この辺の構成は正直自由ですが)。
- /app/Repositories/User/UserRepository.php(実装ファイル)
- /app/Repositories/User/UserRepositoryInterface.php(インターフェイス)
この2つのファイルでModelを経由してDBにアクセスして、データを持ってきたりcreateしたりupdateしたりします。
今回はUser Modelに紐づくリポジトリパターンを作ります。つまりこれらを使ってUserのデータを持ってきたり更新したりします。コントローラではなく、これらのファイルで行うことになります。1. 実装クラス
UserRepository.php<?php // Modelに紐づく2つのメソッド以外はコピペのような感覚で書いちゃって構わないです namespace App\Repositories\User; // Modelにアクセスする旨を書く use App\User; class UserRepository implements UserRepositoryInterface { protected $user; /** * @param object $user */ public function __construct(User $user) { $this->user = $user; } // 名前に紐づくUserのデータを1件持ってくる public function getUser($name) { return $this->user->where('name', $name)->first(); } // 後述のコントローラから $request を受け取って、中に入った名前とメールアドレスでユーザーを作る public function createUser($request) { return $this->user->create([ 'name' => $request['name'], 'email' => $request['email'], ]); } }その他のメソッドは上記を応用して書いてみてください!
2. インターフェース
UserRepositoryInterface.php<?php // 上の実装クラスに書いた、Modelに紐づく2つのメソッドを書いて使えるようにします namespace App\Repositories\User; interface UserRepositoryInterface { public function getUser($name); public function createUser($request); }ServiceProviderに登録する
AppServiceProvider.php
を編集する。
ここにリポジトリのファイルを使うために登録するイメージです。
もしエラーが出たら以下の記事も見てみてください。AppServiceProvider.php<?php namespace App\Providers; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider { /** * Register any application services. * * @return void */ /** * Bootstrap any application services. * * @return void */ public function boot() { // } // インターフェースと実装クラスを登録 public function register() { // 本記事ではタッチしませんが記事用のリポジトリも登録しておきます $this->app->bind( \App\Repositories\Article\ArticleRepositoryInterface::class, \App\Repositories\Article\ArticleRepository::class ); $this->app->bind( \App\Repositories\User\UserRepositoryInterface::class, \App\Repositories\User\UserRepository::class ); } }コントローラでリポジトリを呼び出す
UserController.php<?php namespace App\Http\Controllers; // リポジトリを使うと宣言 use App\Repositories\User\UserRepositoryInterface; // コントローラではModelにタッチしない // use App\Models\User; use Illuminate\Http\Request; class UserController extends Controller { // リポジトリ protected $UserRepository; public function __construct( // リポジトリ UserRepositoryInterface $userRepository ) { // リポジトリ $this->UserRepository = $userRepository; } // 中略 public function show($name) { // リポジトリのメソッドに引数を渡して呼び出す $user = $this->UserRepository->getUser($name); return view('users.show', [ 'user' => $user, ]); } public function store($request) { // フォームから受け取った $request をリポジトリのメソッドに渡し、Userデータを作る $this->UserRepository->createUser($request); return redirect()->route('home'); } }以上です。
データが渡っているかがわからない、うまくいかない場合はdd($request)
などを使って検証してください!
- 投稿日:2020-10-12T16:41:54+09:00
クラスの関係をひと目で確認 PhpStormクラス図
[Something went wrong]()
私は仕事でPHP・Laravelを使用していますが、古くからある大規模システムなど、
ベリーファットなコントローラや無数のメソッドがあったり、追うのが大変なことがあります。
そのときにPhpStormの機能、UMLクラス図作成を使用すると便利です。どんな図?
継承元のクラスが青い実線で表示され、破線は依存関係(use 宣言)を示しています。
各クラスごとのメソッドをpublic, protectedに分けて表示してくれます。
2次元の図で表現することは、その情報を記憶しやすくする効果があります。人間の頭はイメージのほうが覚えやすいため、「形」で表現してあると、「2つのクラスの上に描かれていたスーパークラスがあったけど名前は何だっけ」というように、イメージの位置関係とあわせて内容が記憶しやすくなります。
平澤 章. オブジェクト指向でなぜつくるのか 第2版 (Japanese Edition) (Kindle Locations 3425-3429). Kindle Edition.
HOW
参照したいクラスを右クリックし、Diagrams > Show Diagramsを選択すると生成されます!
公式ページ
- 投稿日:2020-10-12T16:21:48+09:00
yps並走備忘録 Task4 WordPress環境構築
更新を大分サボってたので大分時間が経ってしまいましたが、Task 4の備忘録を思い出しつつ書いてみます。
ypsはLaravelでの開発がメインですが、今回はちょっと寄り道的なタスクでWordPressの構築を行います。事前準備
wgetがインストールされていない場合はインストールしましょう
sudo yum install wget -y
WordPressのセットアップ
※記事執筆時(2020/10/12)の最新版は5.5
tmpディレクトリに最新版のWPをダウンロードして解凍
1.cd /tmp
1
2.wget https://ja.wordpress.org/latest-ja.zip
3.unzip ./latest-ja.zip
ディレクトリを移動
4.mv wordpress '任意のディレクトリ名'
※任意の名前に変更(なるべく一般的な名前は避ける)
5.mv '任意のディレクトリ名' /var/www/html/
MySQLにWP用のデータベースを作成
6.mysql -u root -p
でMySQLにログイン以下MySQL Cliでの操作
7.create database '任意のDB名';
※データベース名はなるべく複雑なものの方がベター
8.grant all on ypswpdb.* to '任意のuser名'@localhost identified by '任意のパスワード';
データベースの権限を委譲しています
※ここで設定したユーザー名とパスワードを忘れてしまうと後々面倒なのでどこかにメモるなりしておく
9.設定し終わったらexit;
WP設定ファイルの更新
cd /var/www/html/yps-wp/
cp -p wp-config-sample.php wp-config.php
まずは下記を変更します。
define( 'DB_NAME', ' #7で設定したDB名' ); define( 'DB_USER', '#8で設定したuser名' ); define( 'DB_PASSWORD', '#8で設定したパスワード' );続いて下記を更新します。
更新時にはコメントにあるようにhttps://api.wordpress.org/secret-key/1.1/salt/ にアクセスすると自動でシークレットキーを生成してくれるので便利です(アクセスする度に新しいキーが生成されます)。
define( 'AUTH_KEY', 'put your unique phrase here' ); define( 'SECURE_AUTH_KEY', 'put your unique phrase here' ); define( 'LOGGED_IN_KEY', 'put your unique phrase here' ); define( 'NONCE_KEY', 'put your unique phrase here' ); define( 'AUTH_SALT', 'put your unique phrase here' ); define( 'SECURE_AUTH_SALT', 'put your unique phrase here' ); define( 'LOGGED_IN_SALT', 'put your unique phrase here' ); define( 'NONCE_SALT', 'put your unique phrase here' );最後に下記を更新します
$table_prefix = '任意の文字列_';
:wq
で保存したら一先ずWPの設定は完了ファイルとディレクトリのオーナー権限を変更
cd /var/www/html
sudo chown -R centos:nginx /var/www/html/wwpp/
sudo find /var/www/html/wwpp/ -type f -exec chmod 664 {} \;
sudo find /var/www/html/wwpp/ -type d -exec chmod 775 {} \;
次にnginxの設定を変更してLaravelからWPへルートディレクトリを変更します
sudo vi /etc/nginx/conf.d/default.conf
編集内容は以下の通り
root /var/www/html/yps/public; #↓に変更 root /var/www/html/wwpp; #追記 location /wp-config.php { deny all; }
:wq
で設定を保存したらphp-fpmとnginxを再起動します
sudo systemctl restart php-fpm && sudo systemctl restart nginx
※WPとLaravelを同時に動かしたい場合は下記のリンクを参照
ドメインネーム(設定してない場合はインスタンスのpublic IP)でブラウザからアクセス
WPのインストール画面が出ていれば成功です。
ただし、このままだとテーマやプラグインのインストールができないので少し設定をいじります。
cd wp-content/plugins/
wget https://downloads.wordpress.org/plugin/ssh-sftp-updater-support.0.8.2.zip
unzip ./ssh-sftp-updater-support.0.8.2.zip
rm http://ssh-sftp-updater-support.0.8.2.zip
sudo chown -R centos:nginx ./ssh-sftp-updater-support/
正常にプラグインがインストールされていればテーマをインストールできるようになっているはずです。
念のため下記の参考リンクを使ってできる範囲でのセキュリティ対策もしておきましょう以上でWPの構築は終了です。
/tmpは再起動時にディレクトリが消えるので、wgetでインストールするときなどに便利 ↩
- 投稿日:2020-10-12T16:14:46+09:00
Moodle 3.9 マニュアル - コースをリセットする
内容
1 概要
2 リセット方法-ステップバイステップ
3 一般的なリセットオプション
3.1 コース開始日
4 ロールリセットオプション
5 成績表リセットオプション
6 グループリセットオプション
7 アクティビティリセットオプション1 概要
これにより、アクティビティやその他の設定を保持したまま、一連のユーザーデータを空にすることができます。アイテムを選択するときは、選択したユーザーデータをこのコースから完全に削除することに注意してください。
一般、役割、成績表、グループ、アクティビティデータのカテゴリで、削除するユーザーデータを詳細なレベルで選択できます。
注:コースをリセットできるのは、コースのリセットのケーパビリティを持つユーザー(デフォルトではマネージャーと教師)のみです。
2 リセットする方法-ステップバイステップ
- ログインして、リセットするコースエリアに移動します
- 特定のアクティビティをリセットすることは元に戻せないため、ユーザーデータを含むエリアのバックアップを作成したことを確認してください。これはスナップショットであり、必要に応じて復元できます。
- お住まいの地域の管理ブロックで、[リセット]をクリックします
- [詳細を表示]ボタンをクリックして、そのカテゴリのすべてのオプションを表示します
- オプションに基づいて選択を行います(これらの詳細については、以下を参照してください)
- [リセット]ボタンをクリックします
- お住まいの地域に戻り、物事が希望どおりであることを確認してください。
3 一般的なリセットオプション
(リセットする前に)リセットする前に、コース内にある情報を必ずバックアップする必要があります。コースをバックアップするときは、必ずユーザー情報を使用してバックアップしてください。そうすれば、別のグループまたは部門にリセットする前に、コースを受講したもののバックアップデータを取得できます。
3.1 コース開始日
新しくリセットされたコースの新しいコース開始日を設定し、すべてのカレンダーイベント、コメント、コースとアクティビティの完了データ、およびコースに添付されているユーザーメモを削除できます。コースログは削除されないことに注意してください(MDL-43274を参照)
注:新しいコース開始日を設定すると、すべてのコース日付が同じ量だけシフトされます。
4 ロールリセットオプション
これらのロールリセットオプションを使用すると、コース内の特定のロールを持つすべてのユーザー(学生など)の登録を解除したり、コースに固有のすべてのロールオーバーライドとロール割り当てを削除したりできます。これは、コースのコンテキスト外でのユーザーロールの割り当てには影響しません。
5 成績表のリセットオプション
成績表のリセットオプションを使用すると、すべての成績表の項目とカテゴリを削除したり、コース内のすべての記録された成績を削除したりできます。成績表のリセットには2つのオプションがあります。
すべての成績を削除-コース内に手動で追加されたすべての成績アイテムを、上書き、除外、非表示、およびロックされた成績に関する成績とデータとともに削除します。このオプションでは、アクティビティグレードのアイテムは削除されないことに注意してください。
すべてのアイテムとカテゴリを削除する-オーバーライド、除外、非表示、ロックされたグレードのグレードとデータとともに、すべてのカテゴリと関連する手動で追加されたグレードアイテムを削除します。このオプションでは、アクティビティグレードのアイテムは削除されないことに注意してください。
これらの成績は引き続きユーザーのアカウントに対して記録されることに注意してください。
6 グループリセットオプション
グループリセットオプションを使用すると、コースで作成されたすべてのグループを削除したり、コース内のグループからすべてのユーザーを削除したりできます。
コースで作成されたすべてのグループを削除したり、コース内のグループからすべてのユーザーを削除したりすることもできます。
7 アクティビティリセットオプション
コース内で使用されるアクティビティに応じて、これらの学習オブジェクトに関連付けられているユーザーデータを削除するオプションが提供されます。これには、選択肢への回答、クイズの試行、フィードバックの回答、フォーラムの投稿(選択したフォーラムの種類から)、用語集のエントリなどが含まれます。
クイズの場合、次のことができます。
すべての試行を削除します
ユーザーオーバーライドとグループオーバーライドを削除する
ワークショップでは、次のことができます。すべての提出物を削除する
すべての評価を削除する
セットアップフェーズに切り替えます
Wikiの場合、次のことができます。ページを削除する
タグとコメントを削除する新しいコース開始日を指定することもできます。
- 投稿日:2020-10-12T14:50:29+09:00
CodeIgniter4でTwigを使う(Composer利用)
CodeIgniter4でもtwigを使いたい
前の記事ではCI4にSmartyを組み込みましたが、近頃はTwigをテンプレートエンジンに採用しているケースも多いのではないでしょうか?
本記事ではCI4にTwigを利用する方法の解説です。Twig for CodeIgniter4を導入する
CI4上でTwigを利用するには拙作、CodeIgniter4 for Twigを使うと手っ取り早いです。
CI4との統合は最低限の実装にとどめているので動作は軽いと思います。例は「CodeIgniter4をインストール (Composer利用)」での導入を終えた流れでインストールをした場合です。
composerによるTwig for CodeIgniter4の導入$ cd /home/ci4test $ composer require sarah-systems/ci4twig以下は、概ねREADME.mdからの抜粋です。
使い方
デフォルトでは、Twig関連のパスは自体は次のような設定で動作するようになっています。
種類 パス テンプレート app/Views キャッシュ writable/twig/cache
writable
が正しく書き込み可能な場合、キャッシュディレクトリは自動的に生成されます。
もしエラーが起きた場合は、これらのディレクトリを作って適切なパーミッションを与えることで動作します。もしこのパスを変更したい場合は
.env
ファイルに次のパラメータをセットすることで、任意のパスに変更可能です。CI4Twig.TemplateDir = /path/to/TemplateDir CI4Twig.CacheDir = /path/to/CacheDirこれ以外にも
.env
では、TwigのDebugフラグのOn/Offとデフォルトの拡張子を設定できます。CI4Twig.Debug = 1 または 0 CI4Twig.DefaultTemplateExtension = .html.twigview()
CI4のview関数をTwig用にCI4Twigというnamespaceで定義しています。
利用する際は
app
ディレクトリ直下のCommon.php
に次を追記してください。require_once ROOTPATH . "vendor/sarah-systems/ci4twig/src/Common.php";使用法はCI4のview関数と同じですが、関数の利用時には名前空間を指定するか、事前にエイリアスを張ってください。
\CI4Twig\view('template.html.twig');または
use function CI4Twig\view as view; view('template.html.twig');拡張子
.html.twig
(CI4Twig.DefaultTemplateExtension
で設定されたものです。無指定の場合は.html.twig
)は省略可能です。\CI4Twig\view('template');view関数の第2パラメータはTwig変数
$CI
にアサインされます。$data = [ 'apple' , 'banana' , 'lemon' ]; \CI4Twig\view('template',$data);Twigのtemplate上では
{{ CI.0 }} ← appleが表示されます。第3引数の$optionsは無視されます。
Service
CI4のServiceが利用可能です。
use CI4Twig\Config\Services; $time = date('Y-m-d H:i:s'); $twig = Services::twig(); $twig->Environment->addGlobal('time',$time); $twig->Environment->display('template.html.twig');次回はCI4のValidationの使い方について簡単に説明します。
- 投稿日:2020-10-12T13:42:40+09:00
hiddenの使い方
hiddenの使い方
hiddennは疑似要素として扱うことができる。
ctpファイルecho $this->Form->hidden('isSelectArea',["id" => "isSelectArea"]);
jQueryで疑似要素にval()で値を与える。
js$(function () { $(document).on("change", "#area", function () { $("#isSelectArea").val(true); //地域を選択したときにコントローラーで条件分岐をしてaddアクションにリダイレクトさせるためのhidden $("#UserConfirmForm").submit(); //一旦confirmアクションに飛ばす }); });
最後にコントローラで疑似要素を元にif文などで条件分岐できる
controllerif ($this->request->data["User"]["isSelectArea"]){ //もしisSelectAreaというキーを持っていればここで処理 }
- 投稿日:2020-10-12T12:30:31+09:00
SQLでテーブルにデータ挿入がうまくいかない時
テーブルを作成して、実行すると以下のエラーが発生してしまいました。
エラー内容
SQLSTATE[22003]: Numeric value out of range: 1264 Out of range value for column 'phone_number'
(phone_numbeカラムに入ってる値が指定してる範囲を超えています)phone_numberのカラムタイプに ”integer” を指定していて、それが原因でした。
$table->integer(‘phone_number');
”integer(INT)” には、最小値〜最大値まで決められた数値があり、それがこちらです。
INTの部分を見てみると、最小値が2〜最大値が8までとなっています。
私は、phone_numbeのカラムに “08022339999” と指定していて、最大値の8を超えた9を入れてしまっていました。
そのため、エラーが発生してしまったのです。カラムタイプをbigintに変更すれば解決です。
参考記事
https://dev.mysql.com/doc/refman/5.6/ja/integer-types.html
- 投稿日:2020-10-12T12:15:01+09:00
mysql プリペアドステートメント
プリペアドステートメントとは??
sqlのコードをわかりやすくしたテンプレートのようなものです。
書き方
// SQL文の作成
$stmt = $mysqli->prepare("INSERT INTO nekosan (
// パラメータを設定
name, price, better_before, modify_datetime, create_datetime
) VALUES (
?, ?, ?, ?, ?
)");
$stmt->bind_param( 'sisss', $name, $price, $better_before, $date,
$date);
// 実行
$res = $stmt->execute();
$stmt->close();
‘sis’とは、$nameや$priceのデータ型を意味しています。
$nameはstring 「s」
$priceはinteger 「i」
$better_beforeはstring 「s」
?(ハテナ)には、bind_paramで指定したデータが入ってきます。
参考記事; https://gray-code.com/php/prepared-statement-by-mysqli/
- 投稿日:2020-10-12T11:59:53+09:00
【xampp+LibXL】libxlをxamppに導入
自分用のメモとして残します。
LibxlのLinuxへのインストールはそこそこありましたが、
Win環境+xamppへのインストール方法があまりにも少なすぎるため、メモ程度ですが残します。■やり方
1. php_excel.dllインストール
ダウンロード
下記サイトから対応するPHPのバージョンのビルドをダウンロードする。
https://www.apachelounge.com/viewtopic.php?t=6359php_excel.dll設置
解凍して以下のファイルをxamppに設置
\ext\php_excel.dll
を\xampp\php\ext直下に設置。2. libxl.dllインストール
ダウンロード
下記サイトからLibXLをダウンロードする。
https://www.libxl.com/download.htmllibxl.dll設置
解凍して以下のファイルをxamppに設置(2か所)
\libxl-3.9.2.1\bin\libxl.dll
を\xampp\apache\bin直下に設置。
\libxl-3.9.2.1\bin\libxl.dll
を\xampp\php直下に設置。3. php.ini変更
下記をphp.iniに追記。
トライアルで使う場合は、license_name、license_keyは無くてもOK。php.ini[excel] extension=php_excel.dll excel.license_name="" excel.license_key=""以上
■さいごに
導入後の動作はぼちぼちググれば出てくるので、そちらを参考してください。。
また、今回はwindows上のxamppへのLibxl導入になります。
そのため、当該記事と同環境の場合はwindows用のライセンスでないとライセンスの認証が通らないようになっているため、製品版をwindowsで使用する場合はLinux用のライセンスでなく、win用のLibxlライセンスを取得して動作確認をしましょう。
- 投稿日:2020-10-12T10:19:22+09:00
[DDD Tips] アプリケーション層とドメイン層の区分けについて
はじめに
記事を書く時間が取れないため、単発のTipsを書くことにしました。
ドメイン駆動設計の現場で気づいたことや、自分が理解に苦しんだポイントなどを簡易的に取り上げていきたいと思います。この記事では、ドメイン駆動設計を始めようとしている方を対象に書いています。
「DDDの書籍は沢山読んだ!理解した気がする!」という段階の方に向いていると思います。
概念を理解したつもりでも、いざコードを書こうとすると手が止まってしまう。今回は、アプリケーション層(ユースケース)とドメイン層の実装で判断に迷いそうな箇所を取り上げていきたいと思います。
※ 当記事はLaravelを例に書いております。
例題1
- 記事の投稿機能を持つアプリケーション
- 投稿された記事をユーザーに対して表示するユースケース
BAD Practice
ShowPostUseCase.php<?php // ユースケースのどこか final class ShowPostUseCase { private PostRepositoryInterface $postRepository; public function __construct(PostRepositoryInterface $postRepository) { $this->postRepository = $postRepository; } public function __invoke(Request $request): Post { $post = $this->getPostByRequest($request); abort_if(!$post, 404); $this->validatePost($post); return $post; } private function getPostByRequest(Request $request): ?Post { return $this->postRepository->find( PostId::of($request->input('id')) ); } private function validatePost(Post $post) { // 記事をユーザーに表示しても良いかの判断 // 公開意外のステータスや、公開期間外だったら見せない if (!$post->hasPublicStatus() || !$post->hasActivePeriod()) abort(404); } }Post.php<?php // ドメインエンティティー final class Post extends Entity { protected PostId $id; protected string $title; protected string $content; protected PostStatus $status; protected PostPublishPeriod $period; public function hasPublicStatus(): bool { return $this->status->equals(PostStatus::PUBLIC); } public function hasActivePeriod(): bool { return $this->period->isActive(); } }手抜き満載のコードですが、とりあえず伝われば良しとします。
上記例のvalidatePost
メソッドにて、記事を一般ユーザーに見せても良いかどうかの確認を行っています。
何も問題ないように見えますが、実は必要以上のドメイン知識がユースケース層に含まれています。NGの理由1
ずばり、ユースケース側で投稿記事のルールを知ることなるからNGです。
記事がステータスを持っていること、公開でない場合はユーザーに見せることができないということ、
公開期間が定められていること、期間外はユーザーに見せられないということなど、
ユースケースに必要以上の知識が求められます。NGの理由2
1つの理由にあったルールは、いわゆるビジネスルールに該当するかと思います。
場合によっては、特定の権限を持つユーザーには非公開記事を見せる仕様にするかもしれないし、
記事が持つ属性によって、掲載期間が変動するかもしれない。これらの条件(ビジネスルール)をユースケースで取り扱うとなれば、ドメインそのものの意味が薄れてしまうので、
ユースケースでは判断をせずに、ドメイン側で解決するようにしましょう。Good Practice
ShowPostUseCase.php<?php final class ShowPostUseCase { private PostRepositoryInterface $postRepository; public function __construct(PostRepositoryInterface $postRepository) { $this->postRepository = $postRepository; } public function __invoke(Request $request): ?Post { $post = $this->getPostByRequest($request); abort_if(!$post, 404); $this->validatePost($post); return $post; } private function getPostByRequest(Request $request): ?Post { return $this->postRepository->find( PostId::of($request->input('id')) ); } private function validatePost(Post $post) { // 記事をユーザーに表示しても良いかの判断 // 判断の中身はユースケースで知る必要がないので、ドメインに任せる abort_if(!$post->isVisible(), 404); } }Post.php<?php final class Post extends Entity { protected PostId $id; protected string $title; protected string $content; protected PostStatus $status; protected PostPublishPeriod $period; private function hasPublicStatus(): bool { return $this->status->equals(PostStatus::PUBLIC); } private function hasActivePeriod(): bool { return $this->period->isActive(); } public function isVisible(): bool { return $this->hasPublicStatus() && $this->hasActivePeriod(); } }改善内容
- ユースケースでは投稿記事の閲覧条件(判断基準)を知る必要がないので、ドメイン層に判断を任せる
- ビジネスルールをドメインに集約したことで、ビジネスルールが増えても管理がしやすい。ユースケースによるバグが減らせる。
- コードの再利用性が自然と上がる
- テストが書きやすくなる(投稿エンティティーをモックして、ユースケースの振る舞いをテスト、ビジネスルールは単独でテストできるなど)
おわりに
ルールがシンプル過ぎる場合に、判断ミスがしやすい箇所だと感じましたので、
簡単なTipsとして投稿させて頂きました。ルールがシンプル過ぎるゆえに、
ビジネスロジックであることを見落としてしまうケースではないかと思います。単なるオブジェクト指向とDDDの決定的な違いだと思ったりもします。
今回は、参考になる内容かどうかも知りたかったので、ニーズが合う場合は
また時間ができたタイミングで単発記事を書きたいと思います。
- 投稿日:2020-10-12T09:56:55+09:00
Moodle 3.9 マニュアル - コースをアップロードする
注:このページは、テキスト(.csv)ファイルを使用したコースの作成に関するものです。コースのバックアップを.mbzまたは.tgz形式でアップロードする場合は、コースの復元を参照してください。
内容
1 コースをアップロードする
1.1 短いファイルの例
2 テキストファイルの作成
2.1 コース情報フィールド
2.1.1 登録フィールド
2.1.2 役割の名前変更
2.2 コースアクションフィールド
2.3 必須フィールド
2.4 インポートオプション
2.5 コースプロセス
2.6 デフォルトのコース値
3 速度を上げる
4 関連項目1 コースをアップロードする
新しいコースの作成に加えて、コースのアップロード機能を使用して、コースを更新または削除したり、別のコースからコンテンツをインポートしたりすることもできます。この機能を使用してコーステンプレートを作成する方法については、新しいコースの追加を参照してください。
1つ以上のコースをアップロードするには
- [管理]> [サイト管理]> [コース]> [コースのアップロード]に移動します
- CSVファイルをドラッグアンドドロップするか、[ファイルの選択]ボタンをクリックして、ファイルピッカーでファイルを選択します
- 適切なインポートオプションを慎重に選択し、プレビューボタンをクリックします。
コース管理画面のアップロード
コースが正常にアップロードされました注:コマンドラインツールadmin / tool / uploadcourse / cli /uploadcourse.phpを使用することもできます。
Webインターフェイスを使用する場合は、[プレビュー]オプションを使用して、プレビューされた行でエラーが検出されたかどうかを確認します。アップロードを続行し、コースで何か問題が検出された場合、それは無視されます。
1.1 短いファイルの例
uploadcourse.csv:
注:ショートネーム、フルネーム、およびカテゴリは必須です。
カテゴリフィールドはカテゴリのIDを取り、デフォルトのカテゴリその他はID1を持ちます。カテゴリはすでに存在している必要があります。存在しないカテゴリIDを入力すると、アップロードのプレビュー中に「IDでカテゴリを解決できませんでした」というエラーが表示され、そのカテゴリのコースは作成されません。
shortname,fullname,category,summary,enrolment_1,enrolment_1_role,enrolment_1_enrolperiod,role_student courserestored,Course restored,1,a summary,manual,student,1 month, courserestored2,Course restored 2,1,a summary,,,, courserestored3,Course restored 3,1,a summary,,,,padawan courserestored4,Course restored 4,1,"a summary, with comma",manual,student,1 month,padawanアイテム間にスペースがないことに注意してください。
2 テキストファイルの作成
コースをアップロードするためのテキストファイルはCSVファイルである必要があります。コース情報とコースアクションの2つのカテゴリに分類される次の列を受け入れます。
2.1 コース情報フィールド
これらの設定のほとんどは、コースの設定ページで利用できます。詳細については、コース設定を参照してください。フィールド名は小文字でなければなりません。
shortname
ショートネーム
fullname
フルネーム
idnumber
コースID番号
category
これは、コースを配置するカテゴリ(カテゴリURLにあります)のデータベース識別子です。これは、category_idnumberおよびcategory_pathよりも優先されます。
category_idnumber
コースを配置するカテゴリのID番号([カテゴリの編集]ページで見つけて編集可能)。これはcategory_pathよりも優先されます。
category_path
コースを配置するカテゴリのパス。「映画」カテゴリの下にある「サイエンスフィクション」という名前のカテゴリにコースを配置する場合、提供する値は次のとおりです。映画/サイエンスフィクション
。セパレータは
[スペース] / [スペース]。また、カテゴリは存在する必要があり、作成されないことに注意してください。コースをトップレベルのカテゴリ「映画」に配置する場合、提供する値は次のとおりです。
映画
visible
コースが表示されている場合は1、非表示の場合は0
startdate
コースが始まる時間。この値は、タイムスタンプを生成するためにPHP関数strtotimeに渡されることに注意してください。例01.12.2014(2014年12月1日)
enddate
コースが終了する時間。 startdateと同様に、この値はタイムスタンプを生成するためにPHP関数strtotimeに渡されることに注意してください。例01.12.2014(2014年12月1日)
summary
コースの概要
format
使用するコース形式。これは有効なコース形式プラグイン名である必要があります。例えば。週、トピック。
theme
使用するテーマ
lang
使用する言語
newsitems
ニュース項目の数
showgrades
1は成績表を生徒に表示し、0は非表示にします。
showreports
1はアクティビティレポートを表示し、0は非表示にします。
legacyfiles
1はレガシーコースファイルを有効にし、0は有効にしません。
maxbytes
コースの最大アップロードサイズ(バイト単位)。サイト制限には0を使用します。
groupmode
グループなしの場合は0、個別のグループの場合は1、表示可能なグループの場合は2。
groupmodeforce
グループモードを強制する場合は1、それ以外の場合は0を入力します。
enablecompletion
1はアクティビティの完了を有効にし、0は有効にしません。
tags
コースに追加するタグのコンマ区切りリスト。既存のタグは削除されます。複数のタグを引用符で囲みます。2.1.1 登録フィールド
一部のフィールドは、登録方法を有効にして構成するために作成できます。フィールドには、登録メソッド名としてenrolment_ [number]、プロパティとしてenrolment_ [number] _propertyという名前を付ける必要があります。
enrolment_ [number]
登録方法の名前(例:手動、ゲスト、自己)
enrolment_ [number] _delete
1に設定すると、この登録方法がコースから削除されます。他のすべてのプロパティは無視されます。
enrolment_ [number] _disable
1に設定すると、コースからこの登録方法を無効にします。他のすべてのプロパティは無視されます。
enrolment_ [number] _startdate
登録開始日。この値は、PHP関数strtotime()に渡されます。
enrolment_ [number] _enddate
登録終了日。この値は、PHP関数strtotime()に渡されます。
enrolment_ [number] _enrolperiod
秒数、または「4日」などのstrtotime()によって理解される値でない場合。
enrolment_ [number] _role
役割の短縮名
enrolment_ [number] _ [property]
指定された登録方法によってプロパティが理解される場合
enrolment_ [number] _password
コース登録キー注:アップロードコースは、まだすべての登録方法(MDL-43127)と互換性があるわけではありません。
例
enrolment_1:manual enrolment_1_role:student enrolment_1_enrolperiod:month enrolment_2:self enrolment_2_startdate:2013-01-302.1.2 役割の名前変更
次のパターンを使用して、一部の役割の名前を変更します。
role_ [shortname]
ロールの新しい名前[shortname]。例
role_student:見習い role_teacher:マスター role_mycustomrole:ジェダイ教師の役割の短縮名はeditingteacherであり、非編集教師の短縮名はteacherであることに注意してください。
2.2 コースアクションフィールド
これらの設定は、コースプロセスパラメータよりも優先されます。
delete
コースを削除するには1
rename
コースの名前を変更するショートネーム
backupfile
コースにインポートするバックアップファイル(.mbz)への絶対パス。(これは、コースへのフルパスを意味します(例:/home/yourmoodle/public_html/moodle27/transfert/backup.mbz)。これがわからない場合は、[サイト管理]> [サーバー]> [PHP情報]のinclude_pathを確認してください。)
templatecourse
コンテンツをインポートするコースの短縮名
reset
コースをリセットするには12.3 必須フィールド
shortname
このフィールドは、新しいコースの作成を除いて、すべての操作で必須です。詳細については、コースプロセスパラメータのショートネームテンプレートの詳細を参照してください。
fullname
新しいコースを作成するときに必要です。
category、category_idnumber、category_path
コースを作成するときに、これらの1つが必要です。2.4 インポートオプション
予期しない動作を防ぐには、ツールで実行できるようにすることを指定する必要があります。
Upload mode
これにより、コースを作成および/または更新できるかどうかを指定できます。
Update mode
コースの更新を許可する場合は、コースを何で更新するかをツールに指示する必要もあります。
Allow deletes
削除フィールドが受け入れられるかどうか
Allow renames
名前変更フィールドが受け入れられるかどうか
Allow resets
リセットフィールドが受け入れられるかどうか2.5 コースプロセス
これにより、アップロードされたすべてのコースに対して実行するアクションを指定できます。
Shortname template
ショートネームなしでコースを作成している場合は、このフィールドを使用してショートネームを自動的に生成できます。このフィールドは、ID番号の%iと要約の%fの2つのプレースホルダーを受け入れます。
Restore file
作成/更新後にコースにインポートするバックアップファイル(.mbz)。
Restore from course
作成/更新後にコンテンツをインポートするコースの短縮名。
Reset after upload
コースを作成/更新した後にコースをリセットするかどうか。2.6 デフォルトのコース値
これらは、CSVファイルで指定されていないすべてのフィールドのWebインターフェイスで設定できる値です。これらはコースの作成時に常に使用されますが、更新時に指定された場合にのみ使用されることに注意してください(更新モードを参照)。
3 速度を上げる
バックアップファイルまたは別のコースのコンテンツをインポートするときは、keeptempdirectoriesonbackupの設定を有効にすることをお勧めします。これにより、同じソースから複数回インポートする場合、アップロードのプロセスが大幅にスピードアップします。
4 関連項目
デモのスクリーンキャスト:コースの一括作成
ユーザーをアップロードする
MaryCoochによるMoodle2.6ブログ投稿でのコーステンプレートの作成
- 投稿日:2020-10-12T09:34:29+09:00
curl で unable to load client key: -8178 エラーが出た
要件
ルート証明書を使用して、とあるホストにアクセスする用事があった。
ゴールは、PHP の cURL 関数でアクセスできること。環境
- CentOS 7
- php7.3
- cURL 関数を使用
事象
php の cURL 関数でエラーが発生
証明書のパスを指定して cURL 関数を実行してみたところ、
以下のようなエラーが出てしまった。# オプション定義(抜粋) $ch = curl_init( "https://xxxx" ); curl_setopt( $ch, CURLOPT_SSLCERT, "./aaa.pem" ); curl_exec( $ch ); # 実行結果 cURL の戻り値:58 curl_error のメッセージ: unable to load client key: -8178 (SEC_ERROR_BAD_KEY)調査
CUI の curl でアクセスしてみる
では、同じ URL に対して CUI の curl で試したらどうなるか確認。
# コマンド curl -v https://xxxx --cacert ./aaa.pem # 結果 < HTTP/1.1 200 OK ~省略~ * CAfile: ./aaa.pem CApath: none ~省略~ curl: (58) unable to load client key: -8178 (SEC_ERROR_BAD_KEY)同じエラーが出てしまった。
エラーメッセージを見てみる
curl のエラーの中に
CApath: none
という文言があった。一つ上にある
CAfile
には引数の--cacert
の値が入っているので、
別の引数で指定しないといけない?調べてみると、
--capath
という引数で
CApath
に証明書のディレクトリを指定できるらしい。
早速試してみる。解決編
curl に capath オプションを指定してみる
# コマンド curl -v https://xxxx --capath <aaa.pem が存在するディレクトリのパス> # 結果 < HTTP/1.1 200 OK ~省略~ * CAfile: /etc/...省略.../ca-bundle.crt CApath: <aaa.pem が存在するディレクトリのパス> ~省略~ URL のデータ取得成功!
ちなみに、ディレクトリは絶対パスでも相対パスでも指定可。PHP の cURL 関数でも試してみる
PHP の cURL 関数では
CURLOPT_CAPATH
というオプションで
証明書のパスを指定できるらしい。# オプション定義 curl_setopt( $ch, CURLOPT_CAPATH, "<aaa.pem が存在するディレクトリのパス>" ); # 実行結果 成功(CUI と同じ)ファイル名ではなくディレクトリの指定が必要だったんですね。
追記
OS の証明書ストアに登録する方法
独自の証明書をOSの証明書ストアに登録すれば、
CApath
の指定が無くても読み込んでくれます。
※この方法が普通みたいですね;# cp aaa.pem /usr/share/pki/ca-trust-source/anchors/ # update-ca-trustただし、この場合は独自証明書が OS 全体に適用されてしまうため、
ユースケースによっては、前述の様に証明書パスを指定した方が良いかもしれません。ユースケースの例としては・・・
- 独自証明書をサービス固有で定義したい場合
- サービス毎にディレクトリを作っており、
他のサービスに影響を与えたくない場合など- OS 自体にインストールしないので、
Ansible などでの配布時に OS にほぼ影響を及ぼさない- 証明書を cron などで自動的に取得 & 配置 している場合
- 外部サービスの証明書が頻繁に更新される場合、
証明書ストアを更新するよりも自動化の手間が省ける証明書ファイルを明示的に指定
CURLOPT_CAPATH
を指定していれば、証明書ファイル名を指定しなくても
ディレクトリ内にあるファイルから自動的?に証明書を見つけてくれますが、
CURLOPT_CAINFO
で明示的に証明書パスを指定することもできるようです。
※その場合でもCURLOPT_CAPATH
は指定必須# オプション例 curl_setopt( $ch, CURLOPT_CAINFO , "./aaa.pem" ); curl_setopt( $ch, CURLOPT_CAPATH, "<aaa.pem が存在するディレクトリのパス>" );業務で長く使っていて色々なサーバの証明書が混在していたり、
有効期限切れのものが混ざっていたりしたら
この方が安全かもしれません。
- 投稿日:2020-10-12T08:37:31+09:00
composerでメモリ制限エラーがでた話
エラー内容
Fatal error: Allowed memory size of 1610612736 bytes exhausted (tried to allocate 4096 bytes) in phar:///usr/bin/composer/src/Composer/DependencyResolver/RuleWatchGraph.php on line 52 Check https://getcomposer.org/doc/articles/troubleshooting.md#memory-limit-errors for more info on how to handle out of memory errors.メモリーが足りないよ!ってエラーが帰ってきた
なので下記コマンドでメモリーの許可されている容量を調べると
php -r 'phpinfo();' | grep memory_limitmemory_limit => 128M => 128M128Mじゃそりゃ足りないわな,,,,
ので下記コマンドを実行
tarminalCOMPOSER_MEMORY_LIMIT=-1 composer 〇〇(インストールorアップデートしたいパッケージ)COMPOSER_MEMORY_LIMIT=-1は一時的にメモリを使いたい分一時的に使えるようにするよ!って意味
それと一緒にインストールしたいパッケージを記述し実行
- 投稿日:2020-10-12T08:29:22+09:00
Laravel 8 を体系的に学べる公式チュートリアル和訳
この記事について
この記事は、Laravel 8 のGetting Startedを和訳したものです。
公式のチュートリアルなので、安心して、かつ効率的に学習することができます。
Laravelのインストールとその設定、各種ツールの説明まで網羅されているので、初学者がLaravel 8 に初めて触れたり、中級者が基礎を振り返るのに最適です。
読者に誤解を与えない部分は、読みやすさを重視して適宜意訳しています。
英語の記事へのリンクを日本語の記事へのリンクに変更したり、新しくリンクを追加している部分があります。
DeepL等を使用して推敲は行っていますが、間違っているところやより良い表現があれば、どんどん編集リクエストをお願いいたします。
文頭にあるは、原文のリンクになっています。
翻訳元
laravel / docs : https://github.com/laravel/docs/tree/8.x
ライセンス : MIT
インストール
サーバに必要なもの
Laravelを使用するためには、いくつか必要なものがあります。Laravel Homesteadという仮想マシンを使用すれば必要なものは全て揃うので、Homesteadを使用してLaravelのローカル開発環境を構築することを強くおすすめします。
Homesteadを使用しない場合、サーバは以下の条件を満たす必要があります。
- PHP >= 7.3
- BCMath PHP拡張
- Ctype PHP拡張
- Fileinfo PHP拡張
- JSON PHP拡張
- Mbstring PHP拡張
- OpenSSL PHP拡張
- PDO PHP拡張
- Tokenizer PHP拡張
- XML PHP拡張
Laravelをインストールする
Laravelは、依存関係の管理にComposerを利用しています。なので、Laravelをインストールする前に、Composerがインストールされていることを確かめてください。
和訳者メモ
Macをご利用の場合は、HomeBrewでインストールできます。
brew install composer
Laravelインストーラを使用する方法
まず、Composerを使用して、Laravelインストーラをダウンロードします。
composer global require laravel/installerLaravelの実行ファイルにパスを通すために、Composerのvendor binディレクトリが
$PATH
に含まれていることを確認してください。vendor binディレクトリのある場所は、OSによって異なりますが、多くの場合は以下の場所に配置されています。
macOS:
$HOME/.composer/vendor/bin
Windows:
%USERPROFILE%\AppData\Roaming\Composer\vendor\bin
GNU / Linuxディストリビューション:
$HOME/.config/composer/vendor/bin
もしくは、$HOME/.composer/vendor/bin
Composerのグローバルインストールのパスは、
composer global about
を実行して確認できます。インストールが終わったら、
laravel new
コマンドを実行して、指定したディレクトリに新しいLaravelプロジェクトを作成できます。例えば、laravel new blog
コマンドは、blog
という名前のディレクトリを作成し、その中にLaravelの依存関係がすでにインストールされた状態のプロジェクトを配置します。laravel new blogヒント
ログインや登録などの機能を備えたLaravelプロジェクトを作りたいなら、Laravel Jetstreamをチェックしてみてください。
Composer Create-Projectを使用する方法
Laravelインストーラを使用する代わりに、Composerの
create-project
コマンドでも、Laravelをインストールできます。composer create-project --prefer-dist laravel/laravel blog
開発用ローカルサーバ
PHPがすでにローカルにインストールされていて、PHPに組み込まれている開発用サーバでアプリケーションを公開したい場合、Artisanの
serve
コマンドを使用してください。このコマンドを実行すると、http://localhost:8000
で開発用サーバが起動します。php artisan serveローカル開発環境を強化したい場合は、HomesteadとValetを利用してください。
設定
公開ディレクトリ
Laravelをインストールすると、WebサーバのドキュメントとWebルートが
public
ディレクトリに設定されます。public
ディレクトリにあるindex.php
は、アプリケーションへ入る全てのHTTPリクエストのフロントコントローラとして機能します。
設定ファイル
Laravelの設定ファイルは、全て
config
ディレクトリに保存されています。それぞれのオプションはドキュメント化されているので、目を通しておいてください。
ディレクトリのパーミッション
Laravelをインストールしたら、いくつかパーミッションの設定が必要です。
storage
内のディレクトリとbootstrap/cache
ディレクトリは、Webサーバによって書き込みができる必要があり、そうでなければLaravelは起動できません。Homesteadを使用している場合、これらのパーミッションはすでに設定されています。
アプリケーションキー
Laravelをインストールした後にしておかなければならないのが、アプリケーションキーにランダムな文字列を設定することです。ComposerかLaravelインストーラを使ってLaravelをインストールした場合は、このキーは既に
php artisan key:generate
コマンドによって設定されています。通常、この文字列は32文字の必要があります。また、キーは
.env
という環境ファイルで設定できます。.env.example
ファイルを.env
という名前でコピーしていない場合は、コピーしてください。アプリケーションキーがセットされていない場合、ユーザーセッションやその他の暗号化されたデータは安全ではありません。
追加設定
Laravelはこれ以上設定を必要とせず、すぐに使い始められます。ただし、
config/app.php
ファイルとそのドキュメントには目を通しておいてください。このファイルには、timezone
やlocale
のような、アプリケーションに応じて変更するべきオプションがいくつか含まれています。以下のような追加コンポーネントを構成することもできます。
Webサーバ設定
ディレクトリ設定
Laravelは、常にWebサーバに構成された「Webディレクトリ」のルートから配信される必要があります。Laravelアプリケーションを「Webディレクトリ」のサブディレクトリから配信しないでください。アプリケーション内の機密ファイルを公開してしまう恐れがあります。
URLの設定
Apache
Laravelには
public/.htaccess
ファイルが含まれており、これがあることで、パスにフロントコントローラであるindex.php
を含まないURLを提供できます。ApacheでLaravelを配信する前に、必ずmod_rewrite
モジュールを有効化して、サーバが.htaccess
ファイルを使用するように設定してください。Laravelに含まれる
.htaccess
がApache上でうまく動作しない場合は、以下の代替案を試してみてください。Options +FollowSymLinks -Indexes RewriteEngine On RewriteCond %{HTTP:Authorization} . RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^ index.php [L]
Nginx
Nginxを使用している場合は、サイト設定に以下のディレクティブを記述して、全てのリクエストがフロントコントローラである
index.php
に流れるようにしてください。location / { try_files $uri $uri/ /index.php?$query_string; }HomesteadかValetを使用している場合、URLの設定は自動で行われます。
設定
はじめに
Laravelの設定ファイルは、全て
config
ディレクトリに保存されています。それぞれのオプションはドキュメント化されているので、目を通しておいてください。
環境設定
アプリケーションが実行されている環境ごとに、別々の設定値を使用すると、便利なことがよくあります。例えば、本番環境と異なるキャッシュドライバをローカルで使用する場合などです。
これを簡単にできるようにするため、Laravelでは、PHPライブラリのDotEnvを利用しています。新しく作成したLaravelプロジェクトには、アプリケーションのルートディレクトリに
.env.example
ファイルがあります。ComposerでLaravelをインストールした場合、このファイルは自動的に.env
としてコピーされます。それ以外の場合では、自分でファイルをコピーする必要があります。
.env
ファイルをアプリケーションのソース管理リポジトリにコミットするべきではありません。なぜかというと、アプリケーションを使用する開発者やサーバによって、必要とする環境設定は異なるからです。もっというと、機密情報が公開されるので、悪意のある侵入者がソース管理リポジトリにアクセスした場合、セキュリティリスクになります。チームで開発している場合、
.env.example
ファイルはアプリケーションに残しておいたほうがいいかもしれません。サンプルの設定ファイルにプレースホルダの値を入れておくことで、チーム内の他の開発者が、どの環境変数がアプリケーションの実行に必要なのかよく分かるからです。また、.env.testing
ファイルを作成することもできます。このファイルは、PHPUnitのテストを実行したり、--env=testing
オプションを付けてArtisanコマンドを実行した場合に、.env
ファイルをオーバーライドします。
.env
ファイル内の任意の変数は、サーバレベルやシステムレベルの外部にある環境変数でオーバーライドすることができます。
環境変数の種類
.env
ファイル内の変数は全て文字列としてパースされるので、env()
関数によっていろいろな型を返せるように、いくつか予約語が用意されています。
.env
の値env()
の値true (bool) true (true) (bool) true false (bool) false (false) (bool) false empty (string) '' (empty) (string) '' null (null) null (null) (null) null スペースが含まれた値を環境変数として定義したい場合は、値をダブルクォーテーションで囲ってください。
APP_NAME="My Application"
環境変数の取得
このファイルに記載された全ての変数は、アプリケーションがリクエストを受け取ったときに、PHPのスーパーグローバル変数である
$_ENV
に読み込まれます。ただし、設定ファイル内の変数を取得するには、env
というヘルパー関数を使用します。実際にLaravelの設定ファイルを見てみると、いくつかのオプションでこのヘルパー関数が使用されているのが分かります。'debug' => env('APP_DEBUG', false),
env
関数に渡されている第二引数はデフォルト値です。与えられたキーに対応する環境変数が存在しなかった場合、この値が使用されます。
現在の環境を把握する
アプリケーションの現在の環境は、
.env
ファイルのAPP_ENV
変数で決定されます。この値にアクセスするには、App
ファサードのenvironment
メソッドを使用します。$environment = App::environment();また、現在の環境が指定された値であるかどうかを確かめるために、
environment
メソッドに引数を渡すこともできます。現在の環境が指定された値のいずれかに当てはまる場合、このメソッドはtrue
を返します。if (App::environment('local')) { // 環境がlocalである } if (App::environment(['local', 'staging'])) { // 環境がlocalかstagingのいずれかである }アプリケーションの環境は、サーバレベルの環境変数
APP_ENV
で上書きできます。これを応用すると、別々の環境でアプリケーションを共有できます。
デバッグページから環境変数を秘匿する
例外がキャッチされず、かつ環境変数
APP_DEBUG
がtrue
の場合、デバッグページに全ての環境変数とその内容が表示されます。設定ファイルconfig/app.php
内のdebug_hide
オプションを使用すると、特定の変数を隠すことができます。いくつかの変数は、環境変数とサーバ/リクエストデータの両方で使用されます。そのため、
$_ENV
と$_SERVER
の両方に指定しなければいけない場合もあります。return [ // ... 'debug_hide' => [ '_ENV' => [ 'APP_KEY', 'DB_PASSWORD', ], '_SERVER' => [ 'APP_KEY', 'DB_PASSWORD', ], '_POST' => [ 'password', ], ], ];
設定値へのアクセス
グローバルヘルパー関数の
config
を使用することで、アプリケーションのどこからでも設定値にアクセスすることができます。設定値にアクセスするには、アクセスしたいファイル名とオプション名を含んだドット記法を使用します。デフォルト値を指定することもでき、設定オプションが存在しなかった場合に返される値を指定できます。$value = config('app.timezone'); // 設定値が存在しない場合、デフォルト値が使用される $value = config('app.timezone', 'Asia/Seoul');実行時に設定値をセットする場合、ヘルパー関数
config
に配列を渡します。config(['app.timezone' => 'America/Chicago']);和訳者メモ
3通りの方法で環境の値が取得できるということになります。
>>> config('app.env') => "local" >>> App::environment() => "local" >>> env('APP_ENV') => "local"
設定のキャッシュ
アプリケーションの速度を上げるためには、Artisanコマンドの
config:cache
を使用して、全ての設定ファイルを一つのファイルにキャッシュする必要があります。これにより、アプリケーションの全ての設定オプションは一つのファイルにまとめられ、フレームワークが素早く読み込めるようになります。通常、本番環境へのデプロイのルーティンとして
php artisan config:cache
コマンドは実行するべきです。アプリケーションの開発中は、頻繁に設定オプションを変更するので、このコマンドを実行するべきではありません。注意
デプロイ処理中に
config:cache
コマンドを実行する場合、設定ファイル内からのみenv
関数が呼び出されていることを確認してください。設定がキャッシュされると、.env
ファイルは読み込まれず、env
関数はnull
を返すようになります。
メンテナンスモード
アプリケーションをメンテナンスモードにすると、アプリケーションへの全てのリクエストに対して、カスタムビューが表示されます。これによって、アップデート中やメンテナンス中にアプリケーションを簡単に「無効化」させることができます。メンテナンスモードのチェックは、アプリケーションの標準ミドルウェア内で行われています。アプリケーションがメンテナンスモードになると、ステータスコード503の
MaintenanceModeException
が投げられます。メンテナンスモードを有効にするには、Artisanコマンドの
down
を実行してください。php artisan downまた、
down
コマンドにretry
オプションを与えると、HTTPヘッダにRetry-After
の値としてセットされます。php artisan down --retry=60
メンテナンスモードの迂回
メンテナンスモード中でも、
secret
オプションを使用して、メンテナンスモードを迂回するためのトークンを指定することができます。php artisan down --secret="1630542a-246b-4b66-afa1-dd72a4c43515"アプリケーションをメンテナンスモードにした後、このトークンを指定したアプリケーションのURLを開くと、Laravelはブラウザにメンテナンスモードを迂回するためのCookieを発行します。
https://example.com/1630542a-246b-4b66-afa1-dd72a4c43515この隠されたルートにアクセスすると、アプリケーションのルート
/
にリダイレクトされます。一度ブラウザにCookieが発行されると、メンテナンスモードが無効のときと同じように、アプリケーションをブラウズできます。
メンテナンス画面のプリレンダリング
デプロイ時に
php artisan down
コマンドを利用した場合、Composerの依存関係やその他のインフラコンポーネントが更新されている間、ユーザがアプリケーションにアクセスするとエラーが発生する場合があります。なぜそんなことが起こるかというと、アプリケーションがメンテナンスモードであることを判定し、テンプレートエンジンを使用してメンテナンス画面を描画するためには、Laravelの大部分を起動する必要があるからです。そのため、リクエストサイクルの最初に返されるメンテナンスモード画面を事前にレンダリングできます。この画面は、アプリケーションの依存関係が読み込まれる前にレンダリングされます。プリレンダリングには、
down
コマンドのrender
オプションで指定したテンプレートが使用されます。php artisan down --render="errors::503"
メンテナンスモードへのリクエストをリダイレクトする
メンテナンスモードの間、ユーザがアクセスを試みた全てのアプリケーションURLにメンテナンス画面が表示されます。必要に応じて、全てのリクエストを指定したURLにリダイレクトできます。これには、
redirect
オプションを使用します。全てのリクエストを/
というURIにリダイレクトさせる例は以下の通りです。php artisan down --redirect=/
メンテナンスモードを終了する
メンテナンスモードを終了するには、
up
コマンドを使用します。php artisan upヒント
メンテナンスモードのテンプレートは、
resources/views/errors/503.blade.php
に独自のテンプレートを定義することでカスタマイズできます。
メンテナンスモードとキュー
アプリケーションがメンテナンスモードの間、キュージョブは処理されません。アプリケーションがメンテナンスモードから抜けると、ジョブは通常どおり処理されます。
メンテナンスモードの代替案
メンテナンスモードを使用すると、アプリケーションに数秒のダウンタイムが発生するので、Laravelでダウンタイムの無いデプロイを実現したい場合は、Envoyerのような代替案を検討してください。
ディレクトリ構造
はじめに
デフォルトのLaravelのアプリケーション構造は、大規模なアプリケーションから小規模なアプリケーションまで、優れたスタートポイントを提供することを目的としています。しかし、アプリケーションを好きなように構成することもできます。Laravelは、Composerがクラスをオートロードできる限り、クラスの配置にほとんど制限を設けていません。
ルートディレクトリ
appディレクトリ
app
ディレクトリには、アプリケーションのコアとなるコードが含まれています。このディレクトリに関しては後でもう少し掘り下げて説明しますが、アプリケーションのクラスのほとんどは、このディレクトリの中にあります。
bootstrapディレクトリ
bootstrap
ディレクトリには、フレームワークを起動するapp.php
ファイルが含まれています。また、cache
ディレクトリも含まれており、パフォーマンスの最適化のためにフレームワークが生成したrouteやservicesのキャッシュファイルなどが含まれています。
configディレクトリ
config
ディレクトリには、アプリケーションの設定ファイルが全て含まれています。全てのファイルに目を通し、利用可能なオプションを理解することをおすすめします。
databaseディレクトリ
database
ディレクトリには、データベースのマイグレーション、モデルファクトリー、シードが含まれています。必要に応じて、このディレクトリにSQLiteデータベースを保持することもできます。
publicディレクトリ
public
ディレクトリには、index.php
ファイルが含まれています。このindex.php
ファイルは、アプリケーションへの全てのリクエストのエントリーポイントであり、オートロードの構成も行います。また、このディレクトリには、画像、JavaScript、CSSなどのアセットも入っています。
resourcesディレクトリ
resources
ディレクトリには、ビューだけでなく、LESS、SASS、JavaScriptのような、コンパイル前の生のアセットが含まれます。また、このディレクトリには、全ての言語ファイルも入っています。
routesディレクトリ
routes
ディレクトリには、アプリケーションのルート定義が含まれています。デフォルトでは、web.php
、api.php
、console.php
、channels.php
というルートファイルが入っています。
web.php
ファイルには、RouteServiceProvider
がweb
というミドルウェアのグループに配置するルートが含まれており、セッションの状態、CSRFの保護、Cookieの暗号化を提供します。アプリケーションがステートレスなRESTful APIを提供しない場合、ルートは全てweb.php
ファイルで定義される可能性が高いです。
api.php
ファイルには、RouteServiceProvider
がapi
というミドルウェアのグループに配置するルートが含まれており、レートリミットを提供します。このファイル内で定義されるルートはステートレスであることを意図しているので、これらのルートを経由してアプリケーションへと入るリクエストはトークンで認証され、セッションの状態(ステート)にアクセスすることはありません。
console.php
ファイルには、クロージャベースのコンソールコマンドを定義できます。各クロージャは、コマンドインスタンスにバインドされており、各コマンドのIOメソッドと相互に通信することを可能にします。このファイルには、HTTPのルートではなく、アプリケーションへのコンソールベースのエントリーポイント(ルート)が定義されています。
channels.php
ファイルには、アプリケーションがサポートしている全てのイベントブロードキャストチャネルを登録できます。和訳者メモ
console.php
でinspire
が定義されているので、以下のコマンドを実行すると、英語の格言が表示されます。php artisan inspire
storageディレクトリ
storage
ディレクトリには、コンパイルされたBladeテンプレート、ファイルベースのセッション、ファイルキャッシュなど、フレームワークによって生成されたファイルが含まれています。このディレクトリは、app
、framework
、logs
ディレクトリに分けられています。app
ディレクトリには、アプリケーションが生成したファイルが保存されます。framework
ディレクトリには、フレームワークが生成したファイルと、キャッシュが保存されます。最後に、logs
ディレクトリには、アプリケーションのログファイルが格納されます。
storage/app/public
ディレクトリは、プロフィールアバターのような、一般に公開される必要がある、ユーザが生成したファイルを保存する場所です。このディレクトリを指すシンボリックリンクをpublic/storage
に作成してください。このリンクは、php artisan storage:link
コマンドを使用して作成できます。
testsディレクトリ
tests
ディレクトリには、自動化されたテストが含まれています。Laravelプロジェクトを作成すると、最初からPHPUnitテストの例が用意されています。それぞれのテストクラスには、Test
という接尾語が付けられている必要があります。テストを実行するには、phpunit
コマンドかphp vendor/bin/phpunit
コマンドを使用します。
vendorディレクトリ
vendor
ディレクトリには、Composerの依存関係が含まれています。
Appディレクトリ
アプリケーションの大部分は、
app
ディレクトリに格納されます。このディレクトリは、デフォルトでApp
下に名前空間があり、PSR-4標準オートロードを使用してComposerにオートロードされます。
app
ディレクトリには、Console
やHttps
、Providers
などの様々な追加ディレクトリが含まれています。Console
とHttp
ディレクトリは、アプリケーションのコアにAPIを提供しているものと考えてください。HTTPプロトコルとCLIは、どちらもアプリケーションと通信するための仕組みですが、アプリケーションのロジックを一切含みません。言い換えると、これらはアプリケーションにコマンドを発行する2通りの方法です。Console
ディレクトリには、全てのArtisanコマンドが格納され、一方のHttp
ディレクトリには、コントローラ、ミドルウェア、およびリクエストが格納されます。Artisanコマンドの
make
を使用してクラスを生成すると、app
ディレクトリ内に様々なディレクトリが生成されます。そのため、例えばArtisanコマンドのmake:job
を実行してjobクラスを生成するまで、app/Jobs
というディレクトリは存在しません。ヒント
app
ディレクトリ内のクラスの多くは、コマンドを介してArtisanによって生成することができます。利用可能なコマンドを確認するには、ターミナルでphp artisan list make
を実行してください。
Broadcastingディレクトリ
Broadcasting
ディレクトリには、アプリケーションの全てのブロードキャストチャネルクラスが含まれています。これらのクラスは、make:channel
コマンドを使用して生成できます。このディレクトリはデフォルトでは存在しませんが、最初にチャネルを作成したときに作成されます。チャネルについての詳細は、ブロードキャスティングのドキュメントを参照してください。
Consoleディレクトリ
Console
ディレクトリには、アプリケーションの全てのカスタムArtisanコマンドが含まれています。これらのコマンドは、make:command
コマンドを使用して生成できます。また、このディレクトリには、カスタムArtisanコマンドをスケジューリングタスクに設定できるコンソールカーネルも入っています。
Eventsディレクトリ
このディレクトリはデフォルトでは存在しませんが、Artisanコマンドの
event:generate
とmake:event
によって作成されます。Events
ディレクトリには、イベントクラスが格納されます。イベントは、与えられたアクションが発生したことをアプリケーションの他の部分を通知するのに使用され、非常に大きな柔軟性と分離性を提供します。
Exceptionディレクトリ
Exceptions
ディレクトリには、アプリケーションの例外ハンドラが含まれ、アプリケーションによって投げられた例外を配置するのに適しています。例外をログに記録したり描画する方法を変更する場合は、このディレクトリ内のHandler
クラスを編集してください。
Httpディレクトリ
Http
ディレクトリには、コントローラ、ミドルウェア、フォームリクエストが含まれています。アプリケーションに入るリクエストを処理するほとんどのロジックは、このディレクトリ内にあります。
Jobsディレクトリ
このディレクトリはデフォルトでは存在しませんが、Artisanコマンドの
make:job
を実行すると作成されます。Jobs
ディレクトリには、アプリケーションのためのキュージョブが格納されます。ジョブは、アプリケーションによってキューに入れられるか、現在のリクエストのライフサイクルと同期して実行されます。現在のリクエストに同期して実行されるジョブについては、コマンドパターンの実装であるため、「コマンド」と呼ばれることもあります。
Listenersディレクトリ
このディレクトリはデフォルトでは存在しませんが、Artisanコマンドの
event:generate
かmake:listener
を実行すると作成されます。Listeners
ディレクトリには、イベントを処理するクラスが含まれています。イベントリスナはイベントのインスタンスを受け取り、発生したイベントに応じてロジックを実行します。例えば、UserRegistered
イベントは、SendWelcomeEmail
リスナによって処理される、という感じです。
Mailディレクトリ
このディレクトリはデフォルトでは存在しませんが、Artisanコマンドの
make:mail
を実行すると作成されます。Mail::send
メソッドを用いて送信することができます。
Modelsディレクトリ
Models
ディレクトリには、全てのEloquentモデルクラスが含まれています。Laravelに入っているEloquent ORMは、データベースを操作するための美しくシンプルなActiveRecord実装を提供します。各データベーステーブルは対応する「モデル」があり、そのテーブルを操作するために使用できます。モデルを使用すると、テーブルのデータに対してクエリを発行したり、テーブルに新たなレコードを挿入したりできます。
Notificationsディレクトリ
このディレクトリはデフォルトでは存在しませんが、Artisanコマンドの
make:notification
を実行すると作成されます。Notifications
ディレクトリには、アプリケーション内で発生したイベントに関する通知など、アプリケーションから送信される「トランザクション」の通知が全て含まれています。Laravelの通知機能を使用することで、様々なドライバを介して、メールやSlack、SMSで通知を送信したり、データベースに保存したりすることを抽象化できます。
Policiesディレクトリ
このディレクトリはデフォルトでは存在しませんが、Artisanコマンドの
make:policy
を実行すると作成されます。Policies
ディレクトリには、アプリケーションの認可ポリシークラスが含まれています。ポリシーは、ユーザがリソースに対して特定のアクションを実行できるかどうかを判断するのに使用されます。詳細については、認可についてのドキュメントを参照してください。
Providersディレクトリ
Providers
ディレクトリには、アプリケーションの全てのサービスプロバイダが含まれています。サービスプロバイダは、サービスコンテナ内のサービスをバインドしたり、イベントを登録したり、リクエストに対してアプリケーションを準備するために他のタスクを実行したりすることで、アプリケーションを起動します。新規作成したLaravelアプリケーションの場合、このディレクトリにはすでにいくつかプロバイダが入っています。必要に応じて、独自のプロバイダをこのディレクトリに追加することができます。
Rulesディレクトリ
このディレクトリはデフォルトでは存在しませんが、Artisanコマンドの
make:rule
を実行することで作成されます。Rules
ディレクトリには、アプリケーションのカスタムバリデーションルールオブジェクトが含まれます。ルールは、複雑なバリデーションロジックをシンプルなオブジェクトへカプセル化するために使用されます。詳細については、バリデーションについてのドキュメントを参照してください。
Homestead
はじめに
Laravelは、ローカルでの開発を含めたPHP開発体験全体をより楽しくすることに努めてきました。Vagrantを使えば、仮想マシンの管理とプロビジョニングをシンプルかつ洗練された方法で行えます。
Laravel Homesteadは、ローカルマシンにPHPやWebサーバなどのサーバソフトウェアを必要とせず、素晴らしい開発環境を提供してくれる、パッケージがインストールされた状態の公式Vagrant Boxです。これを使えば、もうOSが散らかる心配はありません。Vagrant Boxは使い捨てです。何か問題が起きても、数分でBoxを破棄して作り直すことができます。
Homesteadは、Windows / Mac / Linux上で動作し、Nginx / PHP / MySQL / PostgresSQL / Redis / Memcached / Nodeなど、Laravelアプリケーションを開発するのに必要なものが全て含まれています。
注意
Windowsを使用している場合、ハードウェアの仮想化 (VT-x) を有効にする必要があります。これは通常、BIOSで有効化できます。
UEFIシステムでHyper-Vを使用している場合、VT-xにアクセスするためにHyper-Vを無効化する必要があります。
含まれているソフトウェア
- Ubuntu 18.04
- Git
- PHP 7.4
- PHP 7.3
- PHP 7.2
- PHP 7.1
- PHP 7.0
- PHP 5.6
- Nginx
- MySQL
- lmm for MySQL or MariaDB database snapshots
- Sqlite3
- PostgreSQL (9.6, 10, 11, 12)
- Composer
- Node (With Yarn, Bower, Grunt, and Gulp)
- Redis
- Memcached
- Beanstalkd
- Mailhog
- avahi
- ngrok
- Xdebug
- XHProf / Tideways / XHGui
- wp-cli
オプションのソフトウェア
- Apache
- Blackfire
- Cassandra
- Chronograf
- CouchDB
- Crystal & Lucky Framework
- Docker
- Elasticsearch
- Gearman
- Go
- Grafana
- InfluxDB
- MariaDB
- MinIO
- MongoDB
- MySQL 8
- Neo4j
- Oh My Zsh
- Open Resty
- PM2
- Python
- RabbitMQ
- Solr
- Webdriver & Laravel Dusk Utilities
インストール&セットアップ
最初にすること
Homestead環境を立ち上げる前に、Vagrantと合わせて、VirtualBox 6.x、VMWare、Parallelsまたは、Hyper-Vをインストールする必要があります。これらのソフトウェアパッケージは、一般的なOSに対応した使いやすいビジュアルインストーラです。
VMwareプロバイダを使用する場合、VMware Fusion / WorkstationとVMware Vagrantプラグインを購入する必要があります。無料ではありませんが、VMwareを使用すると、共有フォルダのパフォーマンスを高速化することができます。
Parallelsプロバイダを使用する場合、Parallels Vagrantプラグインをインストールする必要があります。これは無料です。
Vagrantには制限があるので、Hyper-Vプロバイダは全てのネットワーク設定を無視します。
和訳者メモ
VagrantをHomebrewでインストールするには、以下のコマンドを実行します。
brew cask install vagrant
Parallels Vagrantプラグインの概要とインストール方法については以下の日本語記事を参考にしてください。
Homestead Vagrant Boxのインストール
VirtualBox / VMwareとVagrantをインストールしたら、ターミナルで以下のコマンドを実行して、
laravel/homestead
BoxをVagrantに追加する必要があります。インターネットの通信スピードによりますが、Boxのダウンロードには数分かかります。vagrant box add laravel/homesteadコマンドの実行に失敗した場合、Vagrantが最新であるか確認してみてください。
注意
Homesteadは、テストのために"alpha" / "beta" Boxを定期的に発行しますが、それが
vagrant box add
コマンドに支障をきたす場合があります。vagrant box add
の実行で問題が発生した場合は、vagrant up
コマンドを実行することで、Vagrantが仮想マシンの起動をしようとしたときに、正しいBoxをダウンロードすることができます。
Homesteadのインストール
ホストマシンにレポジトリをクローンして、Homesteadをインストールしてください。Homestead Boxは、全てのLaravelプロジェクトのホストとして機能するため、ホームディレクトリの
Homestead
フォルダ内にレポジトリをクローンすることをおすすめします。git clone https://github.com/laravel/homestead.git ~/Homestead
master
ブランチがいつも安定版というわけではないので、タグ付けされたバージョンのHomesteadを確認してください。最新の安定版は、GitHubのリリースページで確認できます。代わりに、常に最新の安定版がリリースされている
release
ブランチにチェックアウトするという方法もあります。cd ~/Homestead git checkout release
Homesteadリポジトリをクローンしたら、Homesteadディレクトリで
bash init.sh
コマンドを実行し、Homestead.yaml
という設定ファイルを生成してください。Homestead.yaml
ファイルは、Homesteadディレクトリに配置されます。// Mac / Linuxの場合 bash init.sh // Windowsの場合 init.bat
Homesteadの設定
プロバイダを起動する
Homestead.yaml
ファイルのprovider
キーには、どのVagrantプロバイダを使用するかを指定します(virtualbox
,vmware_fusion
,vmware_workstation
,parallels
もしくはhyperv
のいずれか)。任意のプロバイダを設定してください。provider: virtualbox
共有フォルダの設定
Homestead.yaml
ファイルのfolders
プロパティには、Homestead環境と共有したいフォルダを列挙します。これらのフォルダに含まれるファイルが変更されると、ローカルマシンとHomestead環境の間で同期されます。共有フォルダは、必要な数だけ設定できます。folders: - map: ~/code/project1 to: /home/vagrant/project1Windowsをご利用の方は、
~/
のようなパスの書き方はせず、代わりにC:\Users\user\Code\project1
のようなプロジェクトへのフルパスを使用してください。全てを
~/code
フォルダにマッピングするのではなく、個々のプロジェクトは独自のフォルダにマッピングするようにしてください。フォルダをマッピングしたとき、仮想マシンはフォルダ内の全てのファイルの全てのディスクIOを追跡します。すると、フォルダ内に多数のファイルがあるとき、パフォーマンスに影響を与えます。folders: - map: ~/code/project1 to: /home/vagrant/project1 - map: ~/code/project2 to: /home/vagrant/project2注意
Homesteadを使用して
.
(カレントディレクトリ)をマウントするのは絶対にやめてください。Vagrantがカレントディレクトリを/vagrant
にマッピングせず、オプションの機能が壊れたり、プロビジョニング中に予期せぬ事態が起きることがあります。NFSを有効化するには、同期フォルダの設定にフラグを追加してください。
folders: - map: ~/code/project1 to: /home/vagrant/project1 type: "nfs"WindowsでNFSを使用する場合は、vagrant-winnfsdプラグインのインストールを検討してください。このプラグインを使用すると、Homestead Box内のファイルとディレクトリに適切なユーザ/グループ権限を与えることができます。
また、
options
キーに列挙することで、VagrantのSynced Foldersがサポートするオプションを渡すこともできます。folders: - map: ~/code/project1 to: /home/vagrant/project1 type: "rsync" options: rsync__args: ["--verbose", "--archive", "--delete", "-zz"] rsync__exclude: ["node_modules"]
Nginxサイトの設定
Nginxについて詳しく知らなくても問題ありません。
sites
プロパティを使えば、簡単に「ドメイン」とHomestead環境のフォルダをマッピングできます。サイト設定の例は、Homestead.yaml
ファイルに含まれています。これにおいても、必要なだけサイトをHomesteadに追加することができます。Homesteadは、作業を行う全てのLaravelプロジェクトに、便利で視認性の高い環境を提供します。sites: - map: homestead.test to: /home/vagrant/project1/publicHomestead Boxをプロビジョニングした後に
sites
プロパティを変更した場合、仮想マシン上のNginx設定を更新するために、もう一度vagrant reload --provision
コマンドを実行する必要があります。Homesteadのスクリプトは、可能な限り問題が発生しないように設計されています。それでもプロビジョニング中に問題が発生した場合は、
vagrant destroy && vagrant up
コマンドを使用して、マシンの破棄と再構築を行ってください。
サービスの有効化 / 無効化
Homesteadはデフォルトでいくつかサービスを起動します。しかし、プロビジョニングの間、どのサービスを有効化し、どのサービスを無効化するのかをカスタマイズすることができます。以下の例では、PostgresSQLを有効化し、MySQLを無効化しています。
services: - enabled: - "postgresql@12-main" - disabled: - "mysql"指定したサービスは、
enabled
とdisabled
ディレクティブに基づいて、起動または停止が行われます。
ホスト名の解決
Homesteadは、自動的にホスト名を解決できるように、
mDNS
を使用してホスト名を公開します。Homestead.yaml
にhostname: homestead
をセットすると、homestead.local
でホストを利用できるようになります。macOS、iOS、Linuxデスクトップディストリビューションは、mDNS
をデフォルトでサポートしていますが、Windowsの場合は、Bonjour Print Services for Windowsのインストールが必要になります。自動で解決されるホスト名が便利なのは、Homesteadをプロジェクトごとにインストールした場合です。一つのHomesteadインスタンス上で複数のサイトをホスティングした場合、Webサイトの「ドメイン」をマシンの
hosts
ファイルに追加する必要があります。hosts
ファイルは、HomesteadサイトへのリクエストをHomesteadマシンへリダイレクトします。MacとLinuxでは、このファイルは/etc/hosts
に配置され、Windowsでは、C:\Windows\System32\drivers\etc\hosts
に配置されます。このファイルには、以下のような行を追加します。192.168.10.10 homestead.test
Homestead.yaml
ファイルで設定されているものと同じIPアドレスを書き込む必要があります。hosts
ファイルにドメインを追加して、Vagrant Boxを起動したら、ウェブブラウザを介してサイトにアクセスできるようになります。http://homestead.test
Vagrant Boxの起動
Homestead.yaml
を好きなように編集したら、Homesteadディレクトリでvagrant up
コマンドを実行します。すると、Vagrantは仮想マシンを起動し、共有フォルダとNginxサイトを自動的に構成します。仮想マシンを破棄するには、
vagrant destroy --force
コマンドを使用します。
プロジェクト単位のインストール
Homesteadをグローバルにインストールし、同じHomestead Boxを全てのプロジェクトで共有するのではなく、管理しているプロジェクトごとにHomesteadインスタンスを構成できます。プロジェクト単位でHomesteadをインストールすると、
Vagrantfile
をプロジェクトに同梱して、別の人がそのプロジェクト上でvagrant up
できるようになります。プロジェクトに直接Homesteadをインストールするには、Composerを使用する必要があります。
composer require laravel/homestead --dev
Homesteadをインストールしたら、
make
コマンドでVagrantfile
とHomestead.yaml
ファイルをプロジェクトルートに作成してください。make
コマンドは、Homestead.yaml
ファイル内のsites
とfolders
ディレクティブを自動で設定します。Mac / Linux :
php vendor/bin/homestead makeWindows :
vendor\\bin\\homestead make次に、ターミナルで
vagrant up
コマンドを実行してから、ブラウザでhttp://homestead.test
を開いてプロジェクトにアクセスしてください。覚えておいていただきたいのは、自動的なホスト名の解決を使用していない場合、homestead.test
または任意のドメインを/etc/hosts
ファイルに追加する必要があります。
オプション機能のインストール
オプションのソフトウェアは、Homesteadの設定ファイルの「feature」設定を用いてインストールされます。ほとんどの機能は、論理値で有効か無効かを設定しますが、一部の機能では、複数の設定オプションが利用できます。
features: - blackfire: server_id: "server_id" server_token: "server_value" client_id: "client_id" client_token: "client_value" - cassandra: true - chronograf: true - couchdb: true - crystal: true - docker: true - elasticsearch: version: 7.9.0 - gearman: true - golang: true - grafana: true - influxdb: true - mariadb: true - minio: true - mongodb: true - mysql8: true - neo4j: true - ohmyzsh: true - openresty: true - pm2: true - python: true - rabbitmq: true - solr: true - webdriver: true
MariaDB
MariaDBを有効化すると、MySQLは削除され、MariaDBがインストールされます。MariaDBはMySQLの完全な互換なので、アプリケーションデータベースの設定では、
mysql
というデータベースドライバを引き続き使用できます。
MongoDB
デフォルトのMongoDBでは、データベースのユーザ名は
homestead
、対応するパスワードはsecret
に設定されています。
Elasticsearch
Elasticsearchのバージョンは、メジャーバージョンを指定するか、正確なバージョン番号(メジャー.マイナー.パッチ の形式)で指定できます。デフォルトのインストールでは、「homestead」という名前のクラスタを作成します。ElasticsearchにOSのメモリの半分以上を使わせるべきではないので、Homesteadマシンのメモリの過半数をElasticsearchアプリケーションに割り当てないでください。
設定をカスタマイズする方法については、Elasticsearchドキュメントを参照してください。
Neo4j
デフォルトでインストールしたNeo4jは、データベースのユーザ名に
homestead
が設定され、対応するパスワードはsecret
になっています。Neo4jブラウザにアクセスするには、Webブラウザでhttp://homestead.test:7474
を開いてください。Neo4jクライアントのために、7687
(Bolt)、7474
(HTTP)、7473
(HTTPS)のポートが用意されています。
エイリアス
Homesteadディレクトリの
aliases
ファイルを編集して、HomesteadマシンへのBashエイリアスを追加しましょう。alias c='clear' alias ..='cd ..'
aliases
ファイルをアップデートしたら、vagrant reload --provision
コマンドでHomesteadマシンを再度プロビジョニングする必要があります。これによって、新しいエイリアスがマシン上で利用できるようになります。
よくある使い方
Homesteadへのグローバルアクセス
ファイルシステムのどこからでも
vagrant up
コマンドでHomesteadマシンを起動したいと思うかもしれません。Mac / Linuxをご利用の場合は、Bash関数をBash profileに追加することで実現できます。Windowsをご利用の場合は、PATH
にバッチファイルを追加することで同様に実現可能です。これらのスクリプトは、システムのどこからでもVagrantコマンドを実行できるようにし、そのコマンドを自動でHomesteadのインストール先に渡してくれます。
Mac / Linux
function homestead() { ( cd ~/Homestead && vagrant $* ) }関数内の
~/Homestead
パスは、実際にHomesteadがインストールされている場所に合わせて書き換えてください。関数をインストールしたら、システムのどこからでもhomestead up
やhomestead ssh
のようにコマンドを実行できます。和訳者メモ
macOS「Catalina」では、デフォルトシェルがbashからzshに変更されているのでご注意ください。特にこだわりがなければ、bashをご利用の場合は
~/.bash_profile
に、zshをご利用の場合は~/.zprofile
に上述のスクリプトを書き込んでください。
Windows
どこにでもいいので
homestead.bat
というバッチファイルを作成し、以下の内容を書き込んでください。@echo off set cwd=%cd% set homesteadVagrant=C:\Homestead cd /d %homesteadVagrant% && vagrant %* cd /d %cwd% set cwd= set homesteadVagrant=スクリプト内で例としてあげた
C:\Homestead
パスは、実際にHomesteadがインストールされている場所に合わせて書き換えてください。ファイルを作成した後、ファイルがある場所をPATH
に追加してください。そうすれば、システムのどこからでもhomestead up
やhomestead ssh
のようなコマンドが実行できるようになります。
SSHを用いた接続
Homesteadディレクトリで
vagrant ssh
コマンドを実行すると、SSHで仮想マシンにアクセスできます。ただし、HomesteadマシンへのSSHアクセスは頻繁に利用するので、前の項でご紹介した関数を追加した方が、Homestead Boxに素早くSSHでアクセスできておすすめです。
データベースへの接続
homestead
のデータベースでは、MySQLとPostgreSQLが最初から使えるようになっています。ホストマシンのデータベースクライアントからMySQLかPostgreSQLデータベースにアクセスするには、127.0.0.1
の33060
番ポート(MySQL)または54320
番ポート(PostgreSQL)に接続してください。どちらのデータベースでも、ユーザ名とパスワードは、homestead
/secret
です。ホストマシンからデータベースに接続するときには、このように一般的ではないポートのみを使用してください。Laravelは仮想マシン内で動いているので、標準的な3306と5432ポートをLaravelのデータベース設定に使用します。
和訳者メモ
私の環境では、ホストマシンからHomesteadのMySQLに接続しようとすると、以下のようなエラーが発生しました。
$ mysql -h 127.0.0.1 -P 33060 -u homestead -psecret ERROR 2007 (HY000): Protocol mismatch; server version = 11, client version = 10ホストマシンのMySQLデーモンが
33060
番ポートをバインドしていることが原因のようだったので、ホストマシン上のMySQLデーモンを停止させた状態でHomesteadを起動し、解決しました。$ brew services stop mysql $ homestead reload --provision $ mysql -h 127.0.0.1 -P 33060 -u homestead -psecret mysql>
データベースのバックアップ
Homesteadには、Vagrant Boxが破棄されたときに、自動的にデータベースのバックアップを作成する機能があります。この機能を利用するには、Vagrantのバージョン2.1.0以上を使用している必要があります。古いバージョンのVagrantを使用している場合には、
vagrant-triggers
というプラグインをインストールしてください。Homestead.yaml
ファイルに以下の行を追加することで、データベースの自動バックアップを有効化できます。backup: true設定した後、
vagrant destroy
コマンドを実行すると、Homesteadは、データベースをmysql_backup
とpostgres_backup
ディレクトリに出力します。これらのディレクトリは、クローンしたHomesteadディレクトリにありますが、プロジェクト単位のインストールを使用した場合は、プロジェクトのルートディレクトリにあります。
データベースのスナップショット
Homesteadでは、MySQLロジカルマネージャを利用することで、MySQLとMariaDBの状態の凍結とブランチが可能です。例えば、数ギガバイトのデータベースを持つサイトで作業していても、データベースをインポートして、スナップショットをとることができます。それから必要な作業をして、ローカルにテストコンテンツを作成した後、すぐに元の状態に戻せます。
内部では、コピーオンライトをサポートしたLVMの薄いスナップショット機能をLMMが利用しています。つまり、テーブルの一つの行を書き換えるということは、書き込んだ変更がただディスクに移されるというだけなので、大幅に時間を短縮し、リストア中のディスク容量を節約できます。
lmm
コマンドはLVMの操作に使用するので、root
で実行する必要があります。実行可能な全てのコマンドを確認するには、Vagrant Box内でsudo lmm
コマンドを実行してください。一般的な流れは、以下のようになります。
- デフォルトのlmmの
master
ブランチにデータベースをインポートする。sudo lmm branch prod-YYYY-MM-DD
コマンドを使用して、変更前のデータベースのスナップショットを保存する。- データベースを編集する。
sudo lmm merge prod-YYYY-MM-DD
コマンドを実行して、全ての変更をなかったことにする。sudo lmm delete <branch>
コマンドを実行して、必要なくなったブランチを削除する。
サイトの追加
Homestead環境をプロビジョニングして実行したあとに、Laravelアプリケーションに新しいNginxサイトを追加したいことがあります。一つのHomestead環境で、何個でもLaravelは実行できます。サイトを追加するには、
Homestead.yaml
ファイルにサイトを追加してください。sites: - map: homestead.test to: /home/vagrant/project1/public - map: another.test to: /home/vagrant/project2/publicVagrantがhostsファイルを自動管理していない場合は、hostsファイルにも新しいサイトを追加する必要があります。
192.168.10.10 homestead.test 192.168.10.10 another.testサイトを追加できたら、Homesteadディレクトリで
vagrant reload --provision
コマンドを実行してください。
サイトの種類
Homesteadでは、Laravelベースではないプロジェクトを簡単に実行できるようにするため、数種類のサイトがサポートされています。例えば、
symfony2
というサイトタイプを使用すると、SymfonyアプリケーションをHomesteadに簡単に追加できます。sites: - map: symfony2.test to: /home/vagrant/my-symfony-project/web type: "symfony2"利用可能なサイトのタイプは次の通りです:
apache
,apigility
,expressive
,laravel
(デフォルト),proxy
,silverstripe
,statamic
,symfony2
,symfony4
,zf
サイトパラメータ
params
というサイトディレクティブを使用して、Nginxのfastcgi_param値をサイトに追加できます。例えば、以下ではBAR
という値を持ったFOO
パラメータを追加しています。sites: - map: homestead.test to: /home/vagrant/project1/public params: - key: FOO value: BAR
環境変数
Homestead.yaml
に書き加えることで、グローバル環境変数を設定できます。variables: - key: APP_ENV value: local - key: FOO value: bar
Homestead.yaml
を編集したら、必ずvagrant reload --provision
コマンドを実行して、再度マシンをプロビジョニングしてください。インストールしている全PHPバージョンのPHP-FPMの設定がアップデートされ、vagrant
ユーザの環境もアップデートされます。
ワイルドカードSSL
Homesteadでは、
Homestead.yaml
ファイルのsites:
セクションに定義したサイトそれぞれに、自己署名付きのSSL証明書が設定されます。サイトのワイルドカードSSL証明書を生成したい場合は、サイト設定にwildcard
オプションを追加してください。サイトは、特定ドメインの証明書ではなく、ワイルドカード証明書を使用するようになります。- map: foo.domain.test to: /home/vagrant/domain wildcard: "yes"
use_wildcard
オプションがno
になっている場合、ワイルドカード証明書は生成されますが、使用されません。- map: foo.domain.test to: /home/vagrant/domain wildcard: "yes" use_wildcard: "no"
Cronスケジュールの設定
Laravelでは、Cronジョブのスケジュールを簡単に使えるようにするため、Artisanコマンドの
schedule:run
を1分ごとに実行するようスケジューリングされています。schedule:run
コマンドは、App\Console\Kernel
にジョブスケジュールが設定されているかどうかによって、ジョブを実行するか判断します。サイトに対して
schedule:run
コマンドを実行したい場合は、サイト設定のschedule
オプションにtrue
を設定してください。sites: - map: homestead.test to: /home/vagrant/project1/public schedule: trueサイトのCronジョブは、仮想マシンの
/etc/cron.d
フォルダ内に定義されます。
Mailhogの設定
Mailhogを使用すると、実際にメールを受信者に送信しなくても、メールを取得できるようになります。使用するにあたって、
.env
ファイルのメール設定を以下のように書き換えてください。MAIL_MAILER=smtp MAIL_HOST=localhost MAIL_PORT=1025 MAIL_USERNAME=null MAIL_PASSWORD=null MAIL_ENCRYPTION=nullMailhogの設定が終わったら、
http://localhost:8025
を開いて、Mailhogダッシュボードにアクセスできます。
Minioの設定
Minioは、Amazon S3と互換性のあるAPIを備えた、オープンソースのオブジェクトストレージサーバです。Minioをインストールするには、
Homestead.yaml
のfeaturesセクションに以下の設定オプションを書き加えてください。minio: trueデフォルトでは、Minioは9600番ポートで利用できます。Minioのコントロールパネルにアクセスするには、
http://localhost:9600/
を開いてください。デフォルトのアクセスキーはhomestead
で、シークレットキーはsecretkey
です。Minioにアクセスする際には、常にus-east-1
リージョンを使用してください。Minioを使用するために、
config/filesystems.php
という設定ファイルで、S3のディスク設定を調整する必要があります。ディスク設定にuse_path_style_endpoint
オプションを追加し、url
キーをendpont
に変更してください。's3' => [ 'driver' => 's3', 'key' => env('AWS_ACCESS_KEY_ID'), 'secret' => env('AWS_SECRET_ACCESS_KEY'), 'region' => env('AWS_DEFAULT_REGION'), 'bucket' => env('AWS_BUCKET'), 'endpoint' => env('AWS_URL'), 'use_path_style_endpoint' => true, ]最後に、
.env
に以下のオプションが含まれていることを確認してください。AWS_ACCESS_KEY_ID=homestead AWS_SECRET_ACCESS_KEY=secretkey AWS_DEFAULT_REGION=us-east-1 AWS_URL=http://localhost:9600バケットをプロビジョニングするには、Homesteadの設定ファイルに
buckets
ディレクティブを追加してください。buckets: - name: your-bucket policy: public - name: your-private-bucket policy: none
policy
の値には、none
,download
,upload
,public
が使用できます。
ポート
デフォルトでは、以下のポートがHomestead環境に転送(ポートフォワーディング)されます。
- SSH: 2222 → 22 に転送
- ngrok UI: 4040 → 4040 に転送
- HTTP: 8000 → 80 に転送
- HTTPS: 44300 → 443 に転送
- MySQL: 33060 → 3306 に転送
- PostgreSQL: 54320 → 5432 に転送
- MongoDB: 27017 → 27017 に転送
- Mailhog: 8025 → 8025 に転送
- Minio: 9600 → 9600 に転送
ポートフォワーディングの追加
必要なら、特定のプロトコル以外にも、追加のポートフォワーディングをVagrant Boxに設定できます。
ports: - send: 50000 to: 5000 - send: 7777 to: 777 protocol: udp
環境の共有
今やっていることを同僚やクライアントと共有したい場合があると思います。Vagrantの
vagrant share
コマンドを使用すれば、これが可能になります。ただし、Homestead.yaml
ファイルで複数のサイトを構成している場合には、使用できません。この問題を解決するために、Homestead自体にも
share
コマンドが搭載されています。これを使用するには、vagrant ssh
コマンドでHomesteadマシンにSSH接続したあと、share homestead.test
コマンドを実行します。すると、設定ファイルのHomestead.yaml
からhomestead.test
というサイトが共有されます。他に構築しているサイトがあれば、homestead.test
の代わりに使用できます。share homestead.testコマンドを実行すると、Ngrokの画面が表示され、そこにはアクティビティログと、共有したサイトの公開URLが含まれています。任意のリージョンやサブドメインなど、Ngrokのランタイムオプションを指定したい場合は、
share
コマンドにそれらを付け加えることで実現可能です。share homestead.test -region=eu -subdomain=laravel注意
忘れないで欲しいのは、Vagrantは本質的に安全ではなく、
share
コマンドを実行すれば、仮想マシンがインターネット上に晒されてしまうということです。
複数のPHPバージョン
Homestead 6から、同じ仮想マシン上で複数のバージョンのPHPがサポートされるようになりました。
Homestead.yaml
ファイルで、サイトに使用するPHPバージョンを指定できます。利用可能なPHPバージョンは、"5.6", "7.0", "7.1", "7.2", "7.3", "7.4" (デフォルト)です。sites: - map: homestead.test to: /home/vagrant/project1/public php: "7.1"さらに、コマンドライン上では、サポートされているPHPバージョンを全て利用できます。
php5.6 artisan list php7.0 artisan list php7.1 artisan list php7.2 artisan list php7.3 artisan list php7.4 artisan listまた、Homesteadの仮想マシン内で以下のコマンドを実行すると、デフォルトのCLIバージョンを変更できます。
php56 php70 php71 php72 php73 php74
Webサーバ
Homesteadでは、デフォルトでWebサーバにNginxを使用します。ただし、サイトタイプに
apache
を指定すれば、Apacheをインストールすることもできます。両方のWebサーバを同時にインストールすることはできますが、同時に動かすことはできません。flip
というシェルコマンドを使用すれば、Webサーバを簡単に切り替えられます。flip
コマンドは、起動しているWebサーバがどちらであるかを自動的に判別して停止し、もう片方のサーバを起動します。このコマンドを使用するには、HomesteadマシンにSSHで接続し、ターミナルで以下のコマンドを実行してください。flip
メール
Homesteadには、Postfixというメール転送エージェントが含まれており、デフォルトで
1025
番ポートを使用しています。なので、localhost
の1025
番ポートでsmtp
のメールドライバを使用するように設定してください。そして、送信されたメールは全て、Postfixによって処理され、Mailhogによって取得されます。送信したメールを確認するには、ブラウザでhttp://localhost:8025にアクセスしてください。
デバッグ&分析
Xdebugを用いたWebリクエストのデバッグ
Homesteadでは、Xdebugを使用したステップ実行がサポートされています。例えば、ブラウザでWebページを読み込むと、PHPはIDEに接続して、動いているコードの検査や修正を可能にします。
Xdebugはデフォルトで既に起動していて、いつでも接続できます。コマンドラインでXdebugを有効化する必要がある場合は、Vagrant Box内で
sudo phpenmod xdebug
コマンドを実行してください。次は、IDEの指示に従って、デバッグを有効化してください。最後に、ブックマークレットや拡張を使用して、Xdebugを起動するようにブラウザを設定してください。注意
Xdebugを使用すると、PHPの動作は著しく遅くなります。Xdebugを無効にするには、Vagrant Box内で
sudo phpdismod xdebug
コマンドを実行し、FPMサービスを再起動してください。
CLIアプリケーションのデバッグ
PHPのCLIアプリケーションをデバッグするには、Vagrant Box内で
xphp
というシェルエイリアスを使用します。xphp path/to/script
Xdegugの自動起動
Webサーバのリクエストを作成する機能テストをデバッグする場合、デバッグするためにカスタムヘッダやCookieを使用するように変更するより、自動起動のデバッグを使用した方が簡単です。Xdebugを自動起動にする方法は、Vagrant Box内の
/etc/php/7.x/fpm/conf.d/20-xdebug.ini
を編集し、以下の設定を追記してください。; ここに記述すべきIPアドレスは、Homestead.yamlに記載されているIPアドレスです。 xdebug.remote_host = 192.168.10.1 xdebug.remote_autostart = 1
Blackfireを用いたアプリケーションの分析
Blackfireは、WebリクエストとCLIアプリケーションを分析し、パフォーマンスアサーションの記述ができるSaaSサービスです。分析データをコールグラフとタイムラインで表示する、インタラクティブなユーザーインターフェースを提供します。開発環境でも、ステージングでも、本番環境でも、エンドユーザに影響を与えずに使用できます。コードと設定ファイル
php.ini
に対して、パフォーマンス、クオリティ、セキュリティのチェックができます。Blackfire Playerは、分析方法を記述するためにBlackfireと共に使用できる、オープンソースのWebクローラ / Webテスト / Webスクレイピングアプリケーションです。
Blackfireを有効化するには、Homesteadの設定ファイル内の「features」設定を使用します。
features: - blackfire: server_id: "server_id" server_token: "server_value" client_id: "client_id" client_token: "client_value"Blackfireサーバの資格情報とクライアントの資格情報には、ユーザアカウントが必要です。Blackfireには、アプリケーションを分析するために、コマンドラインツールとブラウザ拡張を含めた様々なオプションがあります。詳細は、Blackfireのドキュメントをご覧ください。
XHGuiを用いたPHPパフォーマンスの分析
XHGuiは、PHPアプリケーションのパフォーマンスを調査するためのユーザインターフェースです。XHGuiを有効化するには、サイト設定に
xhgui: 'true'
を加えてください。sites: - map: your-site.test to: /home/vagrant/your-site/public type: "apache" xhgui: 'true'サイトが既に存在している場合、設定を更新した後に
vagrant provision
コマンドを実行してください。Webリクエストを分析するには、リクエストのクエリパラメータに
xhgui=on
を追加してください。XHGuiは、レスポンスに自動でCookieを付与するので、次回のリクエストにクエリパラメータは必要ありません。また、アプリケーションの分析結果を閲覧するには、ブラウザでhttp://your-site.test/xhgui
にアクセスしてください。XHGuiを使用してCLIリクエストを分析するには、コマンドの前に
XHGUI=on
を付与してください。XHGUI=on path/to/scriptCLIの分析結果は、Webの分析結果と同じように閲覧できます。
分析を行うと、スクリプトの実行速度が遅くなり、実時間が実際のリクエストの約2倍になることに注意してください。したがって、実際の数字ではなく、常に改善率を比較するようにしてください。また、実行時間には、デバッガ内で一時停止される時間も含まれています。
分析を行うと、ディスクスペースの大部分を消費してしまうので、数日経つと自動的に消去されます。
ネットワークインターフェース
Homestead.yaml
のnetworks
プロパティは、Homestead環境のネットワークインターフェースを構成します。インターフェースは、必要な数だけ構成できます。networks: - type: "private_network" ip: "192.168.10.20"ブリッジインターフェースを有効化するには、
bridge
設定を追加し、ネットワークタイプをpublic_network
に変更してください。networks: - type: "public_network" ip: "192.168.10.20" bridge: "en1: Wi-Fi (AirPort)"DHCPを有効化するには、設定から
ip
オプションを削除してください。networks: - type: "public_network" bridge: "en1: Wi-Fi (AirPort)"
Homesteadの拡張
Homesteadディレクトリのルートにある
after.sh
を使用すると、Homesteadを拡張できます。このファイルには、仮想マシンの設定やカスタマイズのためのシェルコマンドを記述できます。Homesteadをカスタマイズするとき、Ubuntuは、パッケージの元の設定を維持するか、新しい設定ファイルで上書きするかを確認する場合があります。これを回避するには、パッケージをインストールする際に以下のコマンドを使用して、Homesteadで以前に書かれた設定を上書きしないようにします。
sudo apt-get -y \ -o Dpkg::Options::="--force-confdef" \ -o Dpkg::Options::="--force-confold" \ install your-package
ユーザカスタマイズ
チーム設定でHomesteadを使用する場合、個人の開発スタイルに合わせるために、Homesteadを微調整できます。Homesteadディレクトリ(
Homestead.yaml
があるのと同じディレクトリ)のルートに、user-customizations.sh
というファイルを作成してください。このファイル内には、独自のカスタマイズを作成できます。ただし、user-customizations.sh
はバージョン管理しないでください。
Homesteadのアップデート
Homesteadをアップデートする前に、Homesteadディレクトリで以下のコマンドを実行し、現在の仮想マシンを削除する必要があります。
vagrant destroy次に、Homesteadのソースコードをアップデートする必要があります。レポジトリをクローンしている場合、レポジトリをクローンした場所で以下のコマンドを実行してください。
git fetch git pull origin releaseこれらのコマンドは、GitHubレポジトリからHomesteadの最新のコードを取得し、latestタグをフェッチしてから、latestタグのついたリリースにチェックアウトしています。最新の安定版のリリースバージョンは、GitHubリリースページで確認できます。
プロジェクトの
composer.json
ファイルを介してHomesteadをインストールした場合、composer.json
ファイルに"laravel/homestead": "^11"
が含まれていることを確認した上で、依存関係をアップデートしてください。composer updateそれから、
vagrant box update
コマンドを使用して、Vagrant Boxをアップデートします。vagrant box update次に、追加の設定ファイルをアップデートするために、Homesteadディレクトリで
bash init.sh
コマンドを実行します。すると、既に存在するHomestead.yaml
、after.sh
、aliases
ファイルを上書きするか尋ねられます。// Mac / Linux... bash init.sh // Windows... init.bat最後に、Homestead Boxを再構築して、最新のVagrantをインストールしてください。
vagrant up
プロバイダ固有の設定
VirtualBox
デフォルトで、Homesteadは
natdnshostresolver
をon
に設定しています。これは、ホストOSのDNS設定をHomesteadが使用できるようにするものです。この設定を上書きしたい場合は、Homestead.yaml
ファイルに以下の行を追加してください。provider: virtualbox natdnshostresolver: 'off'
Windowsでのシンボリックリンク
Windowsマシンでシンボリックリンクがうまく動作しない場合は、以下のブロックを
Vagrantfile
ファイルに書き加える必要があります。config.vm.provider "virtualbox" do |v| v.customize ["setextradata", :id, "VBoxInternal2/SharedFoldersEnableSymlinksCreate/v-root", "1"] end
Valet
はじめに
Valetは、Macを使っているミニマリストのためのLaravel開発環境です。Vagrantも
/etc/hosts
ファイルも使いません。公開しているサイトの共有も、ローカルトンネルを使用します。Valetは、マシンを起動すると、常にNginxをバックグラウンドで起動するように設定します。そして、DnsMasqを使用すれば、Valetは
*.test
ドメインへの全てのリクエストを、ローカルマシンにインストールしているサイトへプロキシします。言い換えると、RAM(メモリ)を7MB程度しか使用しない爆速Laravel開発環境です。ValetはVagrantやHomesteadに完全に取って代わる存在にはなりませんが、柔軟性のある基本的な機能が欲しかったり、極端なスピードを求めていたり、RAMが限られているマシンで作業する場合には、素晴らしい代替手段になります。
Valetは最初から以下をサポートしていますが、これ以外が使用できないということではありません。
- Laravel
- Lumen
- Bedrock
- CakePHP 3
- Concrete5
- Contao
- Craft
- Drupal
- ExpressionEngine
- Jigsaw
- Joomla
- Katana
- Kirby
- Magento
- OctoberCMS
- Sculpin
- Slim
- Statamic
- Static HTML
- Symfony
- WordPress
- Zend
いずれにしろ、カスタムドライバを使用すればValetを拡張できます。
ValetかHomesteadか
ご存知の通り、Laravelはローカルの開発環境としてHomesteadも提供しています。HomesteadとValetは、対象としているユーザと、ローカル開発へのアプローチという点において異なっています。Homesteadは、自動化されたNginx設定が入ったUbuntuの仮想マシン全体を提供します。仮想化されたLinuxの開発環境が欲しい場合や、Windows / Linuxを使用している場合には、Homesteadを使うのは素晴らしい選択肢となります。
ValetはMacしかサポートしておらず、PHPとデータベースサーバをローカルマシン上に直接インストールする必要があります。PHPとデータベースサーバは、Homebrewの
brew install php
とbrew install mysql
というコマンドを使用すれば、簡単に入手できます。Valetは、最小限のリソース消費で爆速のローカル開発環境を構築できるので、必要なものはPHP / MySQLだけであり、完全に仮想化された開発環境が必要でない人には最適です。ValetもHomesteadも、Laravelの開発環境を構築するとても便利なものです。どちらを使うかは、個人的な好みと、チームが必要としているものによるでしょう。
インストール
Valetは、macOSとHomebrewを必要とします。Valetをインストールする前に、ApacheやNginxなどの他のプログラムが、ローカルマシンの80番ポートにバインドされていないことを確認してください。
Homebrewをインストールするか、
brew update
コマンドを使用して最新バージョンにアップデートしてください。Homebrewの
brew install php
コマンドでPHP 7.4をインストールしてください。Composerをインストールしてください。
Composerの
composer global require laravel/valet
コマンドでValetをインストールしてください。~/.composer/vendor/bin
ディレクトリがシステムの「PATH」に含まれている必要があります。
valet install
コマンドを実行してください。ValetとDnsMasqの構築とインストールが行われ、システム起動時に実行されるValetデーモンが登録されます。Valetのインストールが終わったら、
ping foobar.test
のようなコマンドをターミナルで実行して、*.test
ドメインにpingを試してみてください。Valetが正常にインストールされている場合、このドメインは127.0.0.1
で応答するはずです。Valetは、マシンが起動するたびに自動でデーモンを始動させます。一度Valetをインストールしてしまえば、
valet start
やvalet install
のようなコマンドを実行する必要はありません。
データベース
データベースが必要な場合、コマンドラインで
brew install mysql@5.7
を実行し、MySQLを試してみてください。MySQLをインストールしたら、brew services start mysql@5.7
コマンドで起動できます。データベースには127.0.0.1
で接続でき、ユーザ名はroot
、パスワードは空文字を使用してください。
PHPのバージョン
Valetでは、
valet use php@version
コマンドでPHPバージョンの変更が可能です。指定されたバージョンのPHPがインストールされていない場合、ValetはBrewを使用してインストールを行います。valet use php@7.2 valet use php注意
複数のバージョンのPHPがインストールされている場合でも、Valetでは一度に一つのバージョンしか使用できません。
リセット
Valetのインストールで問題が発生して正しく実行できない場合は、
composer global update
コマンドの後でvalet install
を実行すると、インストールしたものをリセットして、問題を解決できます。まれにValetの「ハードリセット」が必要な場合がありますが、その場合は、valet uninstall --force
コマンドの後でvalet install
を実行してください。
アップデート
Valetをアップデートするには、ターミナルで
composer global update
コマンドを実行します。アップデートしたあと、valet install
コマンドを実行すると、設定ファイルが更新されます。
サイトの配信
Valetのインストールができたら、サイトを配信する準備は整っています。Valetには、
park
とlink
というLaravelのサイトを配信するのに便利な二つのコマンドがあります。
Parkコマンド
mkdir ~/Sites
のようなコマンドを実行して、新しいディレクトリをMac上に作成します。次に、cd ~/Sites
とvalet park
を実行します。すると、Valetがサイトを探すパスとして、カレントディレクトリが登録されます。
laravel new blog
コマンドで、このディレクトリに新しいLaravelサイトを作成します。ブラウザで
http://blog.test
を開きます。これだけです。これだけで、「park」したディレクトリに作成したLaravelプロジェクトは、
http://folder-name.test
で配信されます。
Linkコマンド
link
もLaravelサイトを配信するのに使用します。このコマンドは、ディレクトリ全体ではなく、ディレクトリ内で一つのみサイトを配信する場合に便利です。
このコマンドを使用するには、プロジェクトを開き、ターミナルで
valet link app-name
を実行します。すると、カレントディレクトリを指すシンボリックリンクが~/.config/valet/Sites
に作成されます。
link
コマンドを実行したら、ブラウザでhttp://app-name.test
を開いてサイトにアクセスできます。リンクしたディレクトリの一覧は、
valet links
コマンドで確認できます。valet unlink app-name
を使用すると、シンボリックリンクを破棄できます。ヒント
valet link
を使用することで、一つのプロジェクトを複数の(サブ)ドメインで配信できます。プロジェクトにサブドメインや他のドメインを追加するには、プロジェクトフォルダでvalet link subdomain.app-name
を実行してください。
TLSを用いたサイトの暗号化
デフォルトでは、ValetはHTTPでサイトを配信します。しかし、HTTP/2を使用して暗号化されたTLSでサイトを配信したい場合は、
secure
コマンドを使用してください。例えば、laravel.test
ドメインでサイトを配信しているときには、以下のコマンドを実行して暗号化できます。valet secure laravel暗号化をやめて、HTTPでの配信に戻したい場合、
unsecure
コマンドを使用してください。secure
コマンドと同じように、このコマンドにも暗号化をやめたいホスト名を指定します。valet unsecure laravel
サイトの共有
Valetには、ローカルのサイトを全世界に共有するコマンドも含まれていて、モバイルデバイスでのテスト、チームやクライアントとの共有を簡単に行えます。Valetがインストールされていれば、追加のソフトウェアインストールは必要ありません。
Ngrokを用いたサイトの共有
サイトを共有するには、ターミナルでサイトのディレクトリまで移動し、
valet share
コマンドを実行してください。公開URLがクリップボードにコピーされ、ブラウザに直接ペーストしたり、チームと共有することが可能です。サイトの共有を停止するには、
Control + C
でプロセスを中止してください。
valet share --region=eu
のように、shareコマンドには追加のパラメータを渡すこともできます。詳しくは、ngrokドキュメントを参照してください。
Exposeを用いたサイトの共有
Exposeをインストールしている場合、ターミナルでサイトのディレクトリに移動し、
expose
コマンドを実行することで、サイトを共有できます。サポートされているコマンドラインのパラメータについては、Exposeのドキュメントを参照してください。サイトを共有すると、他のデバイスやチームメンバーと共有できるURLが表示されます。サイトの共有を停止するには、
Control + C
でプロセスを中止してください。
ローカルネットワーク上でのサイト共有
Valetは、デフォルトで、受け入れる通信を
127.0.0.1
の内部に限定しています。これによって、開発マシンがインターネットに晒されて、セキュリティリスクが生じることを防いでいます。ローカルネットワーク内の他のデバイスから、マシンのIPアドレス(例:
192.168.1.10/app-name.test
)を使ってValetのサイトにアクセスさせたい場合は、Nginxの設定ファイルを編集し、80番と443番ポートのlisten
ディレクティブの先頭についている127.0.0.1:
という部分を削除してください。
valet secure
を実行していない場合、/usr/local/etc/nginx/valet/valet.conf
ファイルを編集することで、全てのHTTPSではないサイトにネットワークアクセスを解放できます。ただし、HTTPSでプロジェクトのサイトを配信している場合(valet secure
を実行している場合)は、~/.config/valet/Nginx/app-name.test
ファイルを編集してください。Nginxの設定を更新したら、
valet restart
コマンドで、設定の変更を適用してください。
サイト固有の環境変数
他のフレームワークを使用しているアプリケーションでは、サーバの環境変数に依存している場合がありますが、プロジェクト内で環境変数を設定する手段はありません。Valetを使えば、プロジェクトのルートに
.valet-env.php
ファイルを追加することで、サイト固有の環境変数を設定することが可能です。これらの変数は、$_SERVER
というグローバル配列に追加されます。<?php // foo.test サイトの $_SERVER['key'] に "value" を設定する return [ 'foo' => [ 'key' => 'value', ], ]; // 全てのサイトの $_SERVER['key'] に "value" を設定する return [ '*' => [ 'key' => 'value', ], ];
プロキシサービス
Valetのドメインを、ローカルマシン内の他のサービスにプロキシしたい場合があると思います。例えば、Dockerで別のサイトを起動している間に、Valetも起動する必要がある場合です。しかし、ValetとDockerが同時に80番ポートをバインドすることはできません。
これを解決するには、
proxy
コマンドを使用して、プロキシを生成します。以下は、http://elasticsearch.test
への全てのトラフィックをhttp://127.0.0.1:9200
にプロキシする例です。valet proxy elasticsearch http://127.0.0.1:9200
unproxy
コマンドを使えば、プロキシを削除できます。valet unproxy elasticsearch
proxies
コマンドを使えば、プロキシされている全てのサイト構成を一覧表示できます。valet proxies
カスタムValetドライバ
独自のValetドライバを書くことで、ValetがサポートしていないフレームワークやCMSで動いているPHPアプリケーションを配信できます。Valetをインストールすると、
SampleValetDriver.php
ファイルが入った~/.config/valet/Drivers
ディレクトリが作成されます。このファイルには、カスタムドライバの書き方について説明するための、簡単なドライバが実装されています。ドライバを書くのに必要な実装は、serves
、isStaticFile
、frontControllerPath
という3つのメソッドだけです。これら3つのメソッドは全て、引数として
$sitePath
、$siteName
、$uri
という値をとります。$sitePath
は、/Users/Lisa/Sites/my-project
のような、現在配信しているサイトのフルパスです。$siteName
は、ドメイン(my-project
)の"ホスト" / "サイト名"の部分です。$uri
は、リクエストのURI(/foo/bar
)です。カスタムのValetドライバが完成したら、
~/.config/valet/Drivers
ディレクトリにFrameworkValetDriver.php
形式の名前で配置してください。例えば、WordPressのためのカスタムValetドライバを書いた場合、ファイル名はWordPressValetDriver.php
とします。それぞれのメソッドのサンプル実装を見てみましょう。
servesメソッド
serves
メソッドは、ドライバがリクエストを処理すべきならばtrue
を返します。そうでない場合は、false
を返します。なので、このメソッドの内部では、渡された$sitePath
に動作させようとしている種類のプロジェクトが含まれているかを判定します。例として、
WordPressValetDriver
を書いているとしましょう。serves
メソッドは以下のようになります。/** * ドライバをリクエストに適用するかを判定する * * @param string $sitePath * @param string $siteName * @param string $uri * @return bool */ public function serves($sitePath, $siteName, $uri) { return is_dir($sitePath.'/wp-admin'); }
isStaticFileメソッド
isStaticFile
は、リクエストが画像やスタイルシートのような静的なファイルに対してかを判断します。静的なファイルであった場合、静的ファイルのディスク上のフルパスを返します。静的ファイルでなかった場合、メソッドはfalse
を返します。/** * リクエストが静的ファイルに対してのものかを判定する * * @param string $sitePath * @param string $siteName * @param string $uri * @return string|false */ public function isStaticFile($sitePath, $siteName, $uri) { if (file_exists($staticFilePath = $sitePath.'/public/'.$uri)) { return $staticFilePath; } return false; }注意
isStaticFile
メソッドが呼び出されるのは、serves
メソッドがリクエストに対してtrue
を返し、かつリクエストURIが/
ではなかった場合のみです。
frontControllerPathメソッド
frontControllerPath
メソッドは、アプリケーションのフロントコントローラのフルパスを返します。多くの場合、index.phpかそれに相当するものです。/** * アプリケーションのフロントコントローラのフルパスを取得する * * @param string $sitePath * @param string $siteName * @param string $uri * @return string */ public function frontControllerPath($sitePath, $siteName, $uri) { return $sitePath.'/public/index.php'; }
ローカルドライバ
単一のアプリケーションにカスタムのValetドライバを定義したい場合、アプリケーションのルートディレクトリに
LocalValetDriver.php
を作成してください。カスタムドライバは、ベースとなるValetDriver
クラスを継承するか、LaravelValetDriver
のような既に存在するアプリケーション固有のドライバを継承します。class LocalValetDriver extends LaravelValetDriver { /** * ドライバをリクエストに適用するかを判定する * * @param string $sitePath * @param string $siteName * @param string $uri * @return bool */ public function serves($sitePath, $siteName, $uri) { return true; } /** * アプリケーションのフロントコントローラのフルパスを取得する * * @param string $sitePath * @param string $siteName * @param string $uri * @return string */ public function frontControllerPath($sitePath, $siteName, $uri) { return $sitePath.'/public_html/index.php'; } }
その他のValetコマンド
コマンド 説明 valet forget
parkしたディレクトリで実行することで、parkしたディレクトリのリストから削除します。 valet log
Valetのサービスによって書かれたログの一覧を表示します。 valet paths
全てのparkしたパスを表示します。 valet restart
Valetデーモンを再起動します。 valet start
Valetデーモンを起動します。 valet stop
Valetデーモンを停止します。 valet trust
sudoersファイルにBrewとValetを追加して、パスワード入力なしでValetコマンドを実行できるようにします。 valet uninstall
Valetをアンインストールします。手動アンインストールのための説明が表示されますが、 --force
パラメータを使用することで、強制的にValetを全て削除することもできます。
Valetディレクトリ&ファイル
Valet環境で起きた問題をトラブルシューティングする際には、以下のディレクトリとファイルの説明が参考になります。
File / Path Description ~/.config/valet/
Valetの設定が全て入っています。このフォルダはバックアップしておくといいでしょう。 ~/.config/valet/dnsmasq.d/
DNSMasqの設定が全て入っています。 ~/.config/valet/Drivers/
カスタムのValetドライバが入っています。 ~/.config/valet/Extensions/
カスタムのValet拡張 / コマンドが入っています。 ~/.config/valet/Nginx/
Valetが生成した全てのNginxサイトの設定が入っています。 install
、secure
、tld
コマンドを実行すると、これらのファイルは再生成されます。~/.config/valet/Sites/
リンクしたプロジェクトの全てのシンボリックリンクが入っています。 ~/.config/valet/config.json
Valetのマスタ設定ファイルです。 ~/.config/valet/valet.sock
ValetのNginx設定によって使用されるPHP-FPMソケットです。PHPが正常に動作している場合のみ存在します。 ~/.config/valet/Log/fpm-php.www.log
PHPエラーのユーザログです。 ~/.config/valet/Log/nginx-error.log
Nginxエラーのユーザログです。 /usr/local/var/log/php-fpm.log
PHP-FPMエラーのシステムログです。 /usr/local/var/log/nginx
Nginxのアクセスログとエラーログが入っています。 /usr/local/etc/php/X.X/conf.d
さまざまなPHPの構築設定のための *.ini
ファイルが含まれています。/usr/local/etc/php/X.X/php-fpm.d/valet-fpm.conf
PHP-FPMのプール設定ファイルです。 ~/.composer/vendor/laravel/valet/cli/stubs/secure.valet.conf
サイト証明書の構築に使用されるデフォルトのNginx設定ファイルです。
デプロイ
はじめに
Laravelアプリケーションを本番環境にデプロイする準備ができたら、アプリケーションを効率的に実行させるために、やるべきことがいくつかあります。この章では、Laravelアプリケーションが適切にデプロイするための重要なポイントを解説します。
サーバの設定
Nginx
Nginxが動いているサーバにアプリケーションをデプロイする場合、Webサーバの設定として、以下の設定ファイルを参考にしてください。ほとんどの場合、サーバの設定に応じてカスタマイズが必要です。サーバの管理にサポートが必要な場合は、Laravel Forgeのようなサービスの利用を検討してください。
server { listen 80; server_name example.com; root /srv/example.com/public; add_header X-Frame-Options "SAMEORIGIN"; add_header X-XSS-Protection "1; mode=block"; add_header X-Content-Type-Options "nosniff"; index index.php; charset utf-8; location / { try_files $uri $uri/ /index.php?$query_string; } location = /favicon.ico { access_log off; log_not_found off; } location = /robots.txt { access_log off; log_not_found off; } error_page 404 /index.php; location ~ \.php$ { fastcgi_pass unix:/var/run/php/php7.4-fpm.sock; fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; include fastcgi_params; } location ~ /\.(?!well-known).* { deny all; } }
最適化
オートローダの最適化
本番環境へデプロイするとき、Composerのクラス・オートローダ・マップを最適化することで、Composerは指定されたクラスのファイルを素早く読み込めるようになります。
composer install --optimize-autoloader --no-devヒント
オートローダの最適化に加えて、プロジェクトのソース管理リポジトリに
composer.lock
ファイルを含めるようにしてください。composer.lock
がある方が、プロジェクトの依存関係をより速くインストールできます。
設定の読み込みの最適化
アプリケーションを本番環境にデプロイするとき、デプロイの流れの中でArtisanコマンドの
config:cache
を実行するようにしてください。php artisan config:cacheこのコマンドは、全てのLaravelの設定ファイルを一つのキャッシュファイルにまとめることで、設定値を読み込む時にフレームワークが参照しなければいけないファイル数を大幅に減らします。
注意
デプロイの流れの中で
config:cache
コマンドを実行する場合、設定ファイル内でのみenv
関数が呼び出されるようにしてください。設定がキャッシュされると、.env
ファイルは読み込まれなくなり、env
関数は全ての呼び出しに対してnull
を返します。
ルートの読み込みの最適化
多くのルートを持つ大規模なアプリケーションを構築する場合、デプロイの流れの中でArtisanコマンドの
route:cache
を実行してください。php artisan route:cacheこのコマンドは、全てのルート登録をキャッシュファイル内の単一のメソッド呼び出しに集約させ、何百ものルートを登録した場合のパフォーマンスを向上させます。
ビューの読み込みの最適化
本番環境にアプリをデプロイするとき、デプロイの流れの中でArtisanコマンドの
view:cache
を実行する必要があります。php artisan view:cacheこのコマンドは、全てのBladeビューをプリコンパイルすることで、要求されたときにコンパイルされるのを防ぎ、ビューを返すリクエストのパフォーマンスを向上させます。
Forge / Vaporを使ったデプロイ
自分でサーバの設定を管理する準備ができていなかったり、強靭なLaravelアプリケーションを実行するのに必要なさまざまなサービスを全て設定することに抵抗がある場合、Laravel Forgeは素晴らしい代替手段です。
Laravel Forgeは、DigitalOceanやLinodeやAWSなど、さまざまなインフラプロバイダ上でサーバを作成できます。加えて、Forgeは、NginxやMySQL、Redis、Memcached、Beanstalkなど、強靭なLaravelアプリケーションを構築するのに必要な全てのツールのインストールと管理を行います。
Laravel Vapor
完全にサーバレスで、オートスケール開発プラットフォームにチューニングされたLaravelを使用したい場合、Laravel Vaporを参照してください。Laravel Vaporは、AWSを利用した、Laravelのサーバレス開発プラットフォームです。LaravelのインフラをVaporで立ち上げ、サーバレスでシンプルにスケールできます。Laravel Vaporは、Laravelの開発者によって、フレームワークとシームレスに動作するようにチューニングされているので、今までと同じようにLaravelアプリケーションを書くことができます。
- 投稿日:2020-10-12T01:06:08+09:00
Carbonで何週目の何曜日の日付を取得する
日付処理を扱う上で、carbonに非常に助けられている今日この頃だが、思ったより簡単に書けない処理があり、暫定で作ったものを備忘録として残す。それもっと簡単に行けるで、という情報があれば是非教えていただければと思う。
前提
日曜始まり土曜終わりを1週として、日曜から順に0,1,2...と曜日と数字が対応している。
['sun' => 0, 'mon' => 1, 'tue' => 2, 'wed' => 3, 'thu' => 4, 'fri' => 5, 'sat' => 6,]1週目、2週目、、、5週目とn週目とnが対応している。
['1週目' => 1, '2週目' => 2, '3週目' => 3, '4週目' => 4, '5週目' => 5, '6週目' => 6]要件
n週目のm曜日を入力値として与えられた時に、日付を返す。
public function getDate($week_of_month, $weekday) { // return '2020-10-19' }Carbonじゃダメなの?
Carbonにも何週目か判定するメソッドや、曜日を判定するメソッドなどなど便利なメソッドが多々あるが、何週目かの計算が、月曜始まりのものと、単純に7日づつ加算して算出するものしかなく、日曜始まりで扱いやすそうな処理が書けなかったので断念
//月曜始まりで、n週目を計算。 $carbon->weekNumberInMonth; //7日間づつ計算 $carbon->weekOfMonth;2020/10/12追記
@vf8974 さんより、標準関数でより簡潔にかける方法をいただいたので追記
public function getDay($params) { // DateTimeImmutableインスタンス $d = new \DateTimeImmutable(); // 年(省略時は今年) $year = $params['year'] ?? $d->format('Y'); // 月(省略時は今月) $month = $params['month'] ?? $d->format('m'); // 対象月1日 $firstDay = $d->setDate($year, $month, 1); // 対象月1日の曜日 $firstDayOfWeek = $firstDay->format('w'); // 対象月の最終日 $lastDay = $firstDay->format('t'); // 第num week曜日の日 $day = 1 + ($params['num'] - 1) * 7 + ($params['week'] - $firstDayOfWeek) % 7; // $dayが当月範囲内ならYYYY-MM-DDを、範囲外ならfalseを返す return $day >= 1 && $day <= $lastDay ? sprintf('%04d-%02d-%02d', $year, $month, $day) : false; }書いたコード
日曜始まりの簡易的なカレンダーを作成し、曜日加算するという二段構えで実装した。
protected $month_weeks; public function __construct() { $this->month_weeks = $this->createWeekOfMonths($this->argument($target_month)) } /** * @param Carbon $start_of_month * @return array */ public function createWeekOfMonths(Carbon $start_of_month): array { //start_of_month='2020-11-01' $target_month_weeks = []; //月初の曜日取得 start_of_month_weekday=0, (ie, sunday) $start_of_month_weekday = $start_of_month->weekday(); //対象月の初週の日曜日を、取得 $target_sunday = (new Carbon())->createFromTimestamp($start_of_month->timestamp)->subDays($start_of_month_weekday); while ($target_sunday->lte($target_month->endOfMonth())) { array_push($month_weeks, (new Carbon())->createFromTimestamp($target_sunday->timestamp)); $target_sunday->addDays(7); } return $month_weeks; } //$this->createWeekOfMonths('2020-11-01'); //['2020-11-01','2020-11-08','2020-11-15','2020-11-22','2020-11-29']こうすると配列のIndexがそのままn-1週目になっている形で取得できるので、あとはこの簡易カレンダーをもとにn週目,n曜日の条件から日付を取得する。
public function getDate($week_of_month, $weekday) { $target_date = array_key_exists($week_of_month - 1, $this->month_weeks) //n週目存在チェック ? (new Carbon()) ->createFromTimestamp($this->month_weeks[$week_of_month - 1]->timestamp) //n週目の日曜日のCarbonオブジェクト取得 ->addDays($weekday) //m曜日のm分加算 (2020-11-01 sun(0) -> 2020-11-03 tue(2)) : null; return $target_date; }まとめ
簡易カレンダー作成にループ使用するのが若干嫌な気がしますが、暫定版なのでひとまずこれで対応。
- 投稿日:2020-10-12T00:09:46+09:00
[Codewars] Duplicate Encoder
概要
Codewarsの問題
Duplicate Encoder
の回答の復習とベストプラクティスをまとめる個人メモです。問題
The goal of this exercise is to convert a string to a new string where each character in the new string is "(" if that character appears only once in the original string, or ")" if that character appears more than once in the original string. Ignore capitalization when determining if a character is a duplicate.
example
"din" => "(((" "recede" => "()()()" "Success" => ")())())" "(( @" => "))(("回答
function duplicate_encode($word){ $count = 0; $result = ""; for($i=0;$i<strlen($word);$i++){ for($j=0;$j<strlen($word);$j++){ if (strtolower($word[$i]) == strtolower($word[$j])){ $count++; } } if($count>1){ $result = $result . ")"; }else{ $result = $result . "("; } $count = 0; } return $result; }
$result .= ")";
とまとめるべきです。ベストプラクティス
function duplicate_encode($word){ $word = str_split(strtolower($word)); $str = ""; foreach($word as $key){ (count(array_keys($word,$key))>1) ? $str .= ")" : $str .= "("; } return $str; }反省点
毎回forでゴリ押しているので、もう少し柔軟な書き方をしていきたいです。。