> For the complete documentation index, see [llms.txt](https://quantumphp.gitbook.io/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://quantumphp.gitbook.io/docs/packages/storage/adapters.md).

# Adapters

Quantum ships with one local adapter and two cloud adapters. They share the same top-level `FileSystem` wrapper, but their naming and destination rules are not identical.

## Local adapter

Use `local` when files live on the same server as your app.

```php
$fs = fs('local');
$fs->put(storage_dir() . '/notes.txt', 'Hello');
```

### What it supports well

The local adapter is the most complete adapter in the package. In addition to the shared filesystem methods, it also provides local-only operations such as:

* `glob()`
* `isReadable()`
* `isWritable()`
* `getLines()`
* `fileName()`
* `fileNameWithExtension()`
* `extension()`
* `require()` and `include()`

### Local adapter caveats

* `makeDirectory()` uses plain `mkdir($dirname)`, so it does not create nested directories for you
* `removeDirectory()` only removes empty directories
* `exists()` returns `true` only for files, not for directories
* `listDirectory()` returns resolved absolute paths, not raw child names

## Dropbox adapter

Use `dropbox` when your app should read and write files by Dropbox path.

```php
$fs = fs('dropbox');
$fs->put('exports/report.csv', $csv);
```

### Naming contract

Dropbox operations use path-like names such as `exports/report.csv`. The adapter normalizes them to Dropbox API paths with a leading slash.

### Behavior notes

* `put()` always uploads with overwrite mode
* `append()` is implemented as read-then-write, so it is not an atomic append operation
* `exists()` delegates to `isFile()`, so directory checks still require `isDirectory()`
* most adapter-level request errors come back as `false` instead of being rethrown directly

## Google Drive adapter

Use `gdrive` when files should live in Google Drive.

```php
$fs = fs('gdrive');
$fs->makeDirectory('Invoices');
```

### Naming contract

Google Drive is less path-oriented than Dropbox.

* `makeDirectory('Invoices')` creates a folder by name under `root` unless you pass a parent ID
* `put('invoice.pdf', $content, $parentId)` creates a new file by name under a parent folder ID
* if the first `put()` argument already matches an existing file ID, the adapter writes into that Drive file instead of creating a new one
* once a file exists, most later operations (`get()`, `rename()`, `remove()`, `copy()`, `isFile()`, `isDirectory()`) expect a Google Drive file or folder ID rather than a path

Treat that adapter as ID-based after creation.

### Behavior notes

* `copy($source, $dest)` copies a file ID into a destination folder ID, defaulting to `root`
* `append()` is also read-then-write rather than atomic
* `listDirectory($dirname)` expects a folder ID and returns the Drive API `files` list for that parent
* `UploadedFile::save()` is best reserved for path-style remote adapters; direct `fs('gdrive')->put(..., $parentId)` calls give you explicit Drive folder placement
* adapter-level request errors are returned as `false`

## Cloud auth requirements

Both cloud adapters depend on a token service class configured under `fs.<adapter>.service`.

That service must implement `Quantum\Storage\Contracts\TokenServiceInterface` so the package can:

* get the current access token
* get the refresh token
* save new tokens after the first OAuth exchange or an automatic refresh

When the configured service implements another interface, adapter resolution raises a storage exception before file operations begin.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://quantumphp.gitbook.io/docs/packages/storage/adapters.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
