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

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

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

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

Laravel 5

Laravel 5は、PHPフレームワークLaravelの最新バージョンで、2014年11月に発表予定です。ディレクトリ構造がが現行版より大幅に変更されるほか、メソッドインジェクションやFormRequestの利用が可能になります。

Q&A

解決済

3回答

1980閲覧

Laravel ファイルのアップロードができない

nnahito

総合スコア2004

PHP

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

Laravel 5

Laravel 5は、PHPフレームワークLaravelの最新バージョンで、2014年11月に発表予定です。ディレクトリ構造がが現行版より大幅に変更されるほか、メソッドインジェクションやFormRequestの利用が可能になります。

0グッド

0クリップ

投稿2017/11/13 13:47

編集2017/11/13 23:57

はじめに

Laravel初心者です。

環境

Windows10
Larabel5.5
XAMPP
PHP 7.1.4 (cli)

質問

Laravel5.5で、Ajax通信を用いたファイルのアップロードができません。
どうやっても、move_uploaded_fileを実行しようとすると、Internet Server Error(500)が返却されてしまいます。
これは何故なのでしょうか?
ご存じの方がいらっしゃいましたら、ご教授いただけると幸いです。

ずっとレガシーコードで書いていたので、フレームワークを触ったことがなく、全然先に進めません……

コード

表面JavaScrip

javascript

1<script> 2 3 // ブラウザ上でファイルを展開する挙動を抑止 4 function onDragOver(event) { 5 console.log('aaa'); 6 event.preventDefault(); 7 } 8 9 // Drop領域にドロップしたファイル情報を読み取り 10 function onDrop(event) { 11 console.log('iii'); 12 // ブラウザ上でファイルを展開する挙動を抑止 13 event.preventDefault(); 14 15 // ドロップされたファイルのfilesプロパティを参照 16 var files = event.dataTransfer.files; 17 if (files.length >= 1) { 18 alert(files[0].name + ":" + files[0].size); 19 FileUpload(files[0]); 20 } 21 } 22 23 // ファイルアップロード 24 function FileUpload(f) { 25 console.log('uuuu'); 26 var formData = new FormData(); 27 formData.append('file', f); 28 $.ajax({ 29 type: 'POST', 30 dataType : "text", 31 contentType: false, 32 processData: false, 33 url: '/admin/file/upload/', 34 data: formData, 35 headers: { 36 'X-CSRF-TOKEN': '{{ csrf_token() }}' 37 } 38 }).done(function(json) { 39 alert(json); 40 41 }).fail(function(jqXHR, textStatus, errorThrown) { 42 43 console.log(jqXHR); 44 alert(textStatus); 45 46 }); 47 } 48 49 </script>

PHPコントローラー

PHP

1namespace App\Http\Controllers; 2 3use App\User; 4use Request; 5use Session; 6use App\Http\Controllers\Controller; 7use App\Model\Dao\ArticleDao; 8 9class AdminController extends Controller 10{ 11 /** 12 * ファイルのアップロード時に通るコントローラー 13 * 14 * @author Nな人<nnahito> 15 * @return view 16 */ 17 public function fileUpload(Request $request) { 18 19 // アップロードファイルが来ているか 20 if ( is_uploaded_file($_FILES['file']['tmp_name']) === true ) { 21 22 // 来ていたら、ファイルをアップロードできたか 23 if( move_uploaded_file($_FILES['file']['tmp_name'], '/upfiles/'.$_FILES['file']['name']) ){ 24 25 // アップロード成功 26 return response()->json(['status' => 'true']); 27 28 } else { 29 30 // アップロード失敗 31 return response()->json(['status' => 'false']); 32 33 } 34 35 } 36 37 // そもそもにアップロード失敗 38 return response()->json(['status' => 'false']); 39 40 } 41}

修正

ご指摘を受け、PHPのコントローラーを次のように書き直しましたがファイルのアップロードができませんでした……
該当フォルダの権限は777を与えております。

PHP

1public function fileUpload(Request $request) { 2 3 // ファイルが来ているかのチェック 4 if ( $request->hasFile('file') !== true ) { 5 return response()->json(['status' => 'false']); 6 } 7 8 // 入力ファイルの取得 9 $file = $request->file('file'); 10 11 // ファイルの保存(戻り値に保存作のパス) 12 $path = $request->file('file')->store('upfiles'); 13 14 // ファイルが取得できているかのチェック 15 if ( $request->file('file')->isValid() !== true ) { 16 // 失敗ならエラー 17 return response()->json(['status' => 'false']); 18 } 19 20 // アップロード成功ならファイルパスも返す 21 return response()->json(['status' => 'true', 'path' => $path]); 22 23 }

参考

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

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

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

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

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

m.ts10806

2017/11/14 00:39

そもそもphpに渡った時点でファイル情報(tmp)はちゃんと想定通りのものが来てるんですかね。
nnahito

2017/11/14 03:22

来てますよ
m.ts10806

2017/11/14 05:40

では、どこまで想定通りにきているか(ソース、ファイル実体)を確認した上で質問に追記された方が良いかと思います。
guest

回答3

0

Laravelでのファイルアップロード方法はこれです。
https://readouble.com/laravel/5.5/ja/requests.html#files
素のPHPでのやり方とかは全部忘れたほうがいいです。
とはいえ正常にアップできてるかの確認とファイルの保存なのでやることは同じです。

まずJSを使わず普通のファイルアップロードから試したほうがいいです。

投稿2017/11/13 14:02

kawax

総合スコア10377

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

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

nnahito

2017/11/13 14:24

ご回答ありがとございます。 早速、変更したところエラーは出なくなりました。 しかし、アップロードのパスは取得できるのですが、実際にファイルがアップロードできておりません。 こちら、$request->photo->store('');メソッドはどこからの相対パスになるのでしょうか? publicフォルダでしょうか? また、 > 素のPHPでのやり方とかは全部忘れたほうがいい これは何故でしょうか?
masaya_ohashi

2017/11/14 00:15

横からの意見になってしまいますが… >> 素のPHPでのやり方とかは全部忘れたほうがいい > これは何故でしょうか? Laravel独自の書き方で書いている箇所と、素のPHPの書き方で書いている箇所が混在すると、かなり問題になるからです。例えばなんらかの処理Aを書こうとしたとき、素のPHPでは本当にAのことしかやらないですが、Laravelの書き方で書くと、Aのセキュリティ向上やアクセス効率向上の為に必要なことBもやってくれている、という可能性があるからです。そして、なんらかの処理Cをするとき、Aの処理を素のPHPでやっていた場合、本来あるはずのBの処理が抜けていてバグになるからです。 あと、storeメソッドで保存される先はlaravelプロジェクトフォルダ/storage以下です。ただし、設定でストレージの場所をアマゾンS3等に変えていた場合、クラウド上のストレージに保存されます。
nnahito

2017/11/14 13:33

ご返信ありがとうございます。 > Laravel独自の書き方で書いている箇所と、素のPHPの書き方で書いている箇所が混在すると、かなり問題になるからです。 なるほどそういうことだったのですね。 ありがとうございます。 > あと、storeメソッドで保存される先はlaravelプロジェクトフォルダ/storage以下です。 こちら知識不足でした。 すべてpublicフォルダ配下に行くものだと思っておりました。
guest

0

ベストアンサー

Laravelのファイルアップロードの補足としては、公式ドキュメント翻訳の以下の箇所になります。
Laravel 5.5 ファイルストレージ ファイルアップロード
保存場所は、config/filesystems.phpの設定により決まります。
画像保存の場合は、以下のライブラリも使いやすいかと思います。
spatie/laravel-medialibrary
Getting started with Laravel Medialibrary

機能の基盤になっているものはflysystemライブラリで、Laravelでの初期サポート形式以外にも必要に応じてSftp等も使えます。
thephpleague/flysystem

投稿2017/11/14 03:29

aro10

総合スコア4106

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

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

nnahito

2017/11/14 13:42

ご回答ありがとうございます。 ファイルは/storageフォルダまで上げることができたのですが、これは結局ユーザに表示できません。 こちらどのようにしてユーザに画像を表示するのでしょうか。
nnahito

2017/11/14 13:46

失礼いたしました。 画像は、URLをルートからアップロードしたパスに変更すると普通に表示できました。
aro10

2017/11/14 13:48

disksをpublicとして、Storageフォルダにデータをアップロードした後は、 以下のコマンドで、storage/app/publicから公開ディレクトリのpublic/storageにシンボリックリンクを貼るコマンドがあるので活用できると思います。 ``` php artisan storage:link ``` [Laravel 5.5 ファイルストレージ パブリックディスク](https://readouble.com/laravel/5.5/ja/filesystem.html#file-uploads#the-public-disk)
nnahito

2017/11/14 13:49

ではなかったです……envいじって、アップロード先を変更してました
nnahito

2017/11/14 13:50

なるほど!そういうことができるのですね!! ありがとうございます!
guest

0

修正例について書いていきます。
この手の質問の場合は、viewsroutesの内容も提示して頂けるとありがたいです。

まずviewsは下記の様にしました。(抜粋)javascriptから呼ばれるURLをurl: '{{ route('fileUpload') }}に変更しています。

html

1 <div id="file_upload_section"> 2 <div id="drop" style="width:380px; height:100px; padding:10px; border:3px solid;" ondragover="onDragOver(event)" ondrop="onDrop(event)"> 3 ファイルをドラッグアンドドロップしてください。 4 </div> 5 </div> 6 </body> 7 8 <script src="{{ asset('js/jquery-3.1.1.min.js') }}"></script> 9 10 <script> 11 // ブラウザ上でファイルを展開する挙動を抑止 12 function onDragOver(event) { 13 console.log('aaa'); 14 event.preventDefault(); 15 } 16 17 // Drop領域にドロップしたファイル情報を読み取り 18 function onDrop(event) { 19 console.log('iii'); 20 // ブラウザ上でファイルを展開する挙動を抑止 21 event.preventDefault(); 22 23 // ドロップされたファイルのfilesプロパティを参照 24 var files = event.dataTransfer.files; 25 if (files.length >= 1) { 26 alert(files[0].name + ":" + files[0].size); 27 FileUpload(files[0]); 28 } 29 } 30 31 // ファイルアップロード 32 function FileUpload(f) { 33 console.log('uuuu'); 34 var formData = new FormData(); 35 formData.append('file', f); 36 $.ajax({ 37 type: 'POST', 38 dataType : "text", 39 contentType: false, 40 processData: false, 41 url: '{{ route('fileUpload') }}',//ここを変更 42 data: formData, 43 headers: { 44 'X-CSRF-TOKEN': '{{ csrf_token() }}' 45 } 46 }).done(function(json) { 47 alert(json); 48 49 }).fail(function(jqXHR, textStatus, errorThrown) { 50 51 console.log(jqXHR); 52 alert(textStatus); 53 54 }); 55 } 56 </script>

で、定義しているrouteはこちらです。api.phpを修正しています。

PHP

1Route::Post('/admin/file/upload/','AdminController@fileUpload')->name('fileUpload');

Controllerは、このままでも動きます。強いて言うなら

php

1 // 入力ファイルの取得 2 $file = $request->file('file'); 3 // ファイルの保存(戻り値に保存作のパス) 4 $path = $request->file('file')->store('upfiles');

// 入力ファイルの取得 $file = $request->file('file'); // ファイルの保存(戻り値に保存作のパス) $path = $file->store('upfiles');

とか

php

1 // 入力ファイルの取得 2 //$file = $request->file('file');いらない 3 // ファイルの保存(戻り値に保存作のパス) 4 $path = $request->file('file')->store('upfiles');

の方が良さげですが…余談なので放っておいてもいいです。

これによりアップロードファイルは、app/upfiles配下に格納されるはずです。

如何でしょうか?

投稿2017/11/14 00:41

編集2017/11/14 00:42
motuo

総合スコア3027

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

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

nnahito

2017/11/14 13:39

ご回答ありがとうございます。 > viewsとroutesの内容も提示して頂けるとありがたいです 失礼いたしました。 Controllerまでデータの通信を確認していたので省略してしまいました。 また、「toreメソッドで保存される先はlaravelプロジェクトフォルダ/storage以下」ということも知らず、アップロードに失敗していると勘違いしておりました。 また、丁寧なサンプルコードをありがとうございます。 今のところ、問題なくweb.phpでのアクセスで動いておりますが、こちらapi.phpの方がよろしいのでしょうか? また、/strageに上がったファイルは表面で表示させることができないのでしょうか?
nnahito

2017/11/14 13:46

失礼いたしました。 画像は、URLをルートからアップロードしたパスに変更すると普通に表示できました。
nnahito

2017/11/14 13:49

ではなかったです……envいじって、アップロード先を変更してました
motuo

2017/11/15 00:24

解決したようなので余談になりますが… >api.phpの方がよろしいのでしょうか? Ajaxで通信していたので、何となくAPIで組んでたのかな?という推測です。こだわらなくても良いとは思います。個人的にはWebページに関するルーティングはweb.phpでAjaxでデータを取ってくる処理などにはapi.phpを使っています。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問