Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Foggy Laravel Package

worksome/foggy

Worksome Foggy is a Laravel package for anonymizing sensitive model data. Configure which attributes should be fogged, and Foggy replaces them with realistic fake values so you can safely use production-like data in local and staging environments.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Install as a dev dependency. composer require worksome/foggy --dev. It is a development/CI tool, not something that should be present in a production autoload path if you can avoid it.
  2. Publish the config. Run php artisan vendor:publish --provider="Worksome\Foggy\FoggyServiceProvider" (or --tag=foggy-config) and open config/foggy.php. This file — not the source — is where 90% of your work happens.
  3. Discover the commands. Foggy is small, so its surface is small. Run php artisan list | grep foggy and php artisan help <command> before reading the README; the exact verb (foggy:dump, foggy:export, etc.) and flags are the fastest thing to confirm against your installed version rather than trusting a blog post.
  4. Start with one table. Pick the single most sensitive table in your app (almost always users: emails, names, phone numbers, password hashes, remember tokens). Add a rule that replaces those columns, point Foggy at a local database, and inspect the output with mysql/psql before you touch anything else.
  5. First real use case: producing a dump you can hand to a contractor, load into a shared staging environment, or attach to a bug report — without leaking customer data and without breaking relationships in the process.

Implementation Patterns

Default-deny on sensitive tables. Configure an explicit allowlist of tables to include (or a denylist of framework noise like jobs, failed_jobs, cache, sessions, telescope_*). Anything not explicitly handled should be excluded, not passed through — the failure mode of a sanitizer is silent leakage.

Column rules as the unit of work. For each included table, describe per-column behavior: drop the column, replace with a constant, replace with a generated fake value, or hash the original. Keep primary keys and foreign keys intact unless you are deliberately re-keying everything.

Keep referential integrity with deterministic hashing. If users.email is hashed, hash it with a fixed application secret so the same input always maps to the same output. Do the same for any column joined across tables. Random fakers break joins; deterministic transforms don't.

Preserve reference data verbatim. Countries, currencies, permission names, plan definitions — copy these tables untouched. Sanitizing them creates a database that looks fine but behaves differently from production, which defeats the point of staging.

Profile by environment. Keep a local profile that scrubs less (you often want your own account intact to log in and debug) and a staging/shared profile that scrubs aggressively. Drive the profile from an env var so the same command works in both places.

Custom transformers for domain types. When you have a value object, an encrypted cast, or a JSON blob with embedded PII, write a small transformer class implementing the package's contract and register it in the config. This is the intended extension point and keeps application-specific logic out of the config file.

Wire it into a dump/restore script, not into your head. Put the command behind a Composer script or a Makefile target (make dump-scrubbed), so nobody on the team ever runs a raw mysqldump "just this once." In CI, run it after your test suite against a seeded database to catch config drift when migrations add new columns.

Review the config in code review. Any migration that adds a users column should come with a diff to config/foggy.php. Add a note to your PR template; this is the only durable defense against a new PII column slipping through.

Gotchas and Tips

  • New columns leak by default. If Foggy works on allowlisted columns, a freshly added users.iban is dumped in the clear until someone remembers. Prefer table-level drop-and-rebuild semantics where possible, and add a test that asserts a known sentinel value is absent from the output.
  • Foreign keys and unique indexes. Replacing an email with a random value can violate a unique constraint mid-dump. Deterministic transforms on the original value solve this cheaply; if you must use random data, derive it from the row's primary key.
  • Self-referential and polymorphic relations. parent_id chains and commentable_type/commentable_id pairs break the moment you renumber IDs. Either keep IDs stable or don't touch IDs at all.
  • Config caching bites in deploy scripts. php artisan config:cache on a machine that then runs a dump will use the cached, possibly production-profile config. Clear the cache in your dump script and assert the profile at runtime.
  • Guard against production. Add a hard check: if app()->environment('production') and no explicit override flag is set, abort. A sanitizer pointed at the wrong DSN is worse than no sanitizer, because people trust it.
  • Large tables and memory. Dumps are streamed by the underlying database tool; any in-PHP transformation step may not be. Test on a copy of a real-sized table early — a transformation that works on 100 rows can OOM on 5 million.
  • JSON, encrypted casts, and serialized columns need custom handling. A naive string replace inside a JSON document corrupts it. Decode → transform → re-encode, or drop the whole column if it isn't needed downstream.
  • Binary and blob columns (avatars, documents, logs) should generally be dropped entirely rather than transformed; they bloat dumps and rarely carry value in staging.
  • Debugging: run the command at maximum verbosity, dump the generated SQL to a file rather than piping it into a database, and diff a scrubbed row against the original for a single known record. If output looks untouched, it's almost always a config key mismatch or a table silently excluded by the allowlist — verify the config is actually loaded with php artisan tinker before reading package source.
  • Maturity risk. With a low star count and a long gap between releases, pin the exact version in composer.json, read the changelog on every bump, and expect to read the source when something is off. Keep a thin wrapper (your own Artisan command or script) around Foggy's command so a breaking upstream change is a one-file fix rather than a search across the team's shell history.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect