質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

Q&A

1回答

125閲覧

Laravelの時間変更処理を一回だけ実行したい

landy77

総合スコア1614

Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

0グッド

0クリップ

投稿2024/04/22 23:05

実現したいこと

フロントはVue3で書いておりLaravelは基本APIとしての呼び出しで使用しています。

テスト用データを作成するに当たりテーブルの関連が多いためシステム自体の日付を戻して正規の画面で入力するという話になりました。

調べてみてCarbonでsetTestNowを利用すると時間を固定できる事がわかり、同じインスタンス上ならCarbonの時刻が連動するようだという認識を持ちました。

ただコントローラが多いので全てのコントローラーにコードを書くのは現実的でないと思ったのでコントローラー前に実行しておきたいと考えたのが今回の主題です。

発生している問題・分からないこと

Middleware等のコントローラー以前の段階で実行しておこうと思ったのですがMiddlewareを作成して入れてみるとリクエスト全てにsetTestNowが走るからかわかりませんが429エラーが出てしまいなんどやっても改善されません。
Groupとかではなくて全体の$middlewareに入れて試しました。

次にbootstrap/app.phpに入れてみようと思いました。
最後のreturn $appの手前に入れてみようと思いましたがそもそもLaravelが起動しませんでした。

次に全てAPIリクエスト時なので、もしかしてRoute/api.phpでいけるのか?と思いまして試したのですがコード自体は実行されるようですが認証周りに影響が出るのか、Authの動作がおかしくなるのか、ログイン処理後一旦認証されるのですがログイン後の画面に遷移した時点でログインしていないことになってしまいます。
毎API呼び出し時にsetTestNowが走るので不正扱いされてしまうのか?と思いましたが確認方法がわかりませんでしたので一旦保留しました。

次に全てのリクエストを受け付けているであろうpublic/index.phpの最後に入れてみる事をしてみました。
いれるなら$appが作成された後だろうと思い、index.phpの最後にsetTestNowを入れてみると実行自体はされて、その時点のログには指定した時間がセットされたのがわかりました。
ですが実際にAPI呼び出しされ、コントローラーで時間を確認するとそこまでの間で初期化されてしまうのか通常の時間に戻ってしまっていました。

該当のソースコード

Laravel

1//実際は上の方でファサード等のuseをしています 2if (Config::get('app.env') == "local") { 3 try { 4 Log::info(Auth::guard(LoginConsts::ADMIN)->check()); 5 Carbon::setTestNow("2024-4-1 00:00:00"); 6 Log::info(Carbon::now('Asia/Tokyo')->format('Y-m-d H:i:s')); 7 } catch (\Exception $ex) { 8 Log::error($ex->getMessage()); 9 Log::error($ex->getLine()); 10 } 11}

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

おそらくsetTestNowの想定がテスト時の為にこういう動作なのかと思いますが、そもそも発想がまずいのか、何かを勘違いしているのかヒントを頂けませんでしょうか?

よろしくお願いいたします。

補足

特になし

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hentaiman

2024/04/24 18:04

すでに指摘されている通り発想がまずいです。 「理想とするデータが入るから意味が無い」の指摘をされたとのことですが、その指摘も意味も分かりません。上司や先輩社員の意見であれば参考にしたいから作って例を見せてくれとでも言えばいいでしょう。同僚の意見であれば一緒に考えて欲しいと言って相談しながら解決するのが良いでしょう。
guest

回答1

0

setTestNowはテスト時に使うもの。
時間を固定したいならfactoryやseeder段階で固定する。

php

1use Illuminate\Support\Carbon; 2 3$user = User::factory()->create([ 4 'created_at' => Carbon::create(year: 2024, month: 4, day: 23, hour: 12, minute: 0, second: 0), 5 ]); 6 7dd($user->created_at->toDateTimeString()); 8// 2024-04-23 12:00:00

setTestNowはこれをいちいち書くのを省略するだけ。setTestNowを使うとしてもテストファイル単位。これ以上では影響が大きすぎる。

php

1namespace Tests\Feature; 2 3use App\Models\User; 4use Illuminate\Support\Carbon; 5use Tests\TestCase; 6 7class UserTest extends TestCase 8{ 9 protected function setUp(): void 10 { 11 parent::setUp(); 12 13 Carbon::setTestNow(Carbon::create(year: 2024, month: 4, day: 23, hour: 12, minute: 0, second: 0)); 14 } 15 16 protected function tearDown(): void 17 { 18 Carbon::setTestNow(null); 19 20 parent::tearDown(); 21 } 22 23 public function test_user(): void 24 { 25 $user = User::factory()->create(); 26 27 dd($user->created_at->toDateTimeString()); 28 // 2024-04-23 12:00:00

テスト以外でsetTestNowを使おうとしてる発想自体が完全に間違い。システムの時間を戻すなんて発想はもっと異常。こんな変なことしたらプロジェクトが壊れる。

ローカルのDBに固定時間でデータを作りたいならseederを使う。

質問とは関係ない部分のコードからでもLaravelどころかPHPの基礎も理解してない人ばかりなことが分かる。

php

1if (Config::get('app.env') == "local") { 2 3// PHP初歩レベルの修正 4if (Config::get('app.env') === 'local') { 5 6// Laravelでのベストな書き方 7if(app()->isLocal()) {

投稿2024/04/23 01:23

pcs

総合スコア363

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

landy77

2024/04/23 01:55

いや・・・ 最初にseederを使う発想なのは当然わかります。 ただそれだと絶対にこちらが理想とするデータが(データ自体が正確に作られている)出来上がってしまうので意味がないと言われています。 今回は集計類の為だったのですがそのシステム上で作成したデータでチェックしないと正確性を担保できないのでこの時間を戻す処置を提案されている次第です。 出来上がったデータを日付部分を手動で戻すのも否定されているので・・・ (こちらはテーブル複数が絡むデータだから否定されているのもあるのですが) ローカル判定・比較部分等、PHP初歩レベルで失礼しました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問