Как обновить изображение с помощью метода PUT в Laravel REST API?

#php #laravel #rest #vue.js #eloquent

#php #laravel #rest #vue.js #красноречивый

Вопрос:

Я пытаюсь создать REST API с помощью Laravel, где пользователям необходимо обновить свой образ. Но, если я использую метод PUT в postman, он не обновляет изображение и не сохраняет изображение в указанной папке. Если я использую POST вместо этого, он обновляет изображение, а также сохраняет в папке. Но это не сохраняет файл в базе данных, поскольку я настраиваю имя для хранения в БД. В чем может быть причина. Помощь действительно необходима. TIA.

Обновить код

 public function update(Request $request, $id)
{
    $found = Partner::find($id);
    if (!$found) {
        return Response::json(['message' => 'Id not found'], 404);
    }
    $validatedData = Validator::make($request->all(), [
        'company_logo' => 'sometimes|mimes:jpg,png,jpeg|max:3048',
        'company_name' => 'sometimes|max:130',
        'company_email' => 'sometimes|email',
        'password'  =>  'sometimes|min:6',
        'phone'  =>  'sometimes|min:6|max:11',
        'address'  =>  'sometimes',
        'city'  =>  'sometimes|string',
        'country' =>  'sometimes|string' ,
        'business_category'  =>  'sometimes|string',
        'website_link' =>  'nullable|string',
        'facebook_page' =>  'nullable|string'
    ]);
    if ($validatedData->fails()) {
        return Response::json(['success' => false, 'message' => $validatedData->errors()], 400);
    }

    if ($request->hasFile('company_logo')) {
        $logo = $request->company_logo;
        $fileName = date('Y') . $logo->getClientOriginalName();
        $request->company_logo->storeAs('company_logo', $fileName, 'public');
        $found['company_logo'] = $fileName;
    }
    
    $found->update($request->all());

    return Response::json(['success' => true, 'message' => 'Partner updated successfully!', 
                           'updated_data' => $found], 200);
}
  

Мой маршрут

 Route::group(['prefix' => 'partner'], function () {
Route::post('store', [APIMemberController::class, 'store']);
Route::post('update/{id}', [APIPartnerController::class, 'update']); // This works
// Route::put('update/{id}', [APIPartnerController::class, 'update']); // This don't why?
});
  

Партнер по хранению

 public function store(Request $request)
{
    $validatedData = Validator::make($request->all(), [
        'company_logo' => 'required|mimes:jpg,png,jpeg|max:3048',
        'company_name' => 'required|max:130',
        'company_email' => 'required|email|unique:partners',
        'password'  =>  'required|min:6',
        'phone'  =>  'required|min:6|max:11',
        'address'  =>  'required',
        'city'  =>  'required|string',
        'country' =>  'required|string' ,
        'business_category'  =>  'required|string',
        'website_link' =>  'nullable|string',
        'facebook_page' =>  'nullable|string'
    ]);

    if ($validatedData->fails()) {
        return Response::json(['success' => false, 'message' => $validatedData->errors()], 400);
    }

    // $saved = Partner::create($request->all());

    if ($request->hasFile('company_logo')) {
        $logo = $request->file('company_logo');
        $fileName = date('Y') . $logo->getClientOriginalName();
        $request->company_logo->storeAs('company_logo', $fileName, 'public');
    }

    $partner = new Partner();
    
    $partner->company_logo = $request->company_logo->getClientOriginalName();
    $partner->company_name = $request->company_name;
    $partner->company_email = $request->company_email;
    $partner->password = $request->password;
    $partner->phone = $request->phone;
    $partner->address = $request->address;
    $partner->city = $request->city;
    $partner->country = $request->country;
    $partner->business_category = $request->business_category;
    $partner->website_link = $request->website_link;
    $partner->facebook_page = $request->facebook_page;
    $partner->save();
    return Response::json(['success' => 'Partner created successfully!', 'created_partner' => $partner], 201);


}
  

Комментарии:

1. Где находится код публикации?

2. Метод обновления @miken32 — это код публикации!

3. Нет, это получает сообщение. Как вы публикуете?

