20211022のlaravelに関する記事は6件です。

【Laravel】Redisのレプリケーション

はじめに Laravelで作ったアプリケーションについて、Webサーバ1台構成から、 負荷分散のためにロードバランサーを導入し、Webサーバ2台構成へ変更しました。 元々WebサーバのキャッシュクライアントでRedisを導入していたのですが、 Webサーバの増設に伴い、追加するWebサーバにもRedisを導入する必要が生じます。 また、Redisに格納されているキャッシュデータはWebサーバ毎に差分が出てはいけないため、 それぞれのWebサーバのRedis同士で同期が取れている必要があります。 今回は、元々あるWebサーバのRedisを新しく追加したWebサーバのRedisへレプリケーションする方法について 紹介します。 便宜上、元々のWebサーバをWeb1号機、追加するWebサーバをWeb2号機としています。 また、RedisのレプリケーションについてはWeb1号機をMaster、Web2号機をSlaveとするMaster-Slave構成にしています。 システム構成の変更は下記の図のようになります。 環境 Laravel 6.5 Redis 6.2.3 Master・Slaveの疎通確認 Redisの初期設定のままだと、接続設定はそれぞれ127.0.0.1(localhost)のみです。 (Master側で) $ redis-cli -h 192.168.1.y Could not connect to Redis at 192.168.1.y:6379: Connection refused not connected> SlaveからMasterへの接続設定を行う Master・Slaveともに、/etc/redis/redis.confの接続設定部分を修正します。 bind 127.0.0.1 → bind 0.0.0.0 redisの再起動をそれぞれ実行します。 $ systemctl restart redis.service 疎通確認 Master・Slaveそれぞれで疎通確認を行います。 (Master側で) $ redis-cli -h 192.168.1.y 192.168.1.y:6379> (Slave側で) $ redis-cli -h 192.168.1.x 192.168.1.x:6379> サーバ間の疎通が通っていることを確認します。 レプリケーション設定 Slaveのredis.confを修正します。 slaveof <masterのIP> <masterのredisのport番号> と、記載することで、MasterとSlaveの対応関係を設定できます。 slaveof 192.168.1.y 6379 redisの再起動をそれぞれ行います。 $ systemctl restart redis.service レプリケーションの確認 設定の確認 SlaveでMasterがレプリケーションされているか確認します。 (Slave側で) $ redis-cli 127.0.0.1:6379> INFO // 割愛 # Replication role:slave master_host:192.168.1.x master_port:6379 Replication欄のmaster_hostに、設定したMasterのIPアドレスが記載されていれば、レプリケーション設定ができています。 Master側でも設定を確認します。 $ redis-cli 127.0.0.1:6379> INFO # Replication role:master connected_slaves:1 slave0:ip=192.168.1.y,port=6379,state=online,offset=110155,lag=1 Replication欄のslave0に、設定したSlaveのIPアドレスが記載されていればOKです。 今回は行っていないですが、Masterに対して複数のSlaveを持たせることも可能です。 データ同期の確認 Master側で、setしたデータが、Slave側にレプリケーションされているかを確認します。 (Master側で) 127.0.0.1:6379> set key1 value1 OK 127.0.0.1:6379> keys * 1) "key1" (上記実行後、Slave側で) 127.0.0.1:6379> keys * 1) "key1" データの削除も同様に、MasterがSlaveにレプリケーションされます。 (Master側で) 127.0.0.1:6379> keys * 1) "key1" 127.0.0.1:6379> flushdb OK 127.0.0.1:6379> keys * (empty list or set) (上記実行後、Slave側で) 127.0.0.1:6379> keys * (empty list or set) なお、Slaveは参照のみのため、Slaveに対してデータの追加や削除を行おうとすると、エラーが出ます。 (上記実行後、Slave側で) 127.0.0.1:6379> set key1 value1 (error) READONLY You can't write against a read only slave. キャッシュの参照は、それぞれのRedis(つまりlocalhost)を、追加・更新・削除については、Masterを参照するよう、プログラム側で制御する必要があります。 Laravel Redisの設定内容の変更 アプリケーション内のキャッシュの設定については、config/cache.phpに記載されています。 storesキーの中に、redisの設定内容が記載されています。 'stores' => [ // 割愛 'redis' => [ 'driver' => 'redis', 'connection' => 'cache', ], // 割愛 ], デフォルトではredisの記述は1つ(localhost)だけしかないですが、今回は、読み込み/書き込みで2つ分の設定内容が必要なので、設定内容を下記のように変更します。 'stores' => [ // 割愛 'redis_read' => [ 'driver' => 'redis', 'connection' => 'read_cache', ], 'redis_write' => [ 'driver' => 'redis', 'connection' => 'write_cache', ], // 割愛 ], connectionに指定している項目は、キャッシュクライアントの接続先を、config/database.php内のdriverの項目(つまりredis)の、どの値を用いるか、を記載したものになります。 デフォルトのconfig/database.phpは下記のように記載されています。 'redis' => [ 'client' => env('REDIS_CLIENT', 'phpredis'), 'default' => [ 'host' => env('REDIS_HOST', '127.0.0.1'), 'password' => env('REDIS_PASSWORD', null), 'port' => env('REDIS_PORT', 6379), 'database' => env('REDIS_DB', 0), ], 'cache' => [ 'host' => env('REDIS_HOST', '127.0.0.1'), 'password' => env('REDIS_PASSWORD', null), 'port' => env('REDIS_PORT', 6379), 'database' => env('REDIS_CACHE_DB', 1), ], ], 読み込み/書き込みそれぞれの接続情報を分けて記述する必要があるので、下記のように修正します。 'redis' => [ 'client' => env('REDIS_CLIENT', 'phpredis'), 'default' => [ 'host' => env('REDIS_HOST', '127.0.0.1'), 'password' => env('REDIS_PASSWORD', null), 'port' => env('REDIS_PORT', 6379), 'database' => env('REDIS_DB', 0), ], 'read_cache' => [ 'url' => env('REDIS_URL'), 'host' => env('REDIS_HOST', '127.0.0.1'), 'host' => env('REDIS_HOST_READ', '127.0.0.1'), 'password' => env('REDIS_PASSWORD', null), 'port' => env('REDIS_PORT', 6379), 'database' => env('REDIS_CACHE_DB', 1), ], 'write_cache' => [ 'url' => env('REDIS_URL'), 'host' => env('REDIS_HOST_WRITE', '127.0.0.1'), 'password' => env('REDIS_PASSWORD', null), 'port' => env('REDIS_PORT', 6379), 'database' => env('REDIS_CACHE_DB', 1), ], ], また、read_cacheとwrite_cacheのhost(IPアドレス)については、.envファイルに記載をします。 REDIS_HOST_READ=127.0.0.1 REDIS_HOST_WRITE=192.168.1.x 読み込みのRedisのIPアドレスは127.0.0.1(localhost)を指定します。つまり、参照するRedisは自身のWebサーバ内のRedisを参照します。 書き込みのRedisのIPアドレスはMasterのIPアドレスを指定します。こうすることで、Web1号機・Web2号機ともにMasterのRedisに対してデータの書き込みを行うようにすることができます。 最後に Webサーバ2台構成でのRedisのMaster-Slave構成について、そこまで複雑な設定は必要なく、実装することができました。 レプリケーションだけではなく、クラスタリングなどもできるようなので、機会があれば勉強したいと思います。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravel+Vueをレンタルサーバーを想定してローカル環境で開発したい

