Registering Database Migrations in Laravel Packages
When a Laravel package needs its own database tables, its maintainers must decide how the host application will find the package’s migration…
When someone uploads a file to a Laravel route, PHP places it in temporary storage and Laravel makes it available to your code as an uploaded-file object. Validate the object, then save the file to a configured storage disk. A disk is a named location Laravel uses to store files, such as the local filesystem or a public directory.
Send the file as multipart form data, a request format that sends file contents with form fields. Validate it on the server, then call store with a directory and disk. Laravel returns the saved file’s path. Save that path in a database to retrieve the file later.
An HTML form must use enctype="multipart/form-data" for the browser to send file contents. Give the file input a name that your Laravel route will use, and include Laravel’s CSRF token for a form submission:
<button type="submit">Upload</button>
Without this encoding type, Laravel does not receive the file as an uploaded file. The Laravel upload examples also highlight this form requirement.
Use Laravel’s server-side validation before saving a file. For example, this rule requires a file and accepts PDFs:
$request->validate([
'document' => ['required', 'file', 'mimes:pdf'],
]);
The required rule rejects a missing input. The file rule requires an uploaded file. The mimes rule limits which file types Laravel accepts. Add Laravel’s max rule to limit file size, and set the limit to match your upload policy. Laravel’s file type validation guidance covers these server-side checks. Browser-side restrictions can improve the form, but users can bypass them, so they do not replace server validation.
After validation, $request->file('document') returns an object of Symfony’s UploadedFile class, which Laravel uses to represent the uploaded file. The object provides methods such as store. If no file arrives, the call returns null; calling a file method on that value causes an error, as shown in Laravel’s request examples and upload error reports.
For an optional file input, check $request->hasFile('document') before storing it. That method returns a boolean, so use $request->file('document') to get the file object.
Call store on the uploaded-file object to save it. Pass a directory name and disk name to choose the destination directly, instead of relying on the project’s default disk:
use Illuminate\Http\Request;
public function store(Request $request)
{
$request->validate([
'document' => ['required', 'file', 'mimes:pdf'],
]);
$path = $request->file('document')->store('documents', 'local');
return response()->json(['path' => $path]);
}
Laravel saves the file in the documents subdirectory under the root configured for the local disk. The local disk typically uses a location under storage/app. Check config/filesystems.php to see whether your project uses a different root. The path returned by store is relative to the disk’s root, such as documents/<generated-name>.pdf. Keep the path to locate the file later. Laravel’s storage overview describes the storage API and local disk layout.
store generates a filename for the saved file and returns the path on success. Use storeAs('documents', $filename, 'local') when you need to choose the filename yourself. Treat a client-provided filename as untrusted input; validate and control any custom filename rather than using it directly as a path.
The local disk keeps files in Laravel’s storage area and suits files that should not be available through a public URL by default. For browser-accessible files, store the upload on the public disk:
$path = $request->file('document')->store('documents', 'public');
$url = Storage::url($path);
The public disk typically writes files under storage/app/public. Run php artisan storage:link to create public/storage, a symbolic link (a filesystem reference to another location) that lets the web server serve those files. If the link is missing or points to the wrong location, generated public URLs will not reach the stored files; Laravel’s storage-link troubleshooting discussion describes that issue.
Store private documents on a private disk. Anyone who can reach a public URL can access the file, so use the public disk only when you intend the file to be accessible through a public URL.
If $request->file('document') returns null, first check that the form uses multipart/form-data and that the input name matches the name your route reads. Then check the upload size limits configured for PHP, including upload_max_filesize and post_max_size. If the request exceeds either limit, Laravel may not receive a usable file object. Validation or an explicit hasFile check prevents your code from calling a file method on null.
Give Vroni a GitHub issue, bug report, spec, or rough idea. It reads the repo, plans the change, writes code, runs checks, and works toward a review-ready pull request.
Take a look at vroni.com