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

Entity Laravel Package

bfg/entity

BFG Entity is a lightweight Laravel package for defining domain entities as plain PHP classes. It offers attribute handling, validation, and array/JSON serialization, helping keep business logic separate from Eloquent models while staying easy to integrate and test.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Install — composer require bfg/entity. Laravel ≥5.5 should auto-discover the service provider (Bfg\Entity\EntityServiceProvider); on older versions register it in config/app.php.

  2. Publish config and stubs — php artisan vendor:publish --provider="Bfg\Entity\EntityServiceProvider". You typically want the stub files so generated entities match your house style (strict_types, readonly, namespaces).

  3. Look first at — src/ for the base Entity class (the runtime contract) and the console command class (the $signature tells you every flag available). Then src/Stubs for the generated shape.

  4. First use case — scaffold a plain PHP entity and use it as a DTO between a repository/query layer and your controllers:

    php artisan make:entity User
    

    This generates something like app/Entities/UserEntity.php (namespace driven by config). Fill it with typed properties, and construct it from HTTP input instead of passing raw arrays around:

    $entity = new UserEntity();
    $entity->name = $request->validated('name');
    

If the command supports --table / --connection, generate from an existing schema so you get properties matching real columns. If not, the command is just a stub generator — treat it as such.

Implementation Patterns

DTO between layers. The main day-to-day pattern is: controller → service → repository → Entity. Your repository pulls DB/Eloquent rows and maps them into entities; the controller never sees an Eloquent model with hidden side effects.

final class UserRepository
{
    public function find(int $id): ?UserEntity
    {
        $row = DB::table('users')->find($id);
        return $row ? UserEntity::fromArray((array) $row) : null;
    }
}

Hydration from request. If the base class exposes fromArray() or similar, wire it into a FormRequest: entity construction becomes the single place where input is shaped and typed, so your service layer receives a real object, not a Request.

Bulk scaffolding. For a fresh project, generate entities for every table once, commit the result, and from then on hand-edit them. Entities are cheap to own — don't keep regenerating them as part of the normal workflow.

Pair with explicit casts. Since entities are likely plain POPOs (properties assigned in a constructor or magic __set), convert types in a mapper: CarbonImmutable::parse($row->created_at), (bool) $row->active, Status::from($row->status). This keeps entities honest and testable without a DB.

Integration points. Use entities as the source for toArray() in API responses, and for Validator::make($entity->toArray(), $rules) when you need to re-validate persisted data. Because they carry no Eloquent connection, they're trivial to construct in tests.

Gotchas and Tips

  • Maintenance risk. One star, zero dependents, low opportunity score. Read src/ end to end before adopting, pin the exact version in composer.json, and be prepared to fork or inline the stub + base class. The idea is sound; the codebase is small enough to own.
  • Overwrite-on-regenerate. Most generator commands overwrite existing files. Commit generated entities to git, and check for a --force flag before rerunning commands on a live project.
  • Namespace collisions. Don't generate into app/Models — you'll shadow Eloquent's make:model output and confuse Auth/Route model binding. Keep them in a distinct app/Entities namespace and register the PSR-4 mapping in composer.json; run composer dump-autoload after generating.
  • Multiple DB connections. If generating from a schema, pass --connection=... explicitly; the default may be mysql even when your tables live elsewhere.
  • Magic accessors. Base classes that rely on __get/__set typically return null for unknown props instead of throwing. Add __isset and an explicit toArray() on your subclasses, or prefer typed public properties and constructor assignment.
  • Mass-assignment semantics. If the entity supports fill(), define $fillable/$guarded-equivalent protection yourself — plain-PHP entities don't get Eloquent's protection for free.
  • Extension points. Publish the stubs, subclass the provided Entity base class, and override fromArray / toArray. Don't put business logic in the base class — if the package is abandoned, your entities should still work.
  • Debugging generation. Run the artisan command with -v and check --help for --pretend/--dry-run. If nothing is generated, verify the config output path and that the directory is writable.
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.
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core