20210415のlaravelに関する記事は5件です。

初学者がLaravelを学ぶ3(コントローラー)

コントローラーについて webページの基本的な処理はコントローラを使って行うのが基本です。 またMVCアーキテクチャの基本となるものです。 MVCとコントローラ ルーティングはアクセスしたアドレスをもとに処理を割り振る役割でした。ただそれだけではなく、具体的に実行するべき処理は別に用意されていて、それを特定アドレスに割り振って呼び出すための処理です。 MVCとはモデル、ビュー、コントローラの頭文字をとったものです。 モデルはデータ処理全般を担当します。具体的にはデータベースに関する処理全般を司ると言って良いと思います。 ビューは画面表示を担当します。表示に使うテンプレートなどがこれに相当します。 コントローラは全体の制御を担当します。必要に応じてモデルからデータを取得したりビューを利用して画面表示を作成したりします。 コントローラの作成 作成中のアプリのフォルダディレクトリで以下のコマンドを実行することで作成できます。 php artisan make:controller HelloController これによってHelloControllerが作成できます。 ちなみにHelloの部分の名前を変えることで違うコントローラ名で作成することができます。 下記はHelloController.phpの中身です。 順番に内容を見ていきます。 <?php namespace App\Http\Controllers; use Illuminate\Http\Request; class HelloController extends Controller { // } controllersと名前空間 コントローラはクラスとして作成されます。このクラスはApp\Http\Controllersという名前空間に配置されます。 名前空間とはクラスを階層的に整理するための仕組みです。フォルダを使って階層的にファイルを管理するのと同じだと思っておけばいいと思います。 一行目のnamespace App\Http\Controllers; は名前空間を指定しています。 useによるインポート 次に記述されているのはuse文です。以下のように記述されています。 use Illuminate\Http\Request; ここではIlluminate\Httpパッケージ内に用意されているRequestを使える状態にしています。 まだこの段階ではRequestは不要ですがこれから多用することとなるクラスのためデフォルトでuse文が追加されています。 クラスの定義 続いてクラスが提起されています。HelloControllerは以下のように定義されています。 class HelloController extends Controller コントローラクラスはこのようにControllerというクラスを継承して作成します。 アクションを追加する コントローラに用意される処理はアクションと呼ばれる。これはメソッドの形で用意されます。 今回は以下のようにindexメソッドを追加してみます。 ここではindexのように引数を持たないメソッドとして用意されています。(場合によっては引数を用意することもあります。) アクションメソッドはreturnを使ってHTMLのコードを返しています。結果、returnした内容がウェブブラウザに返され表示されることになります。 <?php namespace App\Http\Controllers; use Illuminate\Http\Request; class HelloController extends Controller { public function index() { return <<<EOF <html> <head> <title>Hello/Index</title> <style> body {font-size:16pt; color:#999; } h1 { font-size:100pt; text-align:right; color:#eee; margin:-40px 0px -50px 0px; } </style> </head> <body> <h1>Index</h1> <p>これは、Helloコントローラのindexアクションです。</p> </body> </html> EOF; } } ただこれだけでは表示はできません。ルーティングを変更する必要があります。 web.phpを開き先程の記述を削除しルーティングを変更していきます。 Route::get('hello', 'HelloController@index'); 第二引数には関数ではなくコントローラ名@アクション名が記述されています。 これにより第一引数のアドレスにアクセスしようとすると第二引数に指定されたアクションが実行されるようになります。 コントローラを使ったルートパラメータの利用 ルートパラメータ(アクセスする際にパラメータとして値を渡すことができる)を使用する場合は以下のように編集します。 class HelloController extends Controller { public function index($id='noname', $pass='unknown') { return <<<EOF <html> <head> <title>Hello/Index</title> <style> body {font-size:16pt; color:#999; } h1 { font-size:100pt; text-align:right; color:#eee; margin:-40px 0px -50px 0px; } </style> </head> <body> <h1>Index</h1> <p>これは、Helloコントローラのindexアクションです。</p> <ul> <li>ID: {$id}</li> <li>PASS: {$pass}</li> </ul> </body> </html> EOF; } } ルーティングも以下のように編集していきます。 Route::get('hello/{id?}/{pass?}', 'HelloController@index'); これによって/hello/taro/yamadaというようにhelloの後に二つのパラメータをつけてアクセスするとそれらのパラメータが画面に表示されます。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ローカル環境にDockerを使用しLaravelをgitからclone後、php artisan migrateのエラーでハマった件

どうも、初心者プログラマーTKOです。 今回は新しいdocker環境を試そうと今まで作っていたLaravelアプリをgitからcloneした際に、php artisan migrateのエラーではまった件について話させていただきます。 新規Laravelプロジェクト 初期設定 リポジトリをクローン後 $ docker-compose up -d --build $ docker-compose exec app bash # composer install これで設定したローカルのポート番号にアクセスするとLaravelの画面が表示されます。 ここから mysqlのDockerfileで設定した MYSQL_DATABASE=laravel_local MYSQL_USER=phper MYSQL_PASSWORD=*** MYSQL_ROOT_PASSWORD=*** の値を参考にホスト側の.envファイルを設定します。 DB_PORT=3306 DB_DATABASE=laravel_local DB_USERNAME=phper DB_PASSWORD=*** その後 # cp .env.example .env # php artisan key:generate 後はマイグレーションで終わり と思ったのですが、、、 Illuminate\Database\QueryException : SQLSTATE[HY000] [2002] Connection refused (SQL: select * from information_schema.tables where table_schema = laravel and table_name = migrations and table_type = 'BASE TABLE') at /work/vendor/laravel/framework/src/Illuminate/Database/Connection.php:669 665| // If an exception occurs when attempting to run a query, we'll format the error 666| // message to include the bindings with SQL, which will make this exception a 667| // lot more helpful to the developer instead of just the database's errors. 668| catch (Exception $e) { > 669| throw new QueryException( 670| $query, $this->prepareBindings($bindings), $e 671| ); 672| } 673| Exception trace: 1 Doctrine\DBAL\Driver\PDO\Exception::("SQLSTATE[HY000] [2002] Connection refused") /work/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDO/Exception.php:18 2 Doctrine\DBAL\Driver\PDO\Exception::new(Object(PDOException)) /work/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php:42 Please use the argument -v to see more details. 出ました!予想外のエラー、、、 とりあえず何らかのキャッシュが残っているんだろうなと思い # php artisan config:clear # composer dump-autoload を試してみましたが解決せず DBが登録されていないのかと思いDB内に入るも $ docker-compose exec db bash # mysql -u phper -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 8 Server version: 8.0.22 MySQL Community Server - GPL Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | laravel_local | +--------------------+ 2 rows in set (0.02 sec) ちゃんと登録されている、、、 調べたところ .envの DB_HOST=127.0.0.1 が DB_HOST=db だそうです! なるほど、dockerはコンテナ同士で通信してるからローカルのIPアドレスを指定しても意味ないってことですね。 以後気をつけます。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Laravel】fakerのtextでエラーになった

実行環境 PHP 7.4 Laravel 6.20.0 エラー内容 Faker使ってダミーデータたくさん作ってやるぞ! と思いまして、 <?php /** @var \Illuminate\Database\Eloquent\Factory $factory */ use App\Model\Tag; use Faker\Generator as Faker; $factory->define(Tag::class, function (Faker $faker) { return [ 'title' => $faker->name, 'slug' => $faker->word, 'description' => $faker->text, ]; }); こういったFactoryを用意し、php artisan db:seedを実行したところ ErrorException : implode(): Passing glue string after array is deprecated. Swap the parameters と、$faker->textのところで怒られてしまいました。 原因 php7.4になり、implodeの書き方が変更されたのが原因のようです。 【参考記事】 php7.4からimplode関数の引数順序の推奨について implode(',', ['a','b','c']); とすると、 a,b,cという文字列を作ってくれるのですが、今までは implode(['a','b','c'],','); のように逆でも問題なかったそうです。それが、Fakerのパッケージ内で使われてたということですね。 改善方法 Fakerをアップデートしてみました。 $ composer update fzaninotto/faker これでOK!と思いきや... Package fzaninotto/faker is abandoned, you should avoid using it. No replacement was suggested. と、そもそもfzaninotto/fakerがabandonedだと注意されてしまいました。 仕方ないのでこちらに切り替えます。 $ composer remove vendor/fzaninotto/faker // 既存のfakerパッケージを削除 $ composer require fakerphp/faker // 新パッケージインストール これで無事初期値を実装することができました。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

hyn/multi-tenant使用中にDBのタイムゾーンを変更したらLaravelからテナントのDBに接続出来なくなった件

環境 Laravel MySQL(AURORA) hyn/multi-tenant 結論 テナントDBアカウントのパスワード生成にcreated_atを使用しているため、 値が変更されるとテナントDBアカウントでテナントDBに接続出来なくなる。 経緯 AURORAのパラメータグループで time_zone を変更したらテナントDBアカウントでテナントDBに接続出来なくなった。 Access denied 調べたらテナントDBのパスワード生成には websites.created_atを使用しているようだ。 vendor\hyn\multi-tenant\src\Generators\Database\DefaultPasswordGenerator.php public function generate(Website $website) : string { $key = $this->app['config']->get('tenancy.key'); // Backward compatibility if ($key === null) { return md5(sprintf( '%s.%d', $this->app['config']->get('app.key'), $website->id )); } return md5(sprintf( '%d.%s.%s.%s', $website->id, $website->uuid, $website->created_at, $key )); } うちのwebsites.created_atはtimestamp型なのでDBのタイムゾーンによってよしなに変換される日時は変わってしまう。 今回の場合は9時間遅い時間を返すようになってしまった。 なのでcreated_atに9時間早い日時を設定したところ、DBに接続出来るようになった。 update websites set created_at = '2021-04-14 11:24:12'; 以上
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravelでのデバッグ方法4パターンまとめ

Laravelのデバッグ方法って何かいっぱいあるよね... なぜこの記事を書こうと思ったか 少しでも開発を効率化する為です。 僕自身のメモ用っていうのもあるんですが、パターンに応じてどのデバッグ方法を使うのがベストかというのが分からないんですよね? その時にどんな選択肢があるかも知っておきたかったので、記事にまとめようと思いました! 間違っているもの、他にもこんな方法があるよ!とかあれば是非教えて頂ければ助かります 環境 ターミナル $ php artisan --version Laravel Framework 5.5.50 $ php -v PHP 7.1.33 (cli) (built: Oct 31 2019 17:37:57) ( NTS ) Copyright (c) 1997-2018 The PHP Group Zend Engine v3.1.0, Copyright (c) 1998-2018 Zend Technologies $ composer -v Composer version 2.0.12 2021-04-01 10:14:59 1. Logファサード Logファサードを使用して、ログに変数の値などを出力するやり方。 簡単でお手軽です。 使用したいControllerなどで、下記をUseに指定します(Blade内でも使えます) use Illuminate\Support\Facades\Log; あとは、Logファサードを使用し // 変数 Log::debug($test); // 配列 Log::debug(print_r($arr, true)); // オブジェクト Log::debug(print_r($object, true)); のように出力します。 useを使用しない場合は、下記のように「\」を先頭につければ指定しなくても出力できます! \Log::debug($test); 出力する際のメソッド(ログレベル)は下記の通り。 Log::emergency($message); Log::alert($message); Log::critical($message); Log::error($message); Log::warning($message); Log::notice($message); Log::info($message); Log::debug($message); 上から順にレベル(緊急度)が高く、下記のように設定ファイル(config/app.php)にレベルを記述しておくと、そのレベルより上のログしか出力されなくなるとのこと。 config/app.php 'log_level' => env('APP_LOG_LEVEL', 'debug'), 以下、公式より引用。 Laravelはデフォルトで全ログレベルをストレージに書き込みます。 しかし、実働環境ではapp.php設定ファイルのlog_levelオプションへ、ログすべき最低の重大さレベルを指定したいことでしょう。 このオプションを一度設定すると、Laravelは指定された重大さ以上の全レベルをログします。 たとえば、log_levelにerrorを設定すると、error、critical、alert、emergencyメッセージがログされます。 開発環境だと、debugだけ使用してログを出力して本番環境はそれ以外で出力するみたいな使い方かな 出力場所は、デフォルトでstorage/log/laravel.logに出力されます。 もし日次でファイルを分けたいなら、config/app.phpに下記のように設定すれば分かれます config/app.php 'log' => 'daily' 2. Tinker Laravelに標準で組み込まれているようなので、特に準備せずに使えるようです! (名前ディズニーのキャラみたいでカワイイ?) ターミナルで、下記コマンドを叩きます。 ターミナル $ php artisan tinker Laravel Framework 5.5.50 bash-4.2# php artisan tinker Psy Shell v0.9.12 (PHP 7.1.33 — cli) by Justin Hileman >>> すると上記のように入力待ちの状態になるので、あとはphpのコマンドを入力すれば実行結果が返ってきます。 ターミナル >>> array ('a' => '1', 'b' => '2', 'c' => '3'); => [ "a" => "1", "b" => "2", "c" => "3", ] 変数に値を格納して、操作することも可能。 ターミナル >>> $hoge = new Carbon\Carbon('now'); => Carbon\Carbon @1618184500 {#4459 date: 2021-04-12 08:41:40.625537 Asia/Tokyo (+09:00), } >>> $hoge->dayOfWeek => 1 >>> $hoge->addDay(); => Carbon\Carbon @1618270900 {#4459 date: 2021-04-13 08:41:40.625537 Asia/Tokyo (+09:00), } 終了するには、 exit ターミナル >>> exit Exit: Goodbye ちょっとphp標準のメソッドの動きを確認したい オブジェクトの中身を確認したい と言った「画面を動かすまでもないけど実行結果を見たい」という場合には有効に使えそう。 個人的には、Carbonの動きとか把握するのにかなりありがたい存在? プロジェクト内で、public static functionを定義していればそれも使えるようです。 ※追記 public static以外のメソッドもNewすれば使えるようです。 コメントで教えて頂いた @nunulk さんありがとうございました >>> $hoge = new \App\Hoge() => App\Hoge {#1000} >>> $hoge->piyo() => "piyo" >> 3. Debugbar こちらはめちゃくちゃ有名なので、導入している方も多いかと思います。 準備 下記コマンドでインストール ターミナル composer require barryvdh/laravel-debugbar .envの下記の値をtrueに設定します(本番環境ではfalseに戻すのを忘れずに) .env DEBUGBAR_ENABLED=true 忘れないように、envの値を反映させます ※追記 このタイミングで私は php artisan config:cacheしていたのですが、開発環境でconfigをキャッシュするのは推奨されないとのことなので、cacheしていない場合は特になにもしなくてOKです! 以下、公式より引用。 一般的には、本番環境へのデプロイ作業の一環として、php artisan config:cacheコマンドを実行すべきでしょう。 アプリケーションの開発期間中は設定が頻繁に変更されることも多いので、ローカルでの開発中にこのコマンドを実行してはいけません。 Note: 開発過程の一環としてconfig:cacheコマンド実行を採用する場合は、必ずenv関数を設定ファイルの中だけで使用してください。 設定ファイルがキャッシュされると、.envファイルはロードされなくなり、env関数の呼び出しは全てnullを返します。 ・config:cacheすると、envファイルはロードされなくなる ・env関数を設定ファイル以外で使っている場合は、nullになってしまう ってことですね。 既にcacheしてしまっている場合は、下記コマンドでクリアします。 ターミナル php artisan config:clear コメントで教えて頂いた @kaya754 さん、ありがとうございました! 準備は以上です。 使い方 ブラウザにアクセスすると、ページの下部にデバッグバーが表示されます。 それぞれタブごとに様々な情報が表示されますが、よく使うタブは下記の通りです。 タブ 内容 Messages 出力したログの確認 Views レンダリングされたViewの一覧 Route ルーティング関係の一覧 Query 裏で走っているSQL Session Sessionの一覧と値 Request Requestの一覧と値 Messagesには、デバッグバーの下記メソッドでログを出力できます。 \Debugbar::emergency('emergency'); \Debugbar::alert('alert'); \Debugbar::critical('critical'); \Debugbar::error('error'); \Debugbar::warning('warning'); \Debugbar::notice('notice'); \Debugbar::info('info'); \Debugbar::debug('debug'); \Debugbar::log('log'); 出力してみるとこんな感じです。 一番上の行にあるように、Logファサードで出力したログもこちらで見れるみたいです? いちいちlaravel.logを見るよりこっちの方が簡単ですね。 Viewsは、実際にシステムを動かして、このページを編集したいという時にViewを特定するのに便利かな! Routeは、ルーティングの確認に便利。 web.phpを見ても良いんですが、大きなシステムだとコードを多すぎて1ページでは情報が把握しきれない事があるんですよね? QueryではSQLが把握できます。 Laravelで開発している時ってSQLがどれだけ走ってるかとか意識しづらいと思うんですが、確認してあげる事でN+1問題等にも気付けるんじゃないかと思います。 SessionやRequestは、コード上だけでは分かりづらい中身が見れるのでめっちゃありがたい。 モデルを返した時に、コレクションで返ってきてる事が分かりますね。 これ以外にもタブは幾つかありますが、僕自身まだあまり使いこなせていないので、もっとこんな事もできるとかあれば教えてほしいです 4.ヘルパーメソッド dump()もしくはdd()を使って、値をブラウザ上に出力する方法です。 2つの違いは、 ・dump()は、処理が止まらずに出力するだけ ・dd()は、記述時点で処理が止まる って感じらしい。 使い方はめちゃ簡単で、引数に出力したい値を渡すだけ。 $test = new Carbon\Carbon('now'); dump($test); この状態でブラウザにアクセスすると、上部にバーが表示されてログが出力されます。 ページを見ながら値を確認できるので、分かりやすいですね? View側でControllerから渡ってきた値を確認したいという事もあるので、Viewで書けないのかな?と思いましたが、Viewでも下記にように書けば使えるようです! <div id="wrapper"> <div class="head-information head-margin-top"> <h2>テストページです</h2> @php $test = new Carbon\Carbon('now'); dump($test); @endphp </div> </div> ただし、Viewで書くと記述した場所に出力されるので、デザインが崩れる可能性はありますw 今度は、Contoller側にてdd()で出力してみます。 public function index() { $test = new Carbon('now'); dd($test); return view('page.mypage.dashboard.test'); } すると、ページが表示されずにログだけページに表示されるのがわかります。 dd()では書いた場所で処理が止まるので、上記のコードではreturn Viewが行なわれてないことが分かります。 View側でdd()を書くとどうなるか... <div id="wrapper"> <div class="head-information head-margin-top"> <h2>テストページです</h2> @php $test = new Carbon\Carbon('now'); dd($test); @endphp </div> <h1>さすがディオ!おれたちにできない事を平然とやってのけるッ そこにシビれる! あこがれるゥ!</h1> </div> 途中で読み込みが終わっているので、ジョジョの名言が出力されていないことが分かりますね( ・∀・)!! divタグも閉じられていない事になっているので、クラス名に対してCSSも適用されていない View側でdd()を使う事はあまりなさそうですが、Viewでエラーになっている箇所の手前で使うという使い方はできそうです。 個人的まとめ 基本は、dump()でログ出力 エラー箇所の手前で処理を止めたい場合は、dd() dump()だとViewのデザインが崩れて困るという場合は、debugbarにログ出力 タスクスケジューラ等、画面を必要としない処理はLogファサード LaravelやPHPのメソッド、自作モデルやメソッドの動きを確認したい場合はTinker 参考 laravel-debugbar Laravel 5.5 Artisanコンソール Laravel 5.5 パッケージ開発 Laravel 5.5 エラーとログ laravelデバッグバーの導入 Laravel 5.5 設定 終わりに 軽く調べた感じは他にもデバッグ方法はありそうでしたが、ひとまずこれだけ知っていれば大抵のパターンで困らないんじゃないかな〜と思う! もっと便利なやり方があれば、使いたい所存?
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む