4. Вы выполняете $found-> update($request-> all()); $request[‘company_logo’] — это файл, который заменяет эффект $found[‘company_logo’] в if($request-> HasFile(‘company_logo’), поэтому в БД нет данныхдля имени файла

5. @JakariaRidoy Я не помню точную причину. Однако обходной путь заключается в том, что вы должны использовать POST-запрос с _method=»PUT» в данных формы для загрузки файлов.

Ответ №1:

Я вижу два изменения, которые должны дать вам желаемый результат с помощью функции обновления

 public function update(Request $request, $id)
{
    $found = Partner::find($id);
    if (!$found) {
        return Response::json(['message' => 'Id not found'], 404);
    }
    $validatedData = Validator::make($request->all(), [
        'company_logo' => 'sometimes|mimes:jpg,png,jpeg|max:3048',
        'company_name' => 'sometimes|max:130',
        'company_email' => 'sometimes|email',
        'password'  =>  'sometimes|min:6',
        'phone'  =>  'sometimes|min:6|max:11',
        'address'  =>  'sometimes',
        'city'  =>  'sometimes|string',
        'country' =>  'sometimes|string' ,
        'business_category'  =>  'sometimes|string',
        'website_link' =>  'nullable|string',
        'facebook_page' =>  'nullable|string'
    ]);
    if ($validatedData->fails()) {
        return Response::json(['success' => false, 'message' => $validatedData->errors()], 400);
    }

    if ($request->hasFile('company_logo')) {
        $logo = $request->company_logo;
        $fileName = date('Y') . $logo->getClientOriginalName();

    //Get the path to the folder where the image is stored 
    //and then save the path in database
        $path = $request->company_logo->storeAs('company_logo', $fileName, 'public');
        $found['company_logo'] = $path;
    }
    
    //update with all fields from $request except 'company_logo'

    $found->update($request->except('company_logo'));

    return Response::json(['success' => true, 'message' => 'Partner updated successfully!', 
                           'updated_data' => $found], 200);
}
  

Просто чтобы включить его в ответ здесь:

Если кто-то хочет использовать запрос PUT или PATCH для формы, содержащей загрузку файлов

 <form action="/foo/bar" method="POST">
    @method('PUT')

    ...
</form>
  

через любой фреймворк javascript, например vue

 let data = new FormData;
data.append("_method", "PUT")

axios.post("some/url", data)
  

Я это сделал. Но теперь мой вопрос в том, почему PUT не работает для Laravel в методе обновления?

Это не из-за Laravel, это особенность / ограничение PHP. PHP не заполняет супер глобал $_FILES во время запроса PUT, как это происходит во время запроса POST.

Чтобы получить доступ к загрузке файла с помощью метода Put/ в PHP, см. features.file-upload.put-method

Следовательно, вероятно, проще сделать запрос POST для загрузки файлов и использовать подмену метода, чтобы Laravel знал, что запрос относится к маршруту, соответствующему методу PUT

Комментарии:

1. Я это сделал. Но теперь мой вопрос в том, почему PUT не работает для Laravel в методе обновления?

2. Хотя большое спасибо за ваш ответ

3. Если данные изменения работают для вас, чтобы получить желаемый результат, вы можете пометить его как принятый ответ или проголосовать за него в интересах последующих посетителей.

4. Сообщение с методом put должно содержать идентификатор данных, в противном случае вызываемый им метод не разрешен axios.post("some/url/{id}", data)

5. @Nurkartiko Скажите, если маршрут PUT определен как Route::put('some/url/{id}', [SomeController::class, 'update']); amp; Запрос POST выполняется через axios с данными, содержащими _method=PUT like axios.post('some/url', data) . Когда Laravel пытается вывести входящий запрос, он оценивает URL-адрес и пытается сопоставить его с объявленными маршрутами, будет сопоставлен маршрут POST для хранилища, затем он считывает _method=PUT ключ и пытается найти маршрут put с заданным URL, который не найден. Таким образом, он выдаст сообщение об ошибке, что метод PUT не разрешен для данного URL-адреса «some / url» без идентификатора