初心者様向け記事として忘備録を兼ねて書きました。 Laravelを最近はじめました。 PHPフレームワークがCakeが2になった頃以来で(え?もう10年経ってるかも・・)いろいろ戸惑ったのでそこを共有できたらと・・ 私が想定してたのはLaravel部分は完全に新規ですが、サーバーにはすでに何らかのシステムが動いていて、とあるフォルダ内にこのLaravelのシステムを入れたいんだ!って言う状況です。 「初心者がLaravelに手を出すな!」とか質問で答えてた人が過去にいましたが、さすがに余計なお世話でしょう。 ただ実際のネット上の記事はまっさらなサーバーにLaravelをドカンと置く想定の記事が非常に多く、今回の想定の物はズバリはかなり少なかったのでCakeの時も苦労しましたが、結局今回も苦労しましたので残しておこうという感じです。 そんなLaravel初心者の私が初心者+安めのレンタルサーバーを想定して、さらにローカルで開発するにあたっての環境を作ってみたいと思います。 当然セオリー外の事も多いかと思いますがやばい所はやんわりと指摘していただけると嬉しいです。 長いですが中身はないので中級者以上の方はそろりとBackSpaceを・・・ 今あるシステムの管理画面を今回Laravelで作り直す!って言う想定です。 想定する技量 ・下の記述に等しいですが、Node.js npm PHP MySQL composer について全くわからない・・は難しいかと ・composerやnpmについて最低限使えて、Laravelのプロジェクトを作ったりそこにVueの環境を作ったり「php artisan serveでlocalhost:8000が起動してくる」とか「npm run watch」は問題ないぞって言う人はほぼ問題ないかと ・筆者の環境はWindows ・ローカルはXAMPPで良いけどPHP+MySQLであること ・Laravelは最新(この記事を書いている段階ですとLaravelは8.65.0が入る) ・PHPは7.4でやってます(Laravel8だと7.3以上じゃないと動かないはずなので問題ないと思う ・Laravel+Vue (個人的な環境はそこにVuetify+Tailwindcss) ・レンタルサーバーは、XSERVERのX10やさくらインターネットのスタンダード等、「SSHで接続できる」、「シンボリックリンクが張れる」サーバーなら大丈夫と思います。 問題ある人はまずは他記事でそこまでを学習してください。 まずはプロジェクトが作られており正しい場所で公開される事(見せたいURLでアクセスできる)がまず最初 どういう話かというと、Laravelプロジェクトを作っても正しい位置(URL)で公開できないと意味なくね?じゃあどうやるの?って話です。 私の場合はここが最初に気になったので。 意味はこの先にも書いてありますがLaravelに限らずPHPフレームワークは通常サーバーの公開部分にプロジェクトを置きません。 ですのでLaravelプロジェクトの公開部分は当然サーバーの非公開部分に存在します(ややこしい言い方 ですので、通常は一番後回しの部分を先にやって安心したいという話です(汗 フォルダ構成 フォルダの構成はこんな感じで。 /home/ユーザー名/ドメイン名/public_html/*.*(すでにあるシステム) | |-laravel/app | /public/*.* って感じです(簡略しすぎ XSERVER等では記述した感じで、さくらインターネットですと「public_html」が「www」になりますね。 公開ルートより下部にプロジェクトを置くのはフレームワークでは割と普通です。 じゃあLaravelの公開はルート下部にあるのにそれをどうしたらすでにあるするのか?さあわからない。 よく検索すると出てくるのは「publicのindex.phpを移動して云々」って記事です。 はっきり言ってこれは悪手だと思います。 こんごindex.phpの扱いが一切変更がないともわからないですし、何よりもファイルを移動させるのは個人的に嫌なので。 結果として個人的に一番正解かなと思ったのは「シンボリックリンクを張る」でした。 簡単に言えば見かけ上のフォルダを(ファイルでも本当は良いんですが)作成して、そこにアクセスがあったらリンクを張った場所が実際はアクセスされるってやつです。 今回ならhttp://ドメイン名/adminにアクセスがあったら実際は/home/ユーザー名/ドメイン名/laravel/publicを見に行ってくれるというのを定義します。 あえて言えばどこでもドア?(違う? これも細かくは記事を探して見てください。 まずはSSHでレンタルサーバーへ接続してください。 大抵はユーザー名のディレクトリへ接続されるはずです。 /home/ユーザー名/ そこからpublic_htmlまで移動します。 /home/ユーザー名/ドメイン名/public_html/ この位置で今回の例で言えば /home/ユーザー名/ドメイン名/laravel/app/public にシンボリックリンクを張ってください。 例えばですが ln -s /home/ユーザー名/ドメイン名/laravel/app/public /admin って感じです。 public_html直下でコマンド入力すること、-sの前後、/adminの前にスペースがある事、に注意してください。 基本的に公開部分はこれでいけます(XSERVERでは確認済み。さくらインターネットも記事を見る限り同じなので大丈夫でしょう・・雑 で公開に関してはこれでOKです。 私はこの公開場所をどう設定していいのかよくわからずに数日費やしました・・・ 実はここまでが前置きです。 毎回サーバーへアップして確認するわけには行かないので実際はローカルで作業をしますよね。 ローカルってことはレンタルサーバーとは違って全部自分で環境を構築する必要があります。 その際のLaravelやVueで悩みそうなあれこれを少し書いてみたいのが今回の本題です。 Laravel+Vue 当たり前ですがここからはローカルです。 大げさですが、通常は先の例で行けば /home/ユーザー名/ドメイン名/laravel/の位置でphp artisan serveでlocalhost:8000が立ち上がりWEBブラウザへ入力することでプロジェクトを起動できます。 今回の場合は同じディレクトリ内でnpm run watchする事でVueの部分が修正されたりで保存すると自動でコンパイルされます。 でここまではみんな割とスムースに行くかと思います。 理解しておくこと Laravel+Vue初心者が理解する必要があるのは、Laravel+Vueの場合、最初にindex.blade.php(プロジェクト作成時のファイルをそのまま使ったのならwelcome.blade.php)が表示されます。 そしてその後のフロント側制御はVueに移り、Laravelはバックエンドに専念しますのでそれだけ覚えておけば良いかと。 Vueからaxiosなどでapiにアクセスに行く際にLaravelはがんばります。 それ以外の見えてる部分はすべてVueが担うという形がLaravel+Vueになります。 何が問題なのか? 新規で既存のファイル等を気にしないのならこの先は/resources/js/内にassetsフォルダでも作成して、画像を入れていけばVueのテンプレートからアクセスできるのでなんの問題もありません。 今回の記事は既存システムへLaravelをぶっこむのが目的です。 今回の話ですと実際は例えば管理画面だとするとECとかなら商品マスタ等で既存商品の写真とかがどこかのフォルダにごっそりあることでしょう。 管理画面ならそのファイルの読み出しはもちろん、それ以前にファイルの有無や、書き込み、削除とやりたいことがあるでしょう。 /home/ユーザー名/ドメイン名/public_html/img/item/0001.jpgの画像を読みたいとかあると思います。 ですがLaravel部分(API部分)はStorageの設定とかでローカルフォルダを設定できるので問題ないのですがVueの部分は基本的にはassets内だったりのフォルダにしかアクセスできません。 ですので強硬策として別でWEBサーバーを立ち上げでアクセスさせます。 難しい話ではないのですが、ただのVueCLIならapp.vueでローカル判断を書けば良いんですが、Laravel+Vueだと少し変わってしまうので、この場合はVueのルーターなどでローカル判断して、ローカルならその別で起動したサーバーをファイルの前につけるってのをやります。 /home/ユーザー名/ドメイン名/public_html/の位置でphp -S http://localhost:8081を実行。 これでpublic_htmlをルートとしたローカルのWEBサーバーが起動します(XAMPPでも良いと思うのでURL等を読み替えてください) 例としてローカルと判断した場合はVueのscriptのcreated等でhost:"http://localhost:8081を設定して、テンプレートで<img :src="host+'/img/item/0001.jpg'">と設定すれば無事にVueからサーバーの既存の画像を表示させられました。 この起動したサーバーはあくまでVueからの画像等ファイルアクセス用なのでこれ自体をブラウザで表示させる必要はありません。 ややこしいですが、あくまでブラウザに表示しているのはphp artisan serveで起動したLaravelのlocalhost:8000なので気をつけてください。 あとがき 正直、後半はLaravelはほぼ関係ありません。 どちらかといえばVue等のローカル開発の一番基本的な部分ですが、初心者の方はかなり躓く部分だと思います。 Vueの経験なしにLaravel+Vueとして入ってくるとこのローカル開発の基礎がわからず悩んでしまう方を相当見かけました。 ローカルでの動作、サーバーでの動作をそれぞれ別物だと理解するのに時間がかかるのだろうと前から思っていました。 (同じ画面内でアクセス先がいくつもあるわけですから、理解が難しいのはわかります) 文章がまとめられない人間なのであれですが参考になれば幸いです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【初心者奮闘録】ログイン機能をほんの少し使いこなす!(Laravel)

はじめに この記事は、独学開始から約3ヶ月の実務未経験者が作成したものです。 よって、スキルは非常に未熟なため、決して本記事の内容を鵜呑みにされないよう、ご注意ください。 (未熟な私が記事投稿を行なっている背景については、本文の最後にお伝えします。) 本日の課題 コントローラー内で、ログイン者・非ログイン者で使用できるページを任意で設定する方法について、解説いたします。 対象者 PHP及びLaravelの基礎学習を終え、アプリ開発を始められた方 ログイン機能のダウンロードは完了したが、実用方法がわからない方 環境 PHP 8.0.11 Laravel Framework 8.64.0 実装解説 ベースとなるコード 下記のコードは、app/Http/Controllersディレクトリにある、GiftController.phpです。 (GiftController.phpは私が任意で作成したファイルです。) app/Http/Controllers/GiftController.php <?php class GiftController extends Controller { これをベースに、条件に沿って追記していきます。 条件①;非ログイン者を寄せ付けないアプリにする app/Http/Controllers/GiftController.php <?php class GiftController extends Controller { public function __construct(){ $this->middleware("auth"); } construct関数の中身に注目してください。 $thisを用いて、'auth'ミドルウェアが呼び出されております。 これがGiftControllerクラス内に存在することにより、GiftControllerクラス内のメソッドを使用するページは、非ログイン者は閲覧ができません。 (ただし、GiftControllerクラス内のメソッドを使用していないページには、非ログイン者でもアクセスすることは可能です。) 条件②;非ログイン者にも優しいアプリを作る app/Http/Controllers/GiftController.php <?php class GiftController extends Controller { public function __construct(){ $this->middleware("auth")->except(["index","store"]); } 'auth'ミドルウェアの後ろに、exceptメソッドを追記します。 これの意味は、例外としてGiftController.php内の"index"メソッドと"store"メソッドを使用しているページのみ、非ログイン者でもアクセスを可能とします。 おまけ 上記で紹介している'auth'ミドルウェアは、一体どこから湧いて出てきたのでしょうか? あれは、app/Httpディレクトリ内のKernel.php内に存在します。 app/Http/Kernel.php protected $routeMiddleware = [ 'auth' => \App\Http\Middleware\Authenticate::class, 上記コードは、Kernel.php内の56行付近にあります。 しかし、この一行ではauthの働きについて読み解くことができません。 さらに、Authenticateクラスについて確認していきます。 app/Http/Middlesare/Authenticate.php class Authenticate extends Middleware { protected function redirectTo($request) { if (! $request->expectsJson()) { return route('login'); } } } 上記のコードを簡単に解説すると、非ログイン者がページにアクセスしようとした時、例外を除き、全てログインページ(≒route('login'))に飛ばすという内容です。 最後に 上記でもお伝えいたしましたが、私は独学開始から約3ヶ月の実務未経験者です。 そんな未熟な私が記事を投稿しようと決意した理由は、以下の通りです。 ・初学者の記事が多く出回るほどに、プログラミングの学習を検討している方の背中を押せると考えたから(私自身、学習を開始するまでに初学者の記事を読み漁っておりました) ・周りに同じ境遇の仲間がいない、孤独な初学者さんの競争心を掻き立てられるのではと考えたから(学習効率を上げるためにはライバルの存在は重要) ・あるいはこのような稚拙な記事を読んだ初学者さんが「自分のレベルはこいつよりも上」と優越感を与えられるのではと考えたから(学習効率を上げるためには自信を持つことも重要) プロのエンジニア同様、初学者にもそれなりの努めがあると、私は思います。 今後も、下手くそながらも【初学者ページ】を上げ続けて参ります。 最後まで読んでいただき、誠にありがとうございました。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS-MFA認証のアカウントでAws\S3\S3Clientを利用するには

MFA認証が必要なAWSアカウントに対してWEB用SDKのS3Clientでアクセスする方法です。 AWSリソース間でのアクセスはRoleでの権限設定が推奨されていますが、例えばローカル開発環境からテストでS3にアクセスするとき、AWS_SESSION_TOKENの設定が必要になります。 対策はaws_session_tokenを配列に指定してオブジェクトを生成するだけです。 $s3 = new S3Client([ 'aws_access_key' => env('AWS_ACCESS_KEY'), 'aws_secret_key' => env('AWS_SECRET_ACCESS_KEY'), 'aws_session_token' => env('AWS_SESSION_TOKEN'), 'region' => env('AWS_DEFAULT_REGION'), 'version' => '2006-03-01' ]); session tokenの取得はcliから。 https://aws.amazon.com/jp/premiumsupport/knowledge-center/authenticate-mfa-cli/
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravelアプリケーション理解⑤(サービスプロバイダ)

本記事ではLaravelのアプリケーションを理解し、より良い設計・アーキテクチャを構築できるように学習したことを簡潔にまとめています。 目次 1.Laravelのアーキテクチャ 2.アプリケーションのアーキテクチャ 3.HTTPリクエストとレスポンス 4.データベース 5.認証と許可 6.イベントとキューによる処理の分離 7.コンソールアプリケーション 8.テスト 9.エラーハンドリングとログの活用 10.テスト駆動開発の実践 1.Laravelのアーキテクチャ 1-5. サービスプロバイダ サービスプロバイダとは、サービスコンテナへのバインド処理を行う機能であり、ビジネスロジックが実行される前にサービスプロバイダのメソッドが呼ばれる。 サービスプロバイダは、フレームワークやアプリケーションに含まれるサービス(機能)の初期化処理を行う目的で用意されいるである。 サービスプロバイダの主な役割 1.サービスコンテナへのバインド 2.イベントリスナーやミドルウェア。ルーティングの登録 3.外部コンポーネントを組み込む 下記に、サービスプロバイダの定義場所であるconfig\app.phpを示す。 'providers' => [ Illuminate\Auth\AuthServiceProvider::class, Illuminate\Broadcasting\BroadcastServiceProvider::class, Illuminate\Bus\BusServiceProvider::class, --[略]-- App\Providers\AppServiceProvider::class, App\Providers\AuthServiceProvider::class, App\Providers\EventServiceProvider::class, App\Providers\RouteServiceProvider::class, ], サービスプロバイダの基本的な動作 Laravelの処理処理で、まず各サービスプロバイダのregisterメソッドが実行される。その後、すべてのregisterメソッド処理が終わると、次にbootメソッドが呼び出される。 サービスプロバイダはIlluminate\Support\ServiceProviderクラスを継承しており、registerメソッドではほかの機能に依存していないインスタンスを取得している(必ず実装しなければならない)。 もし他の機能のインスタンスを取得して処理を実行する必要がある場合はbootメソッドを実行する(実装は任意) 下記にデータベース操作を行うDatabaseServiceProviderを示す。 namespace Illuminate\Database; use Faker\Factory as fakerFactory; use Faker\Generator as FakerGenerator; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\ServiceProvider; use Illuminate\Contracts\Queue\EntityResolver; use Illuminate\Database\Connectors\ConnectionFactory; use Illuminate\Database\Eloquent\QueueEntityResolver; use Illuminate\Database\Eloquent\Factory as EloquentFactory; class DatabaseServiceProvider extends ServiceProvier { public function boot() { Model::setConectionResolver($this->app['db']); Model::setEventDispatcher($this->app['events']); } public function register() { Model::clearBootedModels(); // ① $this->registerConnectionServices(); // ② $this->registerEloquentFactory(); // ③ $this->registerQueueableEntityResolver(); $this->registerDoctrineTypes(); } // ① protected function registerConnectionServices() { $this->app->singleton('db.factory', function ($app) { return new ConnectionFactory($app); }); $this->app->singleton('db', function ($app) { return new DatabaseManager($app, $app['db.factory']); }); $this->app->bind('db.connection', function ($app) { return $app['db']->connection(); }); $this->app->singleton('db.transactions', function ($app) { return new DatabaseTransactionsManager; }); } //② protected function registerEloquentFactory() { $this->app->singleton(FakerGenerator::class, function ($app, $parameters) { $locale = $parameters['locale'] ?? $app['config']->get('app.faker_locale', 'en_US'); if(! isset(static::$fakers[$locale])) { static::$fakers[$locale] = FakerFactory::create($locale); } static::$fakers[$locale]->unique(true); return statig::$fakers[$locale]; }); } //③ protected function registerQueueableEntityResolver() { $this->app->singleton(EntityResolver::class, function() { return new QueueEntityResolver; }); } } <コード解説> 上記のコード例のregisterメソッドでは、①registerConnectionServicesと②registerEloquentFactoryと③registerQueueableEntityResolverの3メソッドに分けて、バインド処理を定義している。 ①registerConnectionServicesメソッドでは、 「db.factory」の名前で、Iluminate\Database\ConnectionFactoryのインスタンスを、 「db」の名前でIlluminate\Database\DatabaseManagerのインスタンスをどちらもシングルトンでバインドしている。 また、「db.connection」の名前でDatabaseManegerから取得する\Illuminate\Database\Connectionのインスタンスを取得し、バインドしている。 「db.transaction」の名前でIlluminate\Database\DatabaseTransactionsManagerのインスタンスをシングルトンバインドしている。 ②registerConnectionServicesメソッドは、「FackerGenerator::class」をFakerFactory::createメソッドの戻り値をシングルトンでバインドしている。 ③registerQueueableEntityResolverメソッドでは、Illuminate\Database\Eloquent\QueueEntityResolverクラスのインスタンスをシングルトンでバインドしている。 DatabaseServiceProviderクラスのスーパークラスであるServiceProviderクラスは、プロパティでサービスコンテナのインスタンスを持っているため、$this->appの形でbind()やsingleton()を呼び出さている。 DeferrableProviderインターフェースの遅延実行 サービスプロバイダのregisterメソッドはアプリケーション起動時に実行される仕組みだが、クラスにIlluminate\Contracts\Support\DeferrableProviderインターフェースを実装すると、実行を遅らせることができる。 この場合、registerメソッドの実行タイミングを指定する必要があるため、providesメソッドまたはwhenメソッドで指定する必要がある。 providesメソッドはサービスコンテナで解決する文字列を指定し、文字列の解決をサービスコンテナに依頼したタイミングで、サービスプロバイダのregisterメソッドが呼ばれ、解決が行われる。 whenメソッドはイベントを指定し、対象イベント名を配列で指定するとリスナーが党則され、その中でサービスプロバイダのregisterメソッドが実行される。 providesメソッドもwhenメソッドも、サービスコンテナでの解決やイベントの発行がアプリケーション内で実行さえっるまでインスタンス登録は行われない 下記に遅延実行の例として、キャッシュ操作を行うIlluminate\Cache\CacheServiceProviderのコードを示す。 <?php namespace Illuminate\Cache; use Illuminate\Support\ServiceProvider; class CacheServiceProvider extends ServiceProvider implements DeferrableProvider { public function register() { $this->app->singleton('cache', fuction ($app) { return new CacheManager($app); }); $this->app->singleton('cache.store', functin ($app) { return new $app['cache']->driver(); }); $this->app->singleton('cache.psr6', function ($app) { return new Psr16Adapter($app['cache.store']); }); --[略]-- } public function providers() { return [ 'cache', 'cache.store', 'cache.psr6', 'memcached.connector', 'cache.dynamodb.client', RateLimiter::class, ]; } } <コード解説> 上記のコードでは、providesメソッドで[cache][cache.store][cache.pst6][memcached.connector][cache.dynamodb.client]およびRateLimiterクラスを要素とする配列を返す。このため、ビジネスロジックやコントローラのDIなどで[cache]などのクラス名をサービスコンテナで解決する際に、registerメソッドが実行されロジック側にインスタンスが返される。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

laravel-mix

やること ①npm install をしてから ②npm run dev を実行する ①が失敗していると②もエラーになるので注意 うまくいったやり方 nvm install --lts nvm use --lts npm install laravel-mix --save-dev --no-bin-links mkdir my-app && cd my-app npm init -y npm install laravel-mix --save-dev cp node_modules/laravel-mix/setup/webpack.mix.js ./ ▼うまくいかなかったとき node_moduleを全部削除する! rm -rf node_modules キャッシュが悪さしてるかもしれへんから、削除しておく! npm cache clear --force node_modules を全部インストールし直す。 npm install
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む