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

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

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

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

Q&A

解決済

2回答

1316閲覧

Laravelのモデルファイル内の関数はいつ実行されている?

ChickBeans

総合スコア1

Laravel

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

0グッド

0クリップ

投稿2020/09/24 01:19

編集2020/09/25 01:51

###初歩的な質問:Laravelのモデルファイル内の関数はいつ実行されている?

現在Laravelチュートリアルを行っていて
モデルファイルでアクセサを作成する関数を作成しました。

以下のコードがそれです。

関数は定義しただけじゃ実行されず、呼び出すことで初めて実行され戻り値を取得できるという認識なのですが
このモデルファイルで定義した関数は、他のどのファイル(blade.php, web.php)でも呼び出されていません。
しかし、blade.php内でstatus_labelやstatus_classを利用できることから呼び出してないのにどうして?という疑問が浮かび
モデルファイル内の関数について優しく教えていただきたいです。

私の認識
・モデルファイル内の関数は自動で実行される
・コントローラーファイル内の関数はweb.phpで呼び出しされ初めて実行される

models

php

1<?php 2 3namespace App\Models; 4 5use Carbon\Carbon; 6use Illuminate\Database\Eloquent\Factories\HasFactory; 7use Illuminate\Database\Eloquent\Model; 8 9class Task extends Model 10{ 11 /** 12 * 状態定義 13 */ 14 15 const STATUS = [ 16 1 => ['label' => '未着手', 'class' => 'label-danger'], 17 2 => ['label' => '着手中', 'class' => 'label-info'], 18 3 => ['label' => '完了', 'class' => ''], 19 ]; 20 21 /** 22 * 状態のラベル 23 * @return string 24 */ 25 public function getStatusLabelAttribute() 26 { 27 // 状態値 該当のstatusカラムの値を取得 28 $status = $this->attributes['status']; 29 30 // 定義されていない場合空文字を返す 31 if (!isset(self::STATUS[$status])) { 32 return ''; 33 } 34 35 return self::STATUS[$status]['label']; 36 } 37 38 /** 39 * 状態を表すHTMLクラス 40 * @return string 41 */ 42 public function getStatusClassAttribute() 43 { 44 // 状態値 45 $status = $this->attributes['status']; 46 47 // 定義されていない場合空文字を返す 48 if (!isset(self::STATUS[$status])) { 49 return ''; 50 } 51 52 return self::STATUS[$status]['class']; 53 } 54 55 /** 56 * 整形した期限日 57 * @return string 58 */ 59 60 public function getFormattedDueDateAttribute() 61 { 62 return Carbon::createFromFormat('Y-m-d', $this->attributes['due_date'])->format('Y/m/d'); 63 } 64 65 use HasFactory; 66} 67

blade

php

1<!-- views/tasks/index.blade.php --> 2 3@extends('layout') 4 5@section('content') 6<div class="container"> 7 <div class="row"> 8 <div class="col col-md-4"> 9 <nav class="panel panel-default"> 10 <div class="panel-heading">フォルダ</div> 11 <div class="panel-body"> 12 <a href="{{ route('folders.create') }}" class="btn btn-default btn-block"> 13 フォルダを追加する 14 </a> 15 </div> 16 <div class="list-group"> 17 @foreach($folders as $folder) 18 <a href="{{ route('tasks.index', ['id' => $folder->id]) }}" class="list-group-item {{ $current_folder_id === $folder->id ? 'active' : '' }}"> 19 {{ $folder->title }} 20 </a> 21 @endforeach 22 </div> 23 </nav> 24 </div> 25 <div class="column col-md-8"> 26 <div class="panel panel-default"> 27 <div class="panel-heading">タスク</div> 28 <div class="panel-body"> 29 <div class="text-right"> 30 <a href="{{ route('tasks.create', ['id' => $current_folder_id]) }}" class="btn btn-default btn-block"> 31 タスクを追加する 32 </a> 33 </div> 34 </div> 35 <table class="table"> 36 <thead> 37 <tr> 38 <th>タイトル</th> 39 <th>状態</th> 40 <th>期限</th> 41 <th></th> 42 </tr> 43 </thead> 44 <tbody> 45 @foreach($tasks as $task) 46 <tr> 47 <td>{{ $task->title }}</td> 48 <td> 49 <span class="label {{ $task->status_class }}">{{ $task->status_label }}</span> 50 </td> 51 <td>{{ $task->formatted_due_date }}</td> 52 <td><a href="{{ route('tasks.edit', ['id' => $task->folder_id, 'task_id' => $task->id]) }}">編集</a></td> 53 </tr> 54 @endforeach 55 </tbody> 56 </table> 57 </div> 58 </div> 59 </div> 60</div> 61@endsection

php

1<?php 2 3namespace App\Http\Controllers; 4 5use App\Http\Requests\CreateTask; 6use App\Http\Requests\EditTask; 7use App\Models\Folder; 8use App\Models\Task; 9use Illuminate\Http\Request; 10 11class TaskController extends Controller 12{ 13 public function index(int $id) 14 { 15 // Folderテーブルから全データを取得 16 $folders = Folder::all(); 17 18 // Folderテーブルから選ばれたフォルダを取得する 19 $current_folder = Folder::find($id); 20 21 // 選ばれたフォルダに紐づくタスクを取得する 22 // $tasks = Task::where('folder_id', $current_folder->id)->get(); 23 $tasks = $current_folder->tasks()->get(); 24 25 return view('tasks/index', [ 26 'folders' => $folders, 27 'current_folder_id' => $current_folder->id, 28 'tasks' => $tasks, 29 ]); 30 } 31 32 /** 33 * GET /folders/{id}/tasks/create 34 */ 35 public function showCreateForm(int $id) 36 { 37 return view('tasks/create', [ 38 'folder_id' => $id, 39 ]); 40 } 41 42 public function create(int $id, CreateTask $request) 43 { 44 $current_folder = Folder::find($id); 45 46 $task = new Task(); 47 $task->title = $request->title; 48 $task->due_date = $request->due_date; 49 50 $current_folder->tasks()->save($task); 51 52 return redirect()->route('tasks.index', [ 53 'id' => $current_folder->id, 54 ]); 55 } 56 57 /** 58 * GET /folders/{id}/tasks/{task_id}/edit 59 */ 60 public function showEditForm(int $id, int $task_id) 61 { 62 $task = Task::find($task_id); 63 64 return view('tasks/edit', [ 65 'task' => $task, 66 ]); 67 } 68 69 public function edit(int $id, int $task_id, EditTask $request) 70 { 71 // 1 過去に登録されている情報を取得 72 $task = Task::find($task_id); 73 74 // 2 75 $task->title = $request->title; 76 $task->status = $request->status; 77 $task->due_date = $request->due_date; 78 $task->save(); 79 80 // 3 81 return redirect()->route('tasks.index', [ 82 'id' => $task->folder_id, 83 ]); 84 } 85} 86

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

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

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

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

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

phper.k

2020/09/24 02:19

Blade内でどの様な記述をしているのかを提示してください
ChickBeans

2020/09/24 03:06

回答ありがとうございます! bladeを追加いたしました!
phper.k

2020/09/24 04:57

質問内容と矛盾してますね。 Controller にモデルを呼び出すコード書いてません?
ChickBeans

2020/09/25 01:49

回答ありがとうございます! 私の理解度が低すぎてなにが矛盾してるのかさえわからない状況です、、、。 コントローラーでモデルを呼び出すコードは書いているんですけど モデル内の関数は使用していません。 コントローラーのソースも追記いたしました。
phper.k

2020/09/25 02:01

とりあえず、先につけてある解答の手順は試したんでしょうか?
ChickBeans

2020/09/25 08:41

試したのですが、どこを見ればよいかわからず断念しました。 何度も質問をして申し訳ないですが 原則、モデルに関数を記述するだけでは実行されないという認識で良いのでしょうか?
guest

回答2

0

php

1 2 public function getStatusLabelAttribute() 3 { 4 var_dump(debug_backtrace()); // debug_backtrace 5 6 // 状態値 該当のstatusカラムの値を取得 7 $status = $this->attributes['status']; 8 9 // 定義されていない場合空文字を返す 10 if (!isset(self::STATUS[$status])) { 11 return ''; 12 } 13 14 return self::STATUS[$status]['label']; 15 }

こんなふうに、debug_backtrace を仕込んでおけば、関数の実行順が表示されるので、それでわかると思います。


追記を受けて

原則、モデルに関数を記述するだけでは実行されないという認識で良いのでしょうか?

当然です。Laravelに限らず、プログラミング言語において共通です。

関数は呼び出さない限り実行されません。

blade.php内でstatus_labelやstatus_classを利用できることから呼び出してないのにどうして?

「呼び出していない」という認識が誤りで、「呼び出している」から値が取れています。

投稿2020/09/24 02:05

編集2020/09/25 08:46
phper.k

総合スコア3923

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

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

0

ベストアンサー

関数は定義しただけじゃ実行されず、呼び出すことで初めて実行され戻り値を取得できるという認識なのですが

このモデルファイルで定義した関数は、他のどのファイル(blade.php, web.php)でも呼び出されていません。

PHPのインスタンスには存在しないプロパティにアクセスした場合に、別のメソッドにフォールバックするマジックメソッド__getが用意されています。

アクセサで定義したメソッドはこの__get経由でLaravelの内部で呼び出されています。
そのため、いつ発火したかという問いへの返答は存在しないプロパティにアクセスした時かつ対応する命名規則のメソッドが定義されている時です。

投稿2020/09/25 09:35

mikkame

総合スコア5036

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問