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

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

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

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

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

2回答

1023閲覧

年齢・性別・有効性ででアイコンを切り替えたい

crescens

総合スコア9

Laravel

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

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2020/11/09 01:29

編集2020/11/09 07:08

Laravelでアカウントの属性によって表示するアイコンを切り替えるプログラムを書きたいと考えています。
アカウントが有効・性別が男性・年齢が20~29歳…Aのアイコン
アカウントが無効・性別が男性・年齢が20~29歳…Bのアイコン
アカウントが有効・性別が女性・年齢が20~29歳…Cのアイコン
アカウントが無効・性別が女性・年齢が20~29歳…Dのアイコン etc
というように属性別でアイコンを切り替えたいのですが、
if文で記述するとネストが深くなりそうなので別のやりかたを探しているのですが、「アイコン 性別 年齢 PHP」等で検索しても情報がヒットしません。
どのような手法で実装するのが良いでしょうか? また、検索におすすめにキーワードがあれば教えてください。
よろしくお願い致します。

追記:現状のソースコードを掲載します。
今は年齢に関してはviewで成人か未成年かのみで分岐している状態です。
今後成人の分岐を20~29、30~39、40~49…と109歳まで増やすことになったので綺麗な書き方はないかと思い相談しました。

PHP

1@if ($member->sex == 0) //男性 2 @if ($member->age >= 20) 3 @if ($member->status = 1) //有効 4 <img src="{{ asset('/img/male/adult-active.svg') }}"> 5 @else 6 <img src="{{ asset('/img/male/adult-deactive.svg') }}"> 7 @endif 8 @else 9 @if ($member->status = 1) //有効 10 <img src="{{ asset('/img/male/young-active.svg') }}"> 11 @else 12 <img src="{{ asset('/img/male/young-deactive.svg') }}"> 13 @endif 14 @endif 15@else //女性 16 @if ($member->age >= 20) 17 @if ($member->status = 1) //有効 18 <img src="{{ asset('/img/female/adult-active.svg') }}"> 19 @else 20 <img src="{{ asset('/img/female/adult-deactive.svg') }}"> 21 @endif 22 @else 23 @if ($member->status = 1) //有効 24 <img src="{{ asset('/img/female/young-active.svg') }}"> 25 @else 26 <img src="{{ asset('/img/female/young-deactive.svg') }}"> 27 @endif 28 @endif 29@endif

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

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

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

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

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

phper.k

2020/11/09 03:17 編集

提示された条件をいずれも満たさない場合はどうするのか?
crescens

2020/11/09 03:46

コメントありがとうございます。満たさない場合はアイコンなしにします。
guest

回答2

0

ベストアンサー

モデルに処理を書くことで、view の記述は以下のように劇的に簡素になります。

View bladeでの記述

blade

1@foreach ($members as $member) 2 <img src="{{ asset($member->icon) }}"> 3@endforeach

DB定義

bash

1php artisan make:migration create_members_table

多少、プロパティの設定値など変更してある

  • 男性、女性、の設定値: 0 はPHPでは扱いにくいので、男性:1, 女性:2 とした
  • カラムから、age は取り除いた。birthday を持てば、誕生日のインクリメントの仕組みは不要だから。

php

1<?php 2 3use Illuminate\Database\Migrations\Migration; 4use Illuminate\Database\Schema\Blueprint; 5use Illuminate\Support\Facades\Schema; 6 7class CreateMembersTable extends Migration 8{ 9 /** 10 * Run the migrations. 11 * 12 * @return void 13 */ 14 public function up() 15 { 16 Schema::create('members', function (Blueprint $table) { 17 $table->bigIncrements('id'); 18 $table->string('name')->comment('名前'); 19 $table->date('birthday')->comment('生年月日'); 20 $table->unsignedTinyInteger('sex')->nullable()->comment('性別:男性:1,女性:2'); 21 $table->unsignedTinyInteger('status')->default(1)->comment('ステータス:有効:1,無効:0'); 22 $table->timestamps(); 23 $table->softDeletes(); 24 }); 25 } 26 27 /** 28 * Reverse the migrations. 29 * 30 * @return void 31 */ 32 public function down() 33 { 34 Schema::dropIfExists('members'); 35 } 36}

Factory

bash

1php artisan make:factory MemberFactory --model=Member

php

