-
Notifications
You must be signed in to change notification settings - Fork 0
Core Concepts
The package has four moving parts. Once you understand how they fit together, every adapter behaves the same way.
File ──setFile()──▶ Upload ──delegates──▶ Adapter ──▶ storage backend
▲ │
│ ▼
$_FILES / a path validate + store
A File is a value object describing one file. You
rarely build it by hand; instead:
-
File::setPost('field')reads$_FILES['field']and returns aFile[]— one entry per uploaded file. -
File::setPath('/path/to/file')wraps a file already on disk.
The crucial detail: the original client file name is the source of truth for the name and the extension — not the temporary upload path, which has no extension. This is what makes extension validation and renaming work.
$file = File::setPath('/tmp/IMG_0042.JPG');
$file->getName(); // "IMG_0042.JPG"
$file->getExtension(); // "jpg" (lower-cased)
$file->getSize(); // bytesAn adapter is a storage backend. All three implement the same
UploadAdapterInterface:
| Adapter | Stores to | Page |
|---|---|---|
LocalAdapter |
the local filesystem | Local Adapter |
FTPAdapter |
an FTP/FTPS server | FTP Adapter |
S3Adapter |
an Amazon S3 bucket | S3 Adapter |
Each takes two arrays:
new LocalAdapter($credentials, $options);
// └ where └ what is allowed (optional)-
credentials— backend-specific connection details (a directory and URL for local; host/user/password for FTP; key/secret/bucket for S3). -
options— the validation rules, identical across adapters.
Upload is a thin, type-safe decorator around an
adapter. It is what you call setFile() and to() on:
$upload = new Upload($adapter);
$upload->setFile($file) // returns the same Upload (chainable)
->to(); // returns File|falseWhy wrap the adapter at all? Upload implements the same interface, gives you
a stable type to type-hint against, and keeps the fluent API consistent:
- The mutating
set*methods (setFile,setOption,setCredentials, …) return the sameUploadfor chaining. - The
with*methods (withOption,withCredentials, …) return a newUploadwrapping a fresh adapter clone, leaving the original untouched — handy for per-request tweaks.
$base = new Upload($adapter);
// Original unchanged; $strict is an independent copy.
$strict = $base->withOptions(['allowed_max_size' => 512 * 1024]);to($target) takes an optional $target that means the same thing in every
adapter: a destination path/key prefix.
$upload->setFile($file)->to('avatars/2026');| Adapter | Result of to('avatars/2026')
|
|---|---|
| Local | file written to <dir>/avatars/2026/<name>
|
| FTP | file sent to <remote>/avatars/2026/<name> (dirs created) |
| S3 | object stored under key avatars/2026/<name> in the bucket |
Call to() with no argument to store at the destination root. Backslashes and
surrounding slashes in $target are normalized, so '\\a\\b\\' and 'a/b'
behave identically.
S3 note:
$targetis the object key prefix, never the bucket. The bucket always comes from the credentials. (Earlier versions treated it as the bucket name — see the changelog.)
How the file reaches its destination depends on where it came from:
| Source | Local adapter behaviour |
|---|---|
A real HTTP upload (File::setPost()) |
moved with move_uploaded_file()
|
A path-loaded file (File::setPath()) |
copied, leaving the original in place |
The adapter decides via File::isUploaded(). This means you
can safely re-upload an existing asset with setPath() without destroying it.
$upload->setFile($file)->to('avatars');-
Validate — the adapter checks the upload error code, then your
allowed_extensions,allowed_mime_typesandallowed_max_size. A failure throws anUploadException. -
Resolve the name —
$targetprefix + the renamed name (if you calledrename()) or the original name. - Store — move/copy/transfer/put the bytes, creating directories as needed.
-
Set the URL — on success the stored
Filegets its publicgetURL()populated, and is returned. A failed write returnsfalse.
-
The
FileObject — every accessor in detail - Validation — the rules and their messages
- Local / FTP / S3 adapters
- API Reference — the complete public surface
initphp/upload · MIT License · part of the InitPHP family
Source · Issues · Discussions · Packagist · Contributing · Security Policy
Getting Started
Reference
Adapters
Practical Guides
Other