Storing Uploaded Files

Single File Uploads moved an upload with move_uploaded_file(), and Headers and Uploads showed store() picking a random name. storeAs() takes the name, here the product's SKU, so a new cover replaces the old, and the last argument names the disk:

A cover upload route that stores on the public diskPHP
Route::post('/products/{product}/cover', function (Request $request, Product $product) {
    $request->validate(['cover' => ['required', 'image', 'max:2048']]);
    $file = $request->file('cover');
    $path = $file->storeAs('covers', "{$product->sku}.{$file->extension()}", 'public');
    return ['path' => $path, 'url' => Storage::disk('public')->url($path)];
});
Output
$ curl -s -H 'Sec-Fetch-Site: same-origin' -F 'cover=@cover.jpg' $B/products/1/cover | jq -c
{"path":"covers/BK-PHP-01.png","url":"http://127.0.0.1:8317/storage/covers/BK-PHP-01.png"}

The upload was a PNG named cover.jpg; extension() reads the bytes, so the name ends in .png (the header stands in for a browser's, which the CSRF check accepts, CSRF Protection). Build names from data you own, never from getClientOriginalName(), and keep uploads on the private local disk unless everyone may see them. storeAs() overwrites silently, and it streams the temporary file through the disk's putFileAs(), so large uploads never sit whole in memory.