- 投稿日:2020-02-26T23:53:18+09:00
response()->json() と return [a, b, c]のちがい
Too Long; Don't Read
LaravelでのAPIレスポンスの書き方において、
以下の2つが同じ意味だと思っていた。return response()->json( $response['error_message'], $response['status_code'], $response['example_text'] ); return [ $response['error_message'], $response['status_code'], $response['example_text'] ];
json()の省略形が[]かな
くらいに思っていた。それぞれの結果は以下。
return response()->json( $response['error_message'], $response['status_code'], $response['example_text'] ); // Type error: Argument 3 passed to Illuminate\Routing\ResponseFactory::json() must be of the type array, string given, called in ~~~~ return [ $response['error_message'], $response['status_code'], $response['example_text'] ]; // { 'error_message', 500, 'example text' }前者はエラーが起こっているのに対し、
後者は渡した内容をjson型にしている。題目のresponse()->json() と return [a, b, c]のちがい
とは、この点になる。後述するが、json()の引数はそれぞれ格納するものが決まっていて、第二引数以降にオプションを指定することができる。
そのため、
ただjson型のデータを渡せば良い時と、
オプションを指定して受け取り手へ明示的に値を渡したい時とで、使い分けると良い。今回の場合は
ajaxのdone(), fail() への振り分けを行いたかったことから、
第2引数でHttpステータスを明示できるjson()の書き方を用い、
以下の書き方に変更して無事解決。return response()->json( $response, $response['status'] );勘違いの要因
return response()->json( ['a', 'b', 'c'] );配列でjson()に渡すパターンとjson関数の仕様をごっちゃに覚えていたから。
json( )の仕様
json()は
json_encode()
を内部で用いている。json_encode ( mixed $value [, int $options = 0 [, int $depth = 512 ]] ) : stringvalue
エンコードする値。 リソース 型以外の任意の型を指定できます。
options
JSON_FORCE_OBJECT, .....からなるビットマスク。以降Arrayで渡す
depth
最大の深さを設定します。正の数でなければいけません。引数にはそれぞれ受け付ける型と意味が決まっているため、
Arrayで渡すべきところにStringを渡して、型エラーが出ていたのでした。感想
調べているうちにAjaxのdone, fail の振り分けについても詳しくなれたので良かった。
- 投稿日:2020-02-26T23:05:58+09:00
インフラ知識低のレイヤから勉強(01)
初めまして、潔(日本語の名)と申します。インフラ部は知識がありますが、バラバラです。具体的から勉強したことがありません。仕事の職場では大変ことがあります。考えているのはITエンジニアなら、インフラのことが知った方はいいともいますので、インフラの知識を調べて、メモを記入します。大先輩のオススメは低のレイヤの勉強から始まることです。下記の順番に記入する予定です。
一段階
1. Apacheをソースコードからコンパイルおよびインストール
2. PHPをSource Codeからコンパイルおよびインストール
3. PHPのMySQL Extenstionをソースコードからコンパイルおよびインストール
4. MySQLをソースコードからコンパイルおよびインストール
5. PHP FrameworkをInstall
二段階
1. Apache、MySQL、PHPのインストール
2. PHP FrameworkをInstall
三段階
1. Dockerのインストール
2. Apache + PHP Containerの構築
3. MySQL Containerの構築
4. PHP FrameworkをInstall
四段階
1. KubernetesでPHP/MySQL Webをデプロイしてみます
じゃあ、上から最後まで進めていきましょう。
最初は環境を準備しなければならない。Vagrantをきめます。
■ Vagrant環境を準備
vagrant up vagrant sshさて、Vagrant環境で操作していきます
■ Apache HTTP Server 2.4.34のソース展開
方法#1:サイトからプルしていきます
cd /usr/local/src sudo wget http://www-us.apache.org/dist/httpd/httpd-2.4.34.tar.gz sudo gzip -d httpd-2.4.34.tar.gz sudo tar xvf httpd-2.4.34.tar方法#2:Apacheのダウンロードのページにアクセスして、リンクをクリックします
リンク:https://httpd.apache.org/download.cgi
vagrant ssh cd /var/www/devOps sudo cp httpd-2.4.34.tar.gz /usr/local/src cd /usr/local/src tar zxvf httpd-2.4.34.tar.gz■ APR と APR-Utilの準備
Apache Portable Runtimeのページにアクセスして、
・apr-1.5.2.tar.gz
・apr-util-1.5.4.tar.gz
をダウンロードしますcd /usr/local/src sudo wget https://archive.apache.org/dist/apr/apr-1.5.2.tar.gz sudo gzip -d apr-1.5.2.tar.gz sudo tar xvf apr-1.5.2.tar # 展開したディレクトリをApacheのsrclibディレクトリにコピー。 sudo cp -Rp apr-1.5.2 httpd-2.4.34/srclib/apr sudo wget https://archive.apache.org/dist/apr/apr-util-1.5.4.tar.gz sudo gzip -d apr-util-1.5.4.tar.gz sudo tar xvf apr-util-1.5.4.tar # 展開したディレクトリをApacheのsrclibディレクトリにコピー。 sudo cp -Rp apr-util-1.5.4 httpd-2.4.34/srclib/apr-util■ configure実行
cd httpd-2.4.34 sudo ./configure■ make・make installを実行します
sudo make sudo make install注意:インストールするときエラー
1。APRのインストールしていない
checking for APR... no configure: error: APR not found. Please read the documentation.解決方法
APRのインストールしていきます cd /usr/local/src sudo wget https://archive.apache.org/dist/apr/apr-1.5.2.tar.gz sudo gzip -d apr-1.5.2.tar.gz sudo tar xvf apr-1.5.2.tar # 展開したディレクトリをApacheのsrclibディレクトリにコピー。 sudo cp -Rp apr-1.5.2 httpd-2.4.34/srclib/apr2。Perl-Compatible Regular Expressions Library(PCRE)をインストールしていない
checking for pcre-config... false configure: error: pcre-config for libpcre not found. PCRE is required and available from http://pcre.org/解決方法#1
・pcre.orgサイトからpcreをダウンロードします
・プレフィックスをつけてコンパイルして、インストルしますvagrant ssh cd /usr/local/src/ cd pcre.8.39 sudo ./configure --prefix=/usr/local/pcre sudo make sudo make install・Apacheがインストールされているところで、pcreをつ使用してApacheをコンパイルします
cd http httpd-2.4.34 sudo ./configure --with-pcre=/usr/local/pcre sudo make make install解決方法#2
pcre-develをインストルするだけでした# Fedora Linux yum install -y pcre-devel解決方法#3
RHEL3では、pcre-configを指します。./configure --prefix=/usr/local/apache2 --with-pcre=/usr/local/pcreこれでApacheのインストールが完了しました。
次にいきましょう!
- 投稿日:2020-02-26T23:05:58+09:00
「インフラ知識」低のレイヤの勉強(01)
初めまして、潔(日本語の名)と申します。インフラ部は知識がありますが、バラバラです。具体的から勉強したことがありません。仕事の職場では大変ことがあります。考えているのはITエンジニアなら、インフラのことが知った方はいいともいますので、インフラの知識を調べて、メモを記入します。大先輩のオススメは低のレイヤの勉強から始まることです。下記の順番に記入する予定です。
一段階
1. Apacheをソースコードからコンパイルおよびインストール
2. PHPをSource Codeからコンパイルおよびインストール
3. PHPのMySQL Extenstionをソースコードからコンパイルおよびインストール
4. MySQLをソースコードからコンパイルおよびインストール
5. PHP FrameworkをInstall
二段階
1. Apache、MySQL、PHPのインストール
2. PHP FrameworkをInstall
三段階
1. Dockerのインストール
2. Apache + PHP Containerの構築
3. MySQL Containerの構築
4. PHP FrameworkをInstall
四段階
1. KubernetesでPHP/MySQL Webをデプロイしてみます
じゃあ、上から最後まで進めていきましょう。
最初は環境を準備しなければならない。Vagrantをきめます。
■ Vagrant環境を準備
vagrant up vagrant sshさて、Vagrant環境で操作していきます
■ Apache HTTP Server 2.4.34のソース展開
方法#1:サイトからプルしていきます
cd /usr/local/src sudo wget http://www-us.apache.org/dist/httpd/httpd-2.4.34.tar.gz sudo gzip -d httpd-2.4.34.tar.gz sudo tar xvf httpd-2.4.34.tar方法#2:Apacheのダウンロードのページにアクセスして、リンクをクリックします
リンク:https://httpd.apache.org/download.cgi
vagrant ssh cd /var/www/devOps sudo cp httpd-2.4.34.tar.gz /usr/local/src cd /usr/local/src tar zxvf httpd-2.4.34.tar.gz■ APR と APR-Utilの準備
Apache Portable Runtimeのページにアクセスして、
・apr-1.5.2.tar.gz
・apr-util-1.5.4.tar.gz
をダウンロードしますcd /usr/local/src sudo wget https://archive.apache.org/dist/apr/apr-1.5.2.tar.gz sudo gzip -d apr-1.5.2.tar.gz sudo tar xvf apr-1.5.2.tar # 展開したディレクトリをApacheのsrclibディレクトリにコピー。 sudo cp -Rp apr-1.5.2 httpd-2.4.34/srclib/apr sudo wget https://archive.apache.org/dist/apr/apr-util-1.5.4.tar.gz sudo gzip -d apr-util-1.5.4.tar.gz sudo tar xvf apr-util-1.5.4.tar # 展開したディレクトリをApacheのsrclibディレクトリにコピー。 sudo cp -Rp apr-util-1.5.4 httpd-2.4.34/srclib/apr-util■ configure実行
cd httpd-2.4.34 sudo ./configure■ make・make installを実行します
sudo make sudo make install注意:インストールするときエラー
1。APRのインストールしていない
checking for APR... no configure: error: APR not found. Please read the documentation.解決方法
APRのインストールしていきます cd /usr/local/src sudo wget https://archive.apache.org/dist/apr/apr-1.5.2.tar.gz sudo gzip -d apr-1.5.2.tar.gz sudo tar xvf apr-1.5.2.tar # 展開したディレクトリをApacheのsrclibディレクトリにコピー。 sudo cp -Rp apr-1.5.2 httpd-2.4.34/srclib/apr2。Perl-Compatible Regular Expressions Library(PCRE)をインストールしていない
checking for pcre-config... false configure: error: pcre-config for libpcre not found. PCRE is required and available from http://pcre.org/解決方法#1
・pcre.orgサイトからpcreをダウンロードします
・プレフィックスをつけてコンパイルして、インストルしますvagrant ssh cd /usr/local/src/ cd pcre.8.39 sudo ./configure --prefix=/usr/local/pcre sudo make sudo make install・Apacheがインストールされているところで、pcreをつ使用してApacheをコンパイルします
cd http httpd-2.4.34 sudo ./configure --with-pcre=/usr/local/pcre sudo make make install解決方法#2
pcre-develをインストルするだけでした# Fedora Linux yum install -y pcre-devel解決方法#3
RHEL3では、pcre-configを指します。./configure --prefix=/usr/local/apache2 --with-pcre=/usr/local/pcreこれでApacheのインストールが完了しました。
次にいきましょう!
- 投稿日:2020-02-26T20:27:23+09:00
【Laravel】フラッシュデータを使おう
はじめに
Laravelを触り始めた時、簡単なCRUD機能を持ったToDoアプリを作りました。
その時、データベースに保存したり、削除したりできるような機能を実装していました。
しかし、保存ボタンや削除ボタンを押してもアクションの処理が走るだけで味気ないです。保存できても出来てなくてもリダイレクトしたページを表示するだけです。
そんな味気ないアプリケーション嫌だ!!!!「保存に成功しました」ぐらいのステータスメッセージを表示はしてほしい。。。メッセージがないと成功か失敗かわからないですよね。
しかし、意外とステータスメッセージを自力で実装することはめんどくさいです。その理由を2つあげます。。
- 保存処理が実行した時にメッセージの内容を設定します。保存処理では最後にリダイレクトすることがほとんどだと思うので、メッセージの内容をリダイレクト先のアクションへ渡します。受け取ったアクションからビューへ受け渡すようにコードを書かないといけません。
- ステータスメッセージの表示は基本的に一回だけです。保存処理後のリダイレクト先のページから他のページにアクセスする時にメッセージを表示されないようにしないといけません。
上記の理由でステータスメッセージを自力で実装するのはとてもめんどくさいです。。
そんな時にセッションのフラッシュデータです!!!
セッション?フラッシュデータ?となると思いますので、ざっくり説明します
セッションを使うことでWebブラウザが閉じるまで一時的にサーバー側にデータを保存することが出来ます
フラッシュデータは次のリクエストまでの間セッションに保存されるデータのことです。
次のリクエスト(他のページへアクセスなど)では削除されます。ですので、フラッシュデータは主にステータスメッセージなど継続しない情報にはもってこいです!!ではフラッシュデータを使ってステータスメッセージを表示させる方法を解説します。
フラッシュデータの渡し方
フラッシュデータの渡し方は主に3種類あります
flashメソッドで渡す
Flashメソッドを使うとセッションへ
status
という名前のデータを保存できます。
status
の中身は処理が完了しました
です保存アクション内$request->session()->flash('status', '処理が完了しました'); return redirect('/');スタティックメソッドを使う
Sessionクラスのflashメソッドを使うことでも値を渡すことができます
保存アクション内\Session::flash('flash_message', '処理が完了しました'); return redirect('/');withメソッドを使う
flash
メソッドと同じようにフラッシュデータを渡せるwith
メソッドもあります保存アクション内return redirect('dashboard')->with('status', '処理が完了しました');ビューでの表示
次にビューでの表示の仕方について説明します
Bootstrapを使えばいい感じに表示してくれます@if (session('status')) <div class="alert alert-success"> {{ session('status') }} </div> @endif以上がフラッシュデータを使ったステータスメッセージの表示仕方です。
おまけ
以下おまけです。
フラッシュデータを1つ先のリクエストまで持続させたい場合
reflash
メソッドを使うと全フラッシュデータを次のリクエストまで保持できます。$request->session()->reflash();特定のフラッシュデータのみ持続させたい場合
keep
メソッドを使います。$request->session()->keep(['user', 'email']);以上です!!!
ここまで読んでいただきありがとうございました!!
疑問、気になるところがございましたら、質問、コメントよろしくお願いします!!!
- 投稿日:2020-02-26T20:10:03+09:00
githubからherokuにデプロイ
前提として
- laravelのアプリケーションがある
- githubにpushしている
herokuにnew appを作る
なんか適当な名前をつけてcreate new appボタンをピッ!!!
githubにあるアプリケーションをデプロイする
new appが作れたらそのappをクリックして、上にあるDeployをクリックする
githubを選んで、その下でレポジトリを選ぶ。
最後にbranchを選んでdeployボタンをピッ!!!
APP_KEYを設定する
今の状態だと、デプロイはできるものの
Whoops, looks like something went wrong.
ってエラーが画面に出てくるので、
APP_KEYを設定する必要があるこれはsettingをポチッとして上から2番目のConfig Varsというところに、
ターミナルで
php artisan key:generate --show
と入力しててできたkeyを登録すればいい右側にはAPP_KEYと入力
- 投稿日:2020-02-26T13:16:45+09:00
Laravel HomesteadでVagrant SSHがなかなかできなかった話
Railsを今までずっとやっていましたが、Laravelも学び始めた時にまず環境構築からだよなぁと思い、Qiita内の記事を参考にしながらComposerオンリーで作ってみたり、Homesteadを使ってみたりとしておりましたが、Homesteadで一日沼にハマってしまったので、こちらに備忘録的に書いておきたいと思います。
皆様の参考になれば幸いです。とっても参照してお世話になった記事は 「こちら」からどうぞ!
バージョン情報
PC:Windows10 home 1903
Vagrant 2.2.7
Virtual Box 6.1.2
Composer 1.9.3
Laravel 6.15.1Vagrant & Virtual Box
上記各々検索して出てきた公式サイトにてダウンロード可能です。
Homesatead
こちらでざっと環境開発に必要なプロセスを載せていきます。
1.ホームディレクトリにてvagrant box add laravel/homesteadと入力してHomestead専用のVagrant Boxをインストールします。専用のVagrantfileも生成されます。
virtual Boxの番号を聞かれたら3でいいと思います。※この処理に時間がかかります。2.ユーザーフォルダ直下やCフォルダ直下、デスクトップなどで任意の作業用フォルダを作ります。
3.作業用フォルダ内で
git clone https://github.com/laravel/homestead.git Homesteadと入力しHomesteadを召喚します。
4.Homeasteadフォルダもできるので、移動して
bash init.shと入力してHomeasteadの初期化を行います(これをやらないと不具合がでるらしい)Homeastead initialized等の文言が出てきたらOK
5.もしSSH鍵を生成していなかったら、
ssh-keygenで作っておきましょう。エクスプローラーのユーザ/.ssh内にid_rsaとid_rsa.pubがあればできています。コマンドで
ls -la .sshとかでも見ることができます。
6.Homeasteadディレクトリに移動して、
vim homestead.yamlで下記の用な感じに編集します。
-- ip: "192.168.10.10" #任意のIPアドレス memory: 2048 cpus: 1 provider: virtualbox authorize: ~/.ssh/id_rsa.pub keys: - ~/.ssh/id_rsa folders: - map: ~/app #任意の作業用フォルダ to: /home/vagrant/Code sites: - map: homestead.test #任意のホスト名 to: /home/vagrant/Code/Laravel/public #Laravelは作成するプロジェクト名、何でも良い databases: - homestead # blackfire: # - id: foo # token: bar # client-id: foo # client-token: bar # ports: # - send: 50000 # to: 5000 # - send: 7777 # to: 777 # protocol: udp7.vagrantを
vagrant up --provision #provision入れると不具合が起きにくいかとで起動しましょう。
The specified host network collides with a non-hostonly network! This will cause your specified IP to be inaccessible. Please change the IP or name of your host only network so that it no longer matches that of a bridged or non-hostonly network.と出てきた場合は、Windows/System32/drivers/etc/hostsを管理者権限のあるエディタで開き、
ipと任意のホスト名を入力してあげましょう。8.以上が完了したら、
vagrant sshを入力することでSSH接続が完了します。vagrant@homesteadというディレクトリ名に変わってると思います。
cd code composer create-project laravel/laravel --prefer-dist ディレクトリ名 #この処理に時間がかかりますとすることで編集するプロジェクトが立ち上がり、編集が可能になります。
ちゃんとサーバーに接続できてるか確認するために、ipアドレスをブラウザに入力してみましょう。あれ????できない????
Vagrant SSHができなかった・・・
何回やってもSSH接続ができない!そこで周りの猛者にきいてみたところ、
.ssh/configってなんやこれ?邪魔っぽくね?
というふうに見解をもらったので、すでに生成されているSSH鍵と一緒に右クリック!!!!
新しく鍵を作り直すと、
vagrant ssh
でやっと起動できました~!まとめ
Homesteadを利用した環境構築において、
SSHまでやろうとしてもうまく行かない場合は、考えられる原因は
・Windows/System32/drivers/etc/hosts
・Homestead.yaml
・SSH鍵とその仲間.ssh/configファイル
です。ここに入力漏れがないかをみてみましょう。ありがとうございました。
- 投稿日:2020-02-26T11:11:03+09:00
[Laravel] Collection の順番を逆にしたいけどキーが邪魔になるとき
Laravel の Collection は
reverse()
メソッドによって逆順に並び替えることができます。
しかし以下のようにキーが付与(*1)されてしまうので、思い通りの比較ができないことがあります。$collection = collect(['a', 'b', 'c', 'd', 'e']); $reversed = $collection->reverse(); /* [ 4 => 'e', 3 => 'd', 2 => 'c', 1 => 'b', 0 => 'a', ] */ $otherCollection = collect(['e', 'd', 'c', 'b', 'a']); echo $otherCollection === $reversed; // falseそうじゃないんだよ、欲しいのは
['e', 'd', 'c', 'b', 'a']
なんだよって時は
values()
メソッドでキーを削除(*2)しちゃいましょう。$collection = collect(['a', 'b', 'c', 'd', 'e']); $reversed = $collection->reverse()->values(); /* ['e', 'd', 'c', 'b', 'a'] */ $otherCollection = collect(['e', 'd', 'c', 'b', 'a']); echo $otherCollection === $reversed; // true*1 「付与」→正確には「保持」
*2 「削除」→正確には「リセット」
説明は次の項にてなぜなのか?
前項で使った「付与される」という表現は正確ではなく、 Laravel のドキュメントにもある通りキーが保持された結果として、「新たにキーが付与された」ように見えているだけです。
コレクション前提としてPHPでは、全ての配列は以下のようにキーを持っています。
$array = ['a', 'b', 'c', 'd', 'e']; /* [ 0 => 'a', 1 => 'b', 2 => 'c', 3 => 'd', 4 => 'e', ] */さて、 Collection の
reverse()
では PHP のarray_reverse()
を利用していますが、
第2引数にtrue
を指定しているのにご注目?public function reverse() { return new static(array_reverse($this->items, true)); }
array_reverse()
の第2引数はpreserve_keys
「キーを保持」するパラメーターです。
array_reversePHP の配列の世界で表現するとこんな感じ。
$array = ['a', 'b', 'c', 'd', 'e']; $otherArray = ['e', 'd', 'c', 'b', 'a']; /* [ 0 => 'e', 1 => 'd', 2 => 'c', 3 => 'b', 4 => 'a', ] */ $reversed = array_reverse($array, true); /* [ 4 => 'e', 3 => 'd', 2 => 'c', 1 => 'b', 0 => 'a', ] */ echo $otherArray === $reversed; // false // キーが一致しないので別の配列Laravel の
values()
では、array_values()
を呼び出しています。public function values() { return new static(array_values($this->items)); }
array_values()
は配列の値を取り出してキーを振り直すメソッドなので、以下のように欲しい配列を取得することができるんですね。
array_values$array = ['a', 'b', 'c', 'd', 'e']; $otherArray = ['e', 'd', 'c', 'b', 'a']; $reversed = array_values(array_reverse($array, true)); /* [ 0 => 'e', 1 => 'd', 2 => 'c', 3 => 'b', 4 => 'a', ] */ echo $otherArray === $reversed; // true // 配列でやるなら単純にこれでもいい $reversed2 = array_reverse($array, false); /* [ 0 => 'e', 1 => 'd', 2 => 'c', 3 => 'b', 4 => 'a', ] */ echo $otherArray === $reversed2; // true
- 投稿日:2020-02-26T09:01:45+09:00
Laravel で Read/Write 構成のデータベースに対して明示的に Write コネクションを指定する方法
手っ取り早く結論
- Laravel で明示的に Write コネクションを指定する方法はざっくり 3 つある
- Eloquent Model で
protected $connection
を指定するonWriteConnection()
を使う- トランザクションを切る
前提となる背景
- Laravel1 でデータベースのコネクション設定を Read/Write 構成にすると、参照系のクエリは暗黙的に Read コネクションを使う
- 参照系のクエリで Write コネクションを利用したいときがある
- Read コネクションがリードレプリカに向いていて、書き込み遅延がある
- 更新直後に異なるリクエストによる参照が発生することがあり、書き込み遅延が間に合わず最新のレコードを取得できない
- 更新直後に最新のレコードを取得したいため、一部の参照系で Write コネクションを利用したい
根本的には設計のミスだと思っています。
しかし一旦、この設計は変えられない前提で、小手先のテクニックでなんとかする方法を紹介します。確認バージョン
- Laravel 5.5
- Laravel 6.x
データベース設定
このような設定のとき、参照系のクエリのコネクションに
DB_HOST_WRITE
を使いたい。config/database.php'mysql' => [ 'driver' => 'mysql', 'read' => [ 'host' => env('DB_HOST_READ', env('DB_HOST', 'localhost')), ], 'write' => [ 'host' => env('DB_HOST_WRITE', env('DB_HOST', 'localhost')), ],
protected $connection
Eloquent Model の
protected $connection
に'コネクション名::write'
を入れましょう。
特定のテーブルや Eloquent Model で常に Write を参照したい場合に有効です。class User extends Model implements AuthenticatableContract, AuthorizableContract { use Authenticatable, Authorizable; protected $connection = 'mysql::write';このプロパティがどういう働きをするのかは、このあたりのコードを読むと理解できます。
https://github.com/laravel/framework/blob/5.5/src/Illuminate/Database/DatabaseManager.php#L87
- Pros
- 常に最新のレコードを取得できる
- Cons
- Write コネクションへの負荷が増える
総評
- 社内管理画面など、一部のユーザーが利用するような低トラフィックなアプリケーション&セッションストアにデータベースを採用している場合に有効だと思います
- 高トラフィックで常に最新のレコードを取りたい、という場合には性能的な厳しさに直面すると思います
- 更新時に Redis にキャッシュするなど、他の高速なデータストアの利用を検討したほうが良さそう
onWriteConnection()
Eloquent Model の特定クエリで Write を参照したいときに便利です。
$user = User::onWriteConnection()->first();https://github.com/laravel/framework/blob/5.5/src/Illuminate/Database/Eloquent/Model.php#L344
- Pros
- Write コネクションの負荷を最小限に抑えられる
- 特定のユースケースで最新のレコードを取得できる
- Cons
onWriteConnection()
を書くべきところで書き忘れるとバグる- 遅延によるのでたまにしか再現しなかったりする
総評
- 小手先テクニックとしては個人的にオススメです
- 書き忘れが怖いなら
protected $connection
を検討しましょう- このやり方がツラいときは設計から見直したほうが良いでしょう
トランザクションを切る
Laravel はトランザクションを切ると暗黙的に Write コネクションを利用します。
これはトランザクション本来の用途ではありません2が、1リクエスト中の複数の参照クエリで読み取り一貫性をもたせたいという要求もセットで叶えるならこれです。
Laravel でトランザクションの切り方はドキュメントを見てください。https://laravel.com/docs/5.5/database#database-transactions
- Pros
- 1リクエスト中の複数の参照クエリで読み取り一貫性をもたせられる(※)
- 特定のユースケースで最新のレコードを取得できる
- Cons
- 暗黙的に Write コネクションを利用しているため、知らない人はコードを読んでも分からない
- トランザクションを切っている理由をコメントに書いてあげると親切ですね
(※)トランザクション中の実際の読み取り一貫性はデータベースエンジンやその設定によって左右されます。設定がどうなっているか、実際にトランザクションを切ってどういう振る舞いをするかは確認してください。
総評
- 複数の参照クエリで読み取り一貫性を持たせたい場合はこれしかないです
- 単に Write コネクションを利用したいだけなら
onWriteConnection()
かprotected $connection
を最初に検討しましょうまとめ
- Laravel で明示的に Write コネクションを指定する方法はざっくり 3 つある
- Eloquent Model で
protected $connection
を指定するonWriteConnection()
を使う- トランザクションを切る
参考
- 投稿日:2020-02-26T03:37:47+09:00
Laravel Homestead上のサイトにスマホからアクセスする
環境
- Vagrant 2.2.7
- Laravel Homestead 9.2.0
事前準備
開発用マシン(Laravel Homesteadを実行しているマシン)とスマホを同じWi-Fi(LAN)に接続してから設定作業に進んでください。
設定
プロビジョニングスクリプト修正
スマホからアクセスできるように、仮想マシンにパブリックな(他のホストから見える)IPを振ってあげます。
config.vm.network :public_network, ip: '192.168.0.100'
を追記します。
IPアドレスは空いてるものなら何でもいいですが、LAN内のサブネットを指定しないと繋がらないため、注意してください。(私の環境では、192.168.1.100だと接続できませんでした。)~/Homestead/scripts/homestead.rb(更新前)略 # Configure A Private Network IP if settings['ip'] != 'autonetwork' config.vm.network :private_network, ip: settings['ip'] ||= '192.168.10.10' else config.vm.network :private_network, ip: '0.0.0.0', auto_network: true end # Configure Additional Networks 略↓
~/Homestead/scripts/homestead.rb(更新後)略 # Configure A Private Network IP if settings['ip'] != 'autonetwork' config.vm.network :private_network, ip: settings['ip'] ||= '192.168.10.10' else config.vm.network :private_network, ip: '0.0.0.0', auto_network: true end config.vm.network :public_network, ip: '192.168.0.100' # ←追記 # Configure Additional Networks 略仮想マシンの再プロビジョニング
以下のコマンドを叩いて、仮想マシンを作り直します。
インタフェースにWi-Fiを指定して、プロビジョニングの完了を待ちます。$ vagrant reload --provision ==> homestead: Attempting graceful shutdown of VM... ==> homestead: Checking if box 'laravel/homestead' version '9.2.0' is up to date... ==> homestead: Clearing any previously set forwarded ports... ==> homestead: Clearing any previously set network interfaces... ==> homestead: Available bridged network interfaces: 1) en0: Wi-Fi (AirPort) 2) p2p0 3) awdl0 4) en1: Thunderbolt 1 5) en2: Thunderbolt 2 6) bridge0 ==> homestead: When choosing an interface, it is usually the one that is ==> homestead: being used to connect to the internet. ==> homestead: homestead: Which interface should the network bridge to? 1アクセスしてみる
スマホで http://192.168.0.100/ にアクセスするとサイトが見えるようになっているはずです。
やったね!参考
macos - vagrant homestead - public network not working on osx - Stack Overflow
https://stackoverflow.com/questions/26353186/vagrant-homestead-public-network-not-working-on-osx
- 投稿日:2020-02-26T01:02:14+09:00
Eloquentモデルのクラス名から主キーを取得する
はじめに
既存のDB構成の都合上主キー名が異なるテーブルで条件付きでID一覧をクラスごとに取ろうとしたときにいい方法に出会ったのでそのメモ
愚直な方法
クラス名指定で書くと似たような箇所も多く追加でいちいちcaseを増やさないといけなく面倒・・・
// それぞれ主キー名が異なる類似したモデル use App\Hoge; use App\Fuga; function scopedIds(string $className): array { switch ($className) { case Hoge::class: return Hoge::scope()->pluck('hoge_id'); case Fuga::class: return Fuga::scope()->pluck('fuga_id'); } }Eloquentモデルの
getKeyName
でやってみるhttps://laravel.com/api/6.x/Illuminate/Database/Eloquent/Model.html#method_getKeyName
EloquentモデルのメソッドとしてgetKeyName
という主キー名を取得するものがあり、これ活用するとシンプルに済むfunction scopedIds(string $className): array { $primaryKey = (new $className())->getKeyName(); return $className::scope()->pluck($primaryKey); }終わりに
調べてみるとまだまだ便利なメソッドが提供されているので、複雑なDB構造と戦っている時にドキュメントを覗くといいやり方があったりするので、参考にできそうな感じ
- 投稿日:2020-02-26T00:17:01+09:00
Laravel Horizonのfailed_jobsテーブルを生SQL(PostgreSQL)で追加してみる
はじめに
Laravel Horizon導入時に失敗したjobを溜め込む
failed_jobs
テーブルが必要ですが、migrateがLaravelとは別で機能しているため、自前でテーブル構成を定義したときの話です環境
name ver PHP 7.3 Laravel 6.5 PostgreSQL 10.6 Laravelでマイグレーションした場合のテーブル構造
既存でPostgreSQLを使ってHorizonを導入しているプロジェクトがあったのでテーブルをみてみるとこんな感じだった
hoge=> \d+ failed_jobs Table "public.failed_jobs" Column | Type | Collation | Nullable | Default | Storage | Stats target | Description ------------+--------------------------------+-----------+----------+-----------------------------------------+----------+--------------+------------- id | bigint | | not null | nextval('failed_jobs_id_seq'::regclass) | plain | | connection | text | | not null | | extended | | queue | text | | not null | | extended | | payload | text | | not null | | extended | | exception | text | | not null | | extended | | failed_at | timestamp(0) without time zone | | not null | CURRENT_TIMESTAMP | plain | | Indexes: "failed_jobs_pkey" PRIMARY KEY, btree (id)念の為新規でLaravelの環境を用意してチュートリアルどおり入れてみても同様なのでこの構成で大丈夫そう
https://readouble.com/laravel/6.x/ja/queues.html実行したSQL
上のテーブル構造から以下のSQLを実行で問題なく作成できた
CREATE TABLE failed_jobs ( id BIGSERIAL PRIMARY KEY, connection TEXT NOT NULL, queue TEXT NOT NULL, payload TEXT NOT NULL, exception TEXT NOT NULL, failed_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP );おわりに
artisan
コマンドは便利だけど、やっぱり内部実装を理解してから使わないと混乱するので、実験って大事