Как правильно использовать проверку типа аудиофайла в Laravel?

Я новичок в Laravel и пытаюсь изучить структуру. В настоящее время я создаю простую страницу сообщений/таблицы лидеров, на которую пользователи смогут загружать на нее аудиофайл. Все работает нормально, за исключением загрузки звука. Я не уверен, где ошибка. Я также использую vite для использования кода React для своих компонентов.

Для проверки: я пробовал использовать такие мимомы, как audio/mpeg, mp3, mpeg, aac, wav. Ни один из них не работал, когда я загрузил mp3. И при этом он не сохраняет файл. В конце концов я просто попытался сделать звук обнуляемым и не добавлять никаких дополнительных проверок. В этот момент он перенаправляет меня на страницу сообщений, где я могу увидеть данные. Но звук никуда не сохраняется. По сути, оно утрачено.

Ниже добавлю все необходимые файлы. Где я делаю что-то не так?

create_inzending_table.php:

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('inzendings', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->string('category');
            $table->timestamp('posted_at')->nullable();
            $table->string('upvotes')->nullable();
            $table->string('description');
            $table->string('posted_by');
            $table->string('audio');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('inzendingen');
    }
};

Запросы/StoreInzending.php:

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class StoreInzending extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array<string, mixed>
     */
    public function rules()
    {
        return [
            'audio' =>'nullable',
            'title' => ['required', 'string', 'max:255'],
            'description' => ['required', 'string', 'max:255'],
            'posted_by' => ['required', 'string', 'max:255'],
            'posted_at' => ['nullable', 'date'],
            'category' => ['required', 'string', 'max:255'],
            'upvotes' => ['integer'],

        ];
    }
}

Модели/Inzending.php:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Inzending extends Model
{
    protected $fillable = [
        'audio',
        'title',
        'description',
        'imageUrl',
        'posted_at',
        'posted_by',
        'category',
        'upvotes'
    ];
    
    use HasFactory;
}

маршруты/web.php:

Route::get('inzending', [InzendingController::class,'index'])->name('inzending.index');
Route::get('inzending/create', [InzendingController::class,'create'])->name('inzending.create');
Route::post('inzending', [InzendingController::class,'store'])->name('inzending.store');

СоздатьInzendingForm.jsx:

import React, { useState } from 'react';
import { Link, useForm, usePage } from '@inertiajs/react';
import InputError from '@/Components/InputError';
import InputLabel from '@/Components/InputLabel';
import PrimaryButton from '@/Components/PrimaryButton';
import TextInput from '@/Components/TextInput';
import SelectInput from '@/Components/SelectInput';
import FileInput from './FileInput';

export default function CreateInzendingForm({ mustVerifyEmail, status, className }) {
    const user = usePage().props.auth.user;
    const inzending = usePage()

    const { data, setData, patch, post, errors, processing, recentlySuccessful } = useForm({
        name: user.name,
        email: user.email,
        education: user.education,  
        cohort: user.cohort,
        title: inzending.title,
        description: inzending.description,
        posted_at: inzending.posted_at,
        category: inzending.category,
        posted_by: user.name,
        audio: inzending.audio,
    });

    const submit = (e) => {
        e.preventDefault();

        console.info(data);
        post(route('inzending.store'));
    }


    return (
        <section>
            <header>
                <h2 className = "text-lg font-medium text-gray-900 dark:text-gray-100">Create Inzending</h2>
            </header>

            <form onSubmit = {submit} encType='multipart/form-data' className = "mt-6 space-y-6">
                <div>
                    <InputLabel htmlFor = "title" value = "Title" />

                    <TextInput
                        id = "title"
                        className = "mt-1 block w-full"
                        onChange = {(e) => setData('title', e.target.value)}
                        required
                        isFocused
                        autoComplete = "title"
                    />
                    <InputError className = "mt-2" message = {errors.title} />
                </div>
                <div>
                    <InputLabel htmlFor = "description" value = "Description" />

                    <TextInput
                        id = "description"
                        className = "mt-1 block w-full"
                        onChange = {(e) => setData('description', e.target.value)}
                        required
                        isFocused
                        autoComplete = "description"
                    />
                    <InputError className = "mt-2" message = {errors.description} />
                </div>
                <div>
                    <InputLabel htmlFor = "category" value = "Category" />

                    <SelectInput
                        id = "category"
                        className = "mt-1 block w-full"
                        onChange = {(e) => setData('category', e.target.value)}
                        required
                        isFocused
                        autoComplete = "category"
                    />
                    <InputError className = "mt-2" message = {errors.category} />
                </div>
                <div>
                    <InputLabel htmlFor = "posted_by" value = "Posted By" />

                    <TextInput
                        id = "posted_by"
                        className = "mt-1 block w-full"
                        value = {data.name}
                        onChange = {(e) => setData('posted_by', e.target.value)}
                        required
                        isFocused
                        autoComplete = "posted_by"
                    />
                    <InputError className = "mt-2" message = {errors.posted_by} />
                </div>
                    <div>
                    <InputLabel htmlFor = "audio" value = "Audio" />

                    <FileInput
                        id = "audio"
                        name = "audio"
                        className = "mt-1 block w-full"
                        onChange = {(e) => setData('audio', e.target.value)}
                        required
                        isFocused
                        autoComplete = "audio"
                    />
                    <InputError className = "mt-2" message = {errors.audio} />

                <div className = "flex items-center gap-4">
                    <PrimaryButton disabled = {processing}>Save</PrimaryButton>
                </div>
                </div>
            </form>
        </section>
    );
}

ФайлИнпут.jsx:

import { forwardRef, useEffect, useRef } from 'react';

export default forwardRef(function FileInput({ type = 'file', name, className = '', isFocused = false, ...props }, ref) {
    const input = ref ? ref : useRef();

    useEffect(() => {
        if (isFocused) {
            input.current.focus();
        }
    }, []);

    return (
        <div className = "flex flex-col items-start">
            <input
                {...props}
                name = {name}
                type = {type}
                className = {
                    'border-gray-300 dark:border-gray-700 dark:bg-gray-900 dark:text-gray-300 focus:border-indigo-500 dark:focus:border-indigo-600 focus:ring-indigo-500 dark:focus:ring-indigo-600 rounded-md shadow-sm ' +
                    className
                }
                ref = {input}
            />
        </div>
    );
});

конфигурация/файловые системы.php:

'links' => [
        public_path('storage') => storage_path('app/public'),
        public_path('images') => storage_path('app/public/images'),
        public_path('videos') => storage_path('app/public/videos'),
        public_path('audio') => storage_path('app/public/audio'),
    ],

Любая помощь очень ценится!

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Поиск нового уровня в Laravel с помощью MeiliSearch и Scout
Поиск нового уровня в Laravel с помощью MeiliSearch и Scout
Laravel Scout - это популярный пакет, который предоставляет простой и удобный способ добавить полнотекстовый поиск в ваше приложение Laravel. Он...
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
0
0
89
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблема решена!

Это оказалось простым исправлением, так как в форме я читал e.target.value входного файла, который записывал C:\fakepath\file.mp3. Не сам файл.

Чтобы решить эту проблему, вместо этого прочитайте e.target.files[0].

Другие вопросы по теме