20200226のlaravelに関する記事は11件です。

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 ]] ) : string

value
エンコードする値。 リソース 型以外の任意の型を指定できます。
options
JSON_FORCE_OBJECT, .....からなるビットマスク。

以降Arrayで渡す

depth
最大の深さを設定します。正の数でなければいけません。

引数にはそれぞれ受け付ける型と意味が決まっているため、
Arrayで渡すべきところにStringを渡して、型エラーが出ていたのでした。

感想

調べているうちにAjaxのdone, fail の振り分けについても詳しくなれたので良かった。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

インフラ知識低のレイヤから勉強(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/apr

2。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のインストールが完了しました。

次にいきましょう!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

「インフラ知識」低のレイヤの勉強(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/apr

2。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のインストールが完了しました。

次にいきましょう!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【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']);

以上です!!!
ここまで読んでいただきありがとうございました!!
疑問、気になるところがございましたら、質問、コメントよろしくお願いします!!!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

githubからherokuにデプロイ

前提として
  • laravelのアプリケーションがある
  • githubにpushしている

herokuにnew appを作る

なんか適当な名前をつけてcreate new appボタンをピッ!!!

githubにあるアプリケーションをデプロイする

new appが作れたらそのappをクリックして、上にあるDeployをクリックする

スクリーンショット 2020-02-26 18.13.12.png

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と入力

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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.1

Vagrant & 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: udp

7.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
でやっと起動できました~!

image.png

まとめ

Homesteadを利用した環境構築において、
SSHまでやろうとしてもうまく行かない場合は、考えられる原因は
・Windows/System32/drivers/etc/hosts
・Homestead.yaml
・SSH鍵とその仲間.ssh/configファイル
です。ここに入力漏れがないかをみてみましょう。

ありがとうございました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[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_reverse

PHP の配列の世界で表現するとこんな感じ。

$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
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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() を使う
    • トランザクションを切る

参考


  1. Lumen でも同様 

  2. Laravel が明示的なトランザクションで Write コネクションを使うようにしているだけ 

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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構造と戦っている時にドキュメントを覗くといいやり方があったりするので、参考にできそうな感じ

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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コマンドは便利だけど、やっぱり内部実装を理解してから使わないと混乱するので、実験って大事

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む