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

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

新規登録して質問してみよう
ただいま回答率
85.50%
Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

Laravel

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

PHP

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

Q&A

解決済

1回答

2158閲覧

Laravelで画像アップロードの条件分岐ができない

izaya

総合スコア16

Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

Laravel

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

PHP

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

0グッド

0クリップ

投稿2021/02/12 09:16

編集2021/02/13 04:17

ユーザーのプロフィール更新において、アイコン画像アップロードの処理をif文で条件分岐させようと思っています。
フロントをVue.jsで作成してaxiosでpostしています。

↓UserEdit.vue

vue

1<template> 2 3 <div class="user-edit-page"> 4 5 <div class="user-edit"> 6 7 <div class="user-edit-box" v-if="form"> 8 9 <!-- トップ --> 10 <div class="user-edit-top"> 11 プロフィール編集 12 </div> 13 14 <div class="user-edit-name-icon"> 15 16 <!-- アイコン --> 17 <div class="user-edit-icon-name"> 18 19 <div class="user-edit-icon"> 20 21 <!-- アイコンのプレビュー削除ボタン --> 22 <img v-if="url" class="user-edit-batsu-icon" :src="'../../../image/batsu.png'" @click="deletePreview"> 23 24 <!-- 元々のアイコン --> 25 <img class="user-edit-icon-img" v-if="form.icon && !url" :src="form.icon"> 26 <!-- アイコンがない場合の仮画像 --> 27 <img class="user-edit-icon-img" v-if="!form.icon && !url" :src="'../../../image/user.png'"> 28 <!-- アップロードしたアイコンのプレビュー --> 29 <div v-if="url" class="preview" :style="{ backgroundImage: 'url(' + url + ')' }"></div> 30 31 </div> 32 33 <!-- アイコン画像アップロードボタン --> 34 <div class="user-edit-icon-up"> 35 <label> 36 <img class="image-icon" :src="'../../../image/image.png'"> 37 <input class="file-upload" type="file" ref="preview" @change="uploadIcon" accept="image/*"> 38 </label> 39 </div> 40 41 <!-- アイコン画像のエラーメッセージ表示 --> 42 <div v-if="message" class="user-edit-error"> 43 {{ message }} 44 </div> 45 46 </div> 47 48 <!-- 現在のユーザー名表示 --> 49 <div class="user-edit-current-user-name"> 50 {{ form.name }} 51 </div> 52 53 </div> 54 55 <!-- ユーザー名変更欄 --> 56 <div class="user-edit-user-name"> 57 58 <label for="name"> 59 ユーザー名 60 </label> 61 62 <input type="text" id="name" v-model="form.name"> 63 64 <div v-if="errors.name" class="user-edit-error"> 65 {{ errors.name[0] }} 66 </div> 67 68 </div> 69 70 <!-- 自己紹介文 --> 71 <div class="user-edit-pr"> 72 73 <label for="pr"> 74 自己紹介 75 </label> 76 77 <textarea v-model="form.pr" id="pr"></textarea> 78 79 <div v-if="errors.pr" class="user-edit-error"> 80 {{ errors.pr[0] }} 81 </div> 82 83 </div> 84 85 <!-- 変更ボタン --> 86 <div class="user-edit-modify-btn" @click="submit"> 87 変更 88 </div> 89 90 <!-- テスト --> 91 <div class="user-edit-modify-btn" @click="checkForm"> 92 チェック 93 </div> 94 95 </div> 96 97 </div> 98 99 </div> 100 101</template> 102 103 104<script> 105export default { 106 data () { 107 return { 108 // 送信データ 109 form: { 110 id: null, 111 icon_url: null, 112 name: null, 113 pr: null, 114 // 新しいアイコン 115 newIconImage: null, 116 }, 117 errors: [], 118 // プレビュー用データ 119 url: '', 120 // ここでだけ使うデータ 121 message: '', 122 } 123 }, 124 125 methods: { 126 // 画像の検証とプレビュー表示 127 uploadIcon() { 128 this.form.newIconImage = this.$refs.preview.files[0]; 129 if (!this.form.newIconImage.type.match('image.*')) { 130 this.message = '画像ファイルを選択してください'; 131 this.form.newIconImage = null; 132 return; 133 } 134 this.form.icon_url = null; 135 this.url = URL.createObjectURL(this.form.newIconImage); 136 this.$refs.preview.value = ''; 137 this.message = ''; 138 console.log(this.form.newIconImage); 139 console.log(this.url); 140 }, 141 // 画像のプレビュー削除 142 deletePreview() { 143 URL.revokeObjectURL(this.url); 144 this.form.newIconImage = null; 145 this.form.icon_url = null; 146 this.url = ''; 147 console.log(this.form.newIconImage); 148 console.log(this.form.icon_url); 149 console.log(this.url); 150 }, 151 // 変更を送信 152 submit() { 153 let data = new FormData(); 154 data.append('id', this.form.id); 155 data.append('icon_url', this.form.icon_url); 156 data.append('name', this.form.name); 157 data.append('pr', this.form.pr); 158 data.append('newIconImage', this.form.newIconImage); 159 axios.post('/api/user/edit', data) 160 .then(() => { 161 this.$router.push({ name: 'user', params: { id: this.form.id }}); 162 }).catch((error) => { 163 this.errors = error.response.data.errors; 164 }); 165 }, 166 }, 167 168 mounted() { 169 axios.get('/api/user') 170 .then((res) => { 171 console.log(res.data); 172 this.$set(this.form, 'id', res.data.id); 173 this.$set(this.form, 'icon', res.data.icon_url); 174 this.$set(this.form, 'name', res.data.name); 175 this.$set(this.form, 'pr', res.data.pr); 176 }); 177 }, 178} 179</script>

↓UserController.php

php

1<?php 2 3namespace App\Http\Controllers; 4 5use Illuminate\Http\Request; 6use Illuminate\Validation\ValidationException; 7use Illuminate\Support\Facades\Auth; 8use Illuminate\Support\Facades\Hash; 9use InterventionImage; 10 11use App\User; 12use Storage; 13 14 15class UserController extends Controller 16{ 17 // ユーザーのプロフィール更新 18 public function update(Request $request) 19 { 20 $request->validate(User::$updateRules, User::$updateValMessages); 21 22 $user = User::find(Auth::id()); 23 24 print_r($request->hasFile('newIconImage')); 25 print_r($request->icon_url); 26 27 // アイコン画像アップロードの処理 28 if ($request->hasFile('newIconImage')) { 29 // 画像を正方形にリサイズして保存 30 $image = $request->file('newIconImage'); 31 InterventionImage::make($image) 32 ->fit(200, 200) 33 ->save($image); 34 $path = Storage::disk('s3')->putFile('user_icon', $image, 'public'); 35 // 現在のアイコン画像の削除して新たに画像を保存 36 Storage::disk('s3')->delete(parse_url($user->icon_url, PHP_URL_PATH)); 37 $user->icon_url = Storage::disk('s3')->url($path); 38 } else if (!$request->icon_url) { 39       // プロフィール更新ページで現在のアイコン画像を削除していた場合はuserのicon_urlをnullにする 40 Storage::disk('s3')->delete(parse_url($user->icon_url, PHP_URL_PATH)); 41 $user->icon_url = null; 42 } else { 43 //その他の場合はそのまま 44 $user->icon_url = $user->icon_url; 45 } 46 47 // ユーザー名と自己紹介文の更新 48 $user->name = $request->name; 49 $user->pr = $request->pr; 50 51 $user->save(); 52 } 53} 54

上のようにUserController.phpで、
$request->hasFile('newIconImage')が偽で
$request->icon_urlがnullの場合は、
上のelse ifのところの
「// プロフィール更新ページで現在のアイコン画像を削除していた場合はuserのicon_urlをnullにする」処理をさせたいのですが、実際にその場合で実行してみるとelse ifのとこの処理が行われず、その下のelseの処理が行われてしまいます。

試したこととしては、
「アイコン画像アップロードの処理」の直前でprint_rでそれぞれの値を確かめてみると、
$request->hasFile('newIconImage')は値なし、
$request->icon_urlはnullになっていました。

なぜelse ifのところの処理が呼ばれないのでしょうか?

ちなみに、アップロードの方はちゃんとできます。

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

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

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

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

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

m.ts10806

2021/02/12 09:26

VIEWもご提示ください。
izaya

2021/02/12 09:37

すみません、追記させていただきました!
izaya

2021/02/12 09:41

もう一回変更しましたので、もし現在ご覧いただいているようでしたら画面をリロードしていただいてよろしいですか?
m.ts10806

2021/02/12 09:42

あれ。Vue.jsですか。てっきり普通にBladeとLaravelだけかと。 それならタグも追加してもらった方がいいですね。 https://teratail.com/tags/Vue.js
izaya

2021/02/12 09:45 編集

あ、忘れてました!追加しておきました。 でも多分問題があるのはUserController.phpの方だけだと思うのですが。。
m.ts10806

2021/02/12 09:55

いえ、nullならそもそもform側の設定とかあるかもしれないと思って。 Vueは分からないのですが、this.form.iconImageだけでファイルの実態ってとれるのかなぁという疑問はあります。 大抵.files[0]とかでとるので。 https://developer.mozilla.org/ja/docs/Web/Guide/Using_FormData_Objects axiosも使ったことないですが、ファイル添付は別途処理が必要なように見えます。 https://r17n.page/2020/02/04/nodejs-axios-file-upload-api/
izaya

2021/02/12 10:09

UserControllerの「 if ($request->hasFile('newIconImage')) 」のところで、 newIconImageにファイルが入っているときはちゃんと画像のアップロードはできるので、vueにおけるfiles[0]のところの処理は質問では省略させていただきました。。 ただ、「newIconImageにファイルが存在しているけど$request->icon_urlに値がない場合」にelse if の中の処理が呼ばれないんですよね。。 何か原因として考えられることってありますか?
Lulucom

2021/02/12 12:20

> else if の中の処理が呼ばれない 通ってないこともprint_rで確認されたということでしょうか? 通ってないと思っていたけど実は通っていて、その2行で何か別の問題が起きているという可能性もあるのかなと思いました。
izaya

2021/02/12 14:07 編集

else if の中もprint_rで確認しましたが、通っていないようでした。 多分、if ()、else if ()、の()内の書き方に問題があるのでしょうが、いくら考えてもわかりませんでした。。 一応質問のUserEdit.vueの方に省略していた画像アップロードのメソッドも追記しておきました。 自分でも原因をもっとよく考えてみます。。
Lulucom

2021/02/12 16:04 編集

> $request->hasFile('newIconImage')は値なし、 > $request->icon_urlはnullになっていました。 print_r()の代わりにvar_dump()で再確認してみてはいかがでしょう。型も表示されますので。
izaya

2021/02/13 03:56 編集

わあ、なんということでしょう! var_dumpで調べてみると、 $request->hasFile('newIconImage')はbool(false)、 $request->icon_urlはstring(4) "null" となっていました。 vueの方ではnull型のnullで送信しているのに、Laravelで受信したらstring型の'null'になってしまっていたということですね! ですので、UserController.phpの else if (!$request->icon_url) を、 else if ($request->icon_url = 'null') としてやると、ちゃんとelse if の中身が呼ばれました。 今度からは何か検証する際にはvar_dumpをなるべく使うようにすべきということを今回学べました。 Lulucomさん本当にありがとうございました! でもelse if ($request->icon_url = 'null')はあまり美しくないので修正すべきかもですね。
m.ts10806

2021/02/12 20:16

>else if ($request->icon = 'null') これだと比較ではなく代入です。
Lulucom

2021/02/13 00:41

少し解決に近づいたようで良かったです。掲載されたUserEdit.vueを拝見する限りでは'null'ではなくnullになっているようなので、まだそこが謎ですね・・・
izaya

2021/02/13 03:50

@m.ts10806 あ、書き間違えました!「===」としても同じ結果となりました。 やはり$request->iconにはstring型の'null'が入っているようです。。
izaya

2021/02/13 04:01 編集

@m.ts10806 @Lulucom バリデーションルールに 'icon_url' => 'nullable' を設定すればひょっとして治るかもと思ったのですが、やはりまたstring型の'null'が入っているようでした。。 何はともあれ前進できてよかったです。お二方ご協力ありがとうございますm(__)m
Lulucom

2021/02/13 04:02

> 掲載されたUserEdit.vueを拝見する限りでは'null'ではなくnullになっている UserEdit.vueの掲載されていない部分で'null'を入れてしまっているということはないでしょうか。
m.ts10806

2021/02/13 04:03

> としても同じ結果となりました。 いえ、結果というより見たまんま「それでは分岐の意味をなさない」という指摘です。
izaya

2021/02/13 04:19 編集

@m.ts10806 あ、 else if ($request->icon === 'null') と修正して実行するとちゃんと分岐されてうまくいきます。「同じ結果になった」ではなくて「うまくいった」が正しかったですね。。ご指摘ありがとうございます。
izaya

2021/02/13 04:25

@Lulucom UserEdit.vueで略しているのはhtml部分だけですので、'null'をを代入しているはずはないと思うのですが。。 一応、UserEdit.vueで略していたところも質問の方に追記しました。う〜ん、どこで型変換が起こったんでしょう。。
m.ts10806

2021/02/13 04:26

ただ「`null`という文字」に固定で置き換えるのは悪手ではないかと。
izaya

2021/02/13 04:32

@m.ts10806 >「`null`という文字」に固定で置き換える どこの部分でしょうか? else if ($request->icon === 'null') のところですか?
Lulucom

2021/02/13 04:46

どうもFormDataにnullをセットしても内部で"null"になってしまうようですね。
izaya

2021/02/13 05:08 編集

@Lulucom @m.ts10806 >どうもFormDataにnullをセットしても内部で"null"になってしまうようですね。 あ、それですね!FormDataの仕様の問題でしたか。ググり足りませんでした。。 ですから、UserEdit.vueのmethodsの「//変更を送信」のところの data.append('icon_url', this.form.icon_url); data.append('newIconImage', this.form.newIconImage); を、 if (this.form.icon_url) { data.append('icon', this.form.icon_url); } if (this.form.newIconImage) { data.append('iconImage', this.form.newIconImage); } と修正してあげたら、$request->icon_urlにnull型のnullがちゃんと入っており、 else if (!$request->icon) の条件分岐でうまくいきました! これで全て解決したと思われます。お二方本当にありがとうございました。もっとリサーチ力をつけたいと思います。
Lulucom

2021/02/13 05:22

よかったです、勉強になりました。
guest

回答1

0

自己解決

どうやら、FormDataはnullを送信できないため、null型のnullを送信しようとすると勝手にstring型の'null'に変換されてしまうようです。
ですから、
ですから、UserEdit.vueのmethodsの「//変更を送信」のところの

vue

1data.append('icon_url', this.form.icon_url); 2data.append('newIconImage', this.form.newIconImage);

を、

vue

1if (this.form.icon_url) { 2 data.append('icon', this.form.icon_url); 3} 4if (this.form.newIconImage) { 5 data.append('iconImage', this.form.newIconImage); 6}

と修正してあげたら、$request->icon_urlにnull型のnullがちゃんと入っており、
else if (!$request->icon)
の条件分岐でうまくいきました!

投稿2021/02/13 06:25

編集2021/02/13 06:26
izaya

総合スコア16

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問