«Вызов хранилища функций-членов () в массиве» при загрузке файла с использованием Laravel 8 с Jetstream — Vue и Intertia.js

У меня проблема с загрузкой изображения из формы в файл vue. Я пробовал несколько способов сделать это, но кажется, что файл не установлен должным образом.

  • Я установил "enctype="multipart/form-data" в своем теге формы

  • Вот мой элемент ввода:

    <ввод @change="при изменении файла" тип = "файл" принять = "изображение/*" класс = "управление формой" имя = "файл" идентификатор = "файл" ария-describedby="helpId" placeholder="Загрузить файл" />

  • Вот мои объекты данных и методы, которые отправляют данные:

      data() {
          return {
        editMode: false,
        professionaldevelopmentitems: [],
        professionaldevelopmentitem: {
          domain: 1,
          domaincategory: 1,
          title: "",
          dateofpd: "",
          location: "",
          lengthofpd: "",
          facilitatorname: "",
          facilitatorcredentials: "",
          reflection: "",
          file: "",
        },
      };
    },
    methods: {
      onFileChange(e) {
        alert(e.target.files[0]);
        alert(e.target.files[0].name);
        var files = e.target.files || e.dataTransfer.files;
        if (!files.length)
          return;
        this.professionaldevelopmentitem.file = e.target.files[0];
        alert(this.professionaldevelopmentitem.file);
      },    
      async addProfessionalDevelopmentItem() {
        document.getElementById("pdForm").reset();
        this.editMode = false;
        const res = await axios.post(
          "/api/professionaldevelopmentitems",
          this.professionaldevelopmentitem
        );
    
        if (res.status === 201) {
          Toast.fire({
            icon: "success",
            title: res.data,
          });
          document.getElementById("pdForm").reset();
          $("#manageProfessionalDevelopmentItem").modal("hide");
          Fire.$emit("modifiedPDItem");
        }
      },
      async editProfessionalDevelopmentItem(data) {
        this.professionaldevelopmentitem = Object.assign({}, data);
        this.editMode = true;
      },
      async updateProfessionalDevelopmentItems(data) {
        const res = await axios.put(
          `/api/professionaldevelopmentitems/${data.id}`,
          this.professionaldevelopmentitem
        );
    
        if (res.status === 200) {
          Toast.fire({
            icon: "success",
            title: res.data,
          });
          document.getElementById("pdForm").reset();
          $("#manageProfessionalDevelopmentItem").modal("hide");
          Fire.$emit("modifiedPDItem");
          this.editMode = false;
        }
      },
    

Я получаю данные в свой контроллер и пытаюсь сохранить файл:

обновление публичной функции (запрос $ request, $ id) {

dd($request->all());

$this->validate($request, [
    'title' => ['required'],
    'dateofpd' => ['required'],
    'lengthofpd' => ['required'],
    'location' => ['required']
]);

$path = $request->file('filename')->store('uploads');

$pditem = ProfessionalDevelopmentItem::find($id);
$pditem->domain = $request->domain;
$pditem->domaincategory = $request->domaincategory;
$pditem->title = $request->title;
$pditem->dateofpd = $request->dateofpd;
$pditem->lengthofpd = $request->lengthofpd;
$pditem->location = $request->location;
$pditem->facilitatorname = $request->facilitatorname;
$pditem->facilitatorcredentials = $request->facilitatorcredentials;
$pditem->certificategranted = $request->certificategranted;
$pditem->certificateexpires = $request->certificateexpires;
$pditem->certificateexpiration = $request->certificateexpiration;
$pditem->reflection = $request->reflection;
$pditem->nameofinstitution = $request->nameofinstitution;
$pditem->coursename = $request->coursename;
$pditem->coursecode = $request->coursecode;
$pditem->hoursofinstruction = $request->hoursofinstruction;
$pditem->creditgranted = $request->creditgranted;
$pditem->bookname = $request->bookname;
$pditem->bookauthor = $request->bookauthor;
$pditem->bookyear = $request->bookyear;
$pditem->bookpublisher = $request->bookpublisher;
$pditem->otherdescription = $request->otherdescription;
$pditem->filename = $path;

$pditem->save();

return response('Successfully Updated the Professional Development Item.', 200);

}

ответ назад - это ошибка в строке, когда он пытается сохранить файл:

"message": "Call to a member function store() on array",
"exception": "Error",

Любые мысли о том, что я ошибаюсь, будут оценены.

не должно быть $path = $request->file('filename')->store('uploads');

bhucho 11.12.2020 19:19

Спасибо, я просто добавил это - это не имеет значения.

Andrew 11.12.2020 19:21

попробуй проверить что внутри $request->file('filename') с помощью dd($request->file('filename'));

bhucho 11.12.2020 19:23

null сбрасывается с этим. К вашему сведению, последнее предупреждение "alert(this.professionaldevelopmentitem.file);" показывает «[object File]», так что кажется, что professionaldevelopmentitem.file устанавливается вместе с файлом, но, похоже, по какой-то причине он не встречается

Andrew 11.12.2020 19:33

Если я запущу это: "dd($request->file);" ответ "[]".

Andrew 11.12.2020 19:41

вы используете неправильный dd, либо попробуйте выполнить весь запрос, используя dd($request), либо используйте $request->file('filename'), также проверьте, что dd($request->hasFile('filename')) возвращает true или false

bhucho 11.12.2020 20:00

Хорошо спасибо. dd($request->hasFile('filename')) возвращает ложь

Andrew 11.12.2020 20:07

Я думаю, что на основе вашего кода компонента Vue файл должен быть доступен под ключом «файл». Попробуйте dd($request->hasFile('file'))

Donkarnash 11.12.2020 20:20
dd($request->hasFile('file')) также возвращает false
Andrew 11.12.2020 20:22

Проверьте с dd($request->all()) и посмотрите, какие ключи есть

Donkarnash 11.12.2020 20:23

И "filename" => null, и "file" => [] есть. «Имя файла» — это имя столбца, которое я пытаюсь обновить, указав путь ниже в функции обновления. Я обновил вопрос с помощью функции полного обновления.

Andrew 11.12.2020 20:35
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
11
2 869
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

Попробуйте отправить загруженный файл в FormData. Определите метод в компоненте Vue для подготовки FormData со всеми данными, которые вы хотите отправить через ajax на сервер.

prepareFormData() {
    let data = new FormData;

    Object.keys(this.professionaldevelopmentitem).forEach(
        key => data.append(key, this.professionaldevelopmentitem[key]
    );

    return data;
}

Затем используйте этот метод, чтобы получить FormData и отправить его в виде данных на сервер в addProfessionalDeveloomentItem и updataProfessionalDevelopmentItems.

async addProfessionalDevelopmentItem() {
    document.getElementById("pdForm").reset();
    this.editMode = false;
    const res = await axios.post(
      "/api/professionaldevelopmentitems",
      this.prepareFormData()
    );

    if (res.status === 201) {
      Toast.fire({
        icon: "success",
        title: res.data,
      });
      document.getElementById("pdForm").reset();
      $("#manageProfessionalDevelopmentItem").modal("hide");
      Fire.$emit("modifiedPDItem");
    }
  },
  

  async updateProfessionalDevelopmentItems(data) {
    const res = await axios.put(
      `/api/professionaldevelopmentitems/${data.id}`,
      this.prepareFormData()
    );

    if (res.status === 200) {
      Toast.fire({
        icon: "success",
        title: res.data,
      });
      document.getElementById("pdForm").reset();
      $("#manageProfessionalDevelopmentItem").modal("hide");
      Fire.$emit("modifiedPDItem");
      this.editMode = false;
    }
}

Затем вы должны получить загруженный файл в $request под ключевым файлом $request->file('file')

Эта ошибка означает, что $request->file('filename') возвращает массив. В нашем случае это потому, что мы разрешили пользователям отправлять 2 файла одновременно:

<form action = "/upload" method = "post" enctype = "multipart/form-data">
    @csrf
    <input type = "file" name = "filename[]"><br>
    <input type = "file" name = "filename[]"><br>
    <input type = "submit">
</form>

Чтобы исправить это, в Laravel 9 мы добавили проверку типа переменной в методе контроллера:

public function upload(Request $request)
{
    $file = $request->file('filename');

    if (is_array($file)) {
        foreach ($file as $item) {
            $item->store('uploads');
        }
    } else {
        $file->store('uploads');
    }

    // ...
}

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