Skip to content

Consistency audits ​

FileMagic can compare stored-file database records with their Laravel Filesystem objects:

bash
php artisan file-magic:audit

The command checks only from the database toward storage:

  • a successful exists() result is healthy;
  • false means the object is missing;
  • an exception means the state is unknown, so the record is preserved.

It does not list storage, find objects without database records, delete physical objects, or recreate missing objects.

Read-only audit ​

The default mode does not change the database or storage:

bash
php artisan file-magic:audit
php artisan file-magic:audit --disk=s3
php artisan file-magic:audit --chunk=250
OptionType and defaultBehavior
--disk?non-empty-string, default nullAudit exactly one disk configured in filesystems.disks; omit it to audit all records
--chunkint<1, 5000>, default 500Number of database records loaded per batch
--delete-missing-recordsBoolean flag, default falseDelete database records whose objects are confirmed missing
--forceBoolean flag, default falseSkip confirmation in cleanup mode; using it alone exits with code 2

Invalid option values exit with code 2 before scanning or changing data. The command uses the configured FileMagic model, connection, table, and primary key. It checks records even when the model has global scopes, so use --disk when the audit must be narrowed.

Each missing finding shows only its database key, disk, and storage-relative path. The final summary includes checked, healthy, missing, deleted, and failed.

Cleaning missing records ​

To remove database records whose storage objects are confirmed missing:

bash
php artisan file-magic:audit --delete-missing-records

Interactive execution asks for confirmation before scanning. Declining exits without scanning or changing data. Non-interactive environments must explicitly accept the risk:

bash
php artisan file-magic:audit --delete-missing-records --force --no-interaction

--force is invalid without --delete-missing-records. Storage checks that throw exceptions remain unknown and their records are never deleted.

Cleanup reloads initially missing records and checks their storage objects again. When locking is enabled, both steps run under the path locks. Only an unchanged record whose object is still missing is deleted.

A reappeared object is retained as healthy. A record already removed is skipped and does not count as deleted. A changed disk, path, or location identity, or an unknown storage state, preserves the record and counts as failed.

Cleanup does not dispatch each model's Eloquent deleting or deleted events. Do not use cleanup when your application requires those events for each removed record.

Cost, performance, and consistency ​

The audit performs one storage existence check for every selected database record. On S3 and other remote disks, these checks can add network latency and billable request charges.

--chunk controls database query size and PHP memory use only. It does not reduce the number of storage requests. Cleanup adds a second existence check for initially missing records whose identity is unchanged. Use --disk to limit scope, choose an appropriate chunk size, and avoid running the command more often than the application needs.

Read-only results are point-in-time observations, not atomic snapshots shared with storage. Lock-enabled cleanup closes the FileMagic store/delete race by revalidating under the shared path lock, but direct model deletion, external storage writers, different cache backends, and operations that exceed the lease remain outside that guarantee.

Storage, network, adapter, and permission exceptions are reported as unknown failures rather than missing objects. They produce exit code 2 and preserve the affected records.

Cleanup is not all-or-nothing. If a database error occurs, the command stops with exit code 2, but records handled earlier may already be deleted. The command never deletes storage objects.

Exit codes ​

CodeMeaning
0Audit completed with no missing records, cleanup completed, or the user cancelled cleanup
1The read-only audit completed and missing records remain
2Invalid input, an unknown storage state, a database failure, or partial cleanup

Use --quiet when automation needs only the exit code.

Scheduling ​

FileMagic does not schedule audits automatically. A Laravel application can add one explicitly:

php
use Illuminate\Support\Facades\Schedule;

Schedule::command('file-magic:audit --disk=s3')
    ->daily()
    ->withoutOverlapping();

Use withoutOverlapping() because remote audits can run longer than expected. On multi-server deployments, consider onOneServer() with a shared cache driver. Select the frequency only after accounting for the record count, remote request latency, and provider charges.

Last updated:

Released under the MIT License.