1<?php 2 3/** @var \Illuminate\Database\Eloquent\Factory $factory */ 4 5use App\Member; 6use Faker\Generator as Faker; 7 8$factory->define(Member::class, function (Faker $faker) { 9 return [ 10 'name' => $faker->name, 11 'birthday' => $faker->date('Y-m-d', '-10 years'), 12 'sex' => $faker->randomElement([1, 2]), 13 'status' => $faker->randomElement([0, 1]), 14 ]; 15});

Model(必須)

bash

1php artisan make:model Member
  • dates プロパティに birthday を指定しておけば、Carbon に自動で変換されるので、age の取得が楽
  • get...Attribute() を使いこなせば、blade の記述が劇的に簡素になる

php

1<?php 2 3namespace App; 4 5use Carbon\Carbon; 6use Illuminate\Database\Eloquent\Model; 7use Illuminate\Database\Eloquent\SoftDeletes; 8use Mockery\Exception; 9 10/** 11 * Class Member 12 * @package App 13 * 14 * @property string name 15 * @property Carbon birthday 16 * @property int sex 17 * @property int status 18 * @property int age 19 * @property string icon 20 */ 21class Member extends Model 22{ 23 use SoftDeletes; 24 25 /** 26 * 有効 27 */ 28 const ACTIVE = 1; 29 30 /** 31 * 無効 32 */ 33 const INACTIVE = 0; 34 35 /** 36 * 男性 37 */ 38 const MALE = 1; 39 40 /** 41 * 女性 42 */ 43 const FEMALE = 2; 44 45 protected $fillable = [ 46 'name', 47 'birthday', 48 'sex', 49 'status', 50 ]; 51 52 protected $dates = [ 53 'birthday' 54 ]; 55 56 /** 57 * 有効かの判定 58 * @return boolean 59 */ 60 public function isActive(): bool 61 { 62 return $this->status === self::ACTIVE; 63 } 64 65 /** 66 * 無効かの判定 67 * @return boolean 68 */ 69 public function isInactive(): bool 70 { 71 return $this->status === self::INACTIVE; 72 } 73 74 /** 75 * 男性かの判定 76 * @return boolean 77 */ 78 public function isMale(): bool 79 { 80 return $this->sex === self::MALE; 81 } 82 83 /** 84 * 女性かの判定 85 * @return boolean 86 */ 87 public function isFemale(): bool 88 { 89 return $this->sex === self::FEMALE; 90 } 91 92 /** 93 * 成人かどうか 94 * @return boolean 95 */ 96 public function isAdult(): bool 97 { 98 return $this->age >= 20; 99 } 100 101 /** 102 * 年齢を取得 103 * @return int 104 */ 105 public function getAgeAttribute(): int 106 { 107 return $this->birthday->age; 108 } 109 110 /** 111 * アイコンのファイル名を取得 112 * @param string 113 * @return string 114 */ 115 public function getIconAttribute(): string 116 { 117 switch ($this->sex) { 118 case self::MALE: 119 $path = 'img/male'; 120 break; 121 case self::FEMALE: 122 $path = 'img/female'; 123 break; 124 default: 125 // DB定義上、NULL許可なので 126 throw new Exception('性別が指定されていません。'); 127 } 128 129 if ($this->isAdult()) { 130 $path .= '/adult-'; 131 } else { 132 $path .= '/young-'; 133 } 134 135 if ($this->isActive()) { 136 $path .= 'active.svg'; 137 } else { 138 $path .= 'inactive.svg'; 139 } 140 141 return $path; 142 } 143}

確認のための不完全なTEST

bash

1php artisan make:test MemberTest

php

1<?php 2 3namespace Tests\Feature; 4 5use App\Member; 6use Tests\TestCase; 7 8class MemberTest extends TestCase 9{ 10 private $members; 11 12 public function setUp(): void 13 { 14 parent::setUp(); 15 16 $this->members = factory(Member::class, 100)->make(); 17 } 18 19 public function testIcon() 20 { 21 $this->members->each(function (Member $member) { 22 dump($member->icon); 23 }); 24 } 25}

投稿2020/11/09 08:36

phper.k

総合スコア3923

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

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

phper.k

2020/11/09 09:02

即席で書いたから、所々おかしいとこあるな。
hentaiman

2020/11/09 09:18

初心者(?)がこれを参考にしつつ不明点を自力で調べながら進める事が出来ればLaravelの技術力が飛躍的に上がる良い回答ですね ここまでコードが用意されていて自力で調査出来ない人はアウトー!ってふるいにかけるような回答とも捉える事が出来るけど
crescens

2020/11/09 09:23

ありがとうございます! マニュアルを読みながらよく読み込みます。 パッと見ですがとてもスッキリと書かれていて使い勝手良さそうですので、あとは私が理解するのみだと感じました。 簡素的に書くためのキーワードさえ思い浮かばなかったので、具体的な例があったらひとつひとつ調べられますので感謝しかないです。 ありがとうございます!
phper.k

2020/11/09 09:25

是非。 マジで、結構時間かかって書いた回答なので、無駄にされたら悲しいです。 @hentaiman さん ありがとうございます。
crescens

2020/11/11 00:06

まだ勉強中ですが、アクセサがとても便利だということは把握できました…。Laravelってすごいんですね。 的違いな質問かもしれませんが、意図を聞かせていただけたらありがたいです。 1.性別のDBをnull許可とした理由はあるのでしょうか? 分岐の仕方をswitchとifでサンプル作るためでしょうか? 2.性別の分岐で「0が扱いにくい」と記載されていますが、有効無効では0が使用されています。違いがあるのでしょうか?上記質問にも関係しますがswitchの影響でしょうか。
phper.k

2020/11/11 00:30 編集

1. このサンプルとしては、必須項目の時と、任意項目の時で処理を変えなきゃいけないという意味です。NULLを許可する場合の書き方を例示するため。 2, PHPでは 0 == NULL がtrue となります。0 === NULL は false になりますが、コードを書くときに意識して書くことを強制するよりは、1, 2 で扱うほうが、よほど安全なコードが書けるわけです。 有効無効では、NULL と 0 は同じ意味として扱っていいし、DB側でデフォルト値「1」を設定していることと、NULLは入ってこないように NULLABLE にはなっていませんから、0, 1 で構わないからです。
crescens

2020/11/11 00:49

理解しました。回答ありがとうございます!
hentaiman

2020/11/11 01:00

php8でやっとmatchが来るからソロ開発に限ればそういう気の回し方はしなくて良くなりそう
phper.k

2020/11/11 01:41

@hentaiman たしかに、SOLOなら…とは思うけど、これまでの手癖があったりするので、なかなか難しいですよね。 コードではなく、DB側の設計次第でいくらでも制約できたりするので、幅広く知識を持つことはこの先も重要だと思います。 かといって、DBのストアドやトリガーを使うことはありませんけどね…
guest

0

Laravel を使っているのであれば、アカウント Model に アクセサを設定しておくのが常套手段でしょう。

https://readouble.com/laravel/7.x/ja/eloquent-mutators.html

投稿2020/11/09 04:13

phper.k

総合スコア3923

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

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

crescens

2020/11/09 05:56

誤解を招いたのなら申し訳ないです。 プログラムの記述箇所に関する質問ではなく、プログラムの書き方に関する質問でした。 if文にするとネストだらけになるので、メンテナンス性の良い他の書き方はないかと思い質問しました。
phper.k

2020/11/09 06:16

> メンテナンス性の良い他の書き方はないかと思い質問しました。 それの回答ですけど・・・ 現状のソースコードはどうなっているんですか?
crescens

2020/11/09 07:09

失礼いたしました。現状のソースコードを追記致しました。 今は年齢に関してはviewで成人か未成年かのみで分岐している状態です。
phper.k

2020/11/09 07:40 編集

条件の種類は、コードで表現されているものだけで全てですか? それとも質問では省略し、実際はもっと条件があるということですか? ちなみに使っているLaravelのバージョンは?
phper.k

2020/11/09 07:44

プロパティの age は年齢を持つものと思いますが、誕生日が来たときには、インクリメントする仕組みは他に持っているのですか?
crescens

2020/11/09 07:47 編集

現状の条件の種類はコードで表現されているもので全てです。 このコードから、20歳以上の分岐を増やしたいところで止まっています。 誕生日の際は、ご認識のように他に仕組みをもっています
crescens

2020/11/09 07:49

Laravelのバージョンは6.11です
phper.k

2020/11/09 07:54

了解です。回答作成に結構時間かかると思うので、少々お待ち
crescens

2020/11/09 08:04

ありがとうございます。とても助かります!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問