他に通信を行いたいことを考えると、ファイルのアップロードが思いつきますね。![]()
やってみる
では早速アップロード用の DTO を作成しましょう。
$ php artisan make:data FileUploadData
今回は、文字列と PDF をアップロードするフォームを考えます。
Laravel は MimeType とファイルサイズを指定できます。
アップロードしたファイルは Illuminate の UploadFile というクラスに格納されるので、それを属性として登録しておきます。
namespace App\Data;
use Illuminate\Http\UploadedFile;
use Spatie\LaravelData\Attributes\Validation\File;
use Spatie\LaravelData\Attributes\Validation\Max;
use Spatie\LaravelData\Attributes\Validation\MimeTypes;
use Spatie\LaravelData\Data;
use Spatie\TypeScriptTransformer\Attributes\TypeScript;
#[TypeScript()]
class FileUploadData extends Data
{
public function __construct(
#[Max(255)]
public string $text,
#[File, MimeTypes('application/pdf'), Max(10 * 1024 * 1024)]
public UploadedFile $image,
) {}
}
これをコントローラーで処理します。
任意の名前で保存する場合は Storage::putFileAs() を利用します。
第一引数がファイル名に見えますが、ここはディレクトリまでです。
ここに名前を付与すると<filename>/<hash>.extという場所に保存されます。ファイル名を付与したい場合は
xxxAs系のメソッドを使って第三引数に保存します!!!
(n敗)
ちなみにディレクトリは先に作成しておきましょう。
戻り値で保存先のフルパスが取得できます。
public function upload(FileUploadData $data)
{
$path = Storage::putFileAs(
'',
$data->image,
$data->image->getClientOriginalName(),
);
dd([
'path' => $path,
'data' => $data,
]);
}
画面側は、こんな感じにしてみました。
PrimeVue では FileUpload コンポーネントに上がってきた File オブジェクトを手動で useForm に渡すことで実現しています。
<input type="file"> の場合は、同じような形で File オブジェクトをハンドリングすればOKです。
<template>
<form class="m-4 grid grid-cols-1 gap-2" @submit.prevent>
<div class="grid grid-cols-1">
<label>テキスト</label>
<InputText v-model="form.text"/>
<small class="text-red-500">{{ form.errors.text }}</small>
</div>
<div class="grid grid-cols-1">
<label>PDFアップロード</label>
<div class="flex items-center gap-2">
<FileUpload
mode="basic"
@select="onFileSelect"
customUpload
auto
severity="secondary"
chooseLabel="PDFアップロード"
class="p-button-outlined"
/>
<small>{{ form.image?.name }}</small>
</div>
<small class="text-red-500">{{ form.errors.text }}</small>
</div>
<div>
<Button label="送信" @click="onSubmit" />
</div>
</form>
</template>
<script setup lang="ts">
import { useForm } from '@inertiajs/vue3'
import Button from 'primevue/button'
import InputText from 'primevue/inputtext'
import FileUpload, { FileUploadSelectEvent } from 'primevue/fileupload'
import { upload } from '@/routes/tests'
const form = useForm<App.Data.FileUploadData>({
text: '',
image: undefined,
})
const onFileSelect = (e: FileUploadSelectEvent) => {
form.image = e.files[0]
}
const onSubmit = () => {
form.submit(upload())
}
</script>
では動かしで見ましょう!
アップロードしてみる
ボタンを押して、 Windows のファイル選択ダイアログから PDF ファイルを選択します。
これらは、File オブジェクトとして useForm に登録されます。
File は以下のようなデータが取得できるので、form.image?.name などと書くと画面上にファイルの内容を表示することができます。
上手くやれば画像表示とかもできますよ!
そして「送信ボタン」を押すと、、、
ファイルの保存に成功します!ワーイ!
終わりに
面倒なファイル送信も、Inerita.ja が適当にラップしてくれるんですよねぇ。
この通信は自動的に multipart/form-data; で送ってくれます。
なので、 base64 にしようか... `バイナリで投げつけようか.. などは何も考えなくてOKです。
ただこの記事で説明したのは、ファイルのアップロードの方法のみです。
データベースとの連携や、ファイルのトランザクションは他の方の記事などを読んでしっかり組みましょう。
データベースの範囲内であれば良しなにやってくれますが、ファイルは別空間での管理を余儀なくされますからね。。。
世の中やべーことになってるシステムはたくさんあります。![]()
お気をつけて!





