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

Laravel Dataobject Laravel Package

czim/laravel-dataobject

Lightweight data objects for Laravel: define typed properties, hydrate instances from arrays, and convert them back to arrays or JSON. A simple way to keep request, config, and domain data structured, consistent, and easy to pass around with minimal boilerplate.

View on GitHub
Deep Wiki
Context7

Getting Started

Install the package via Composer — it's a small, dependency-light library that auto-registers its service provider through Laravel's package discovery:

composer require czim/laravel-dataobject

There is generally no config file to publish; the package is designed to be dropped in and extended. Start by reading the base class (Czim\DataObject\DataObject or the associated interface) — the entire surface area is small, so a 10-minute skim of the source tells you more than the README.

Your first use case should be a DTO for a request → service → response flow. Create a class like:

use Czim\DataObject\DataObject;

class CustomerData extends DataObject
{
    protected $attributes = [
        'name' => null,
        'email' => null,
        'phone' => null,
    ];
}

Then hydrate it from a request and read it back:

$data = new CustomerData($request->only(['name', 'email', 'phone']));

return response()->json($data->toArray());

That is the sweet spot: replacing loose associative arrays that get passed between controllers, services, and jobs with a named, predictable object.

Implementation Patterns

Hydration from requests. Pass $request->validated() or $request->only([...]) into the constructor or a fill() method. This gives you a single boundary where incoming data becomes a typed-shaped object. Combine it with Form Requests so validation happens before the DataObject is instantiated.

Explicit schema as a contract. The $attributes (or equivalent property) declaration doubles as documentation. For teams, treat this as an interface: if it isn't in $attributes, it doesn't exist. This keeps DTOs honest and prevents "just add a field" drift.

Serialization back out. Use toArray() / toJson() at the edges — API responses, queued job payloads, cache values. This is where DataObjects earn their keep versus plain arrays, because the shape is defined in one class rather than scattered across serializers.

Composition over inheritance. For nested structures, embed one DataObject inside another's attributes rather than flattening everything. When serializing, ensure the parent's toArray() recurses (most implementations will call jsonSerialize() on nested objects, so wrapping is usually free).

Integration with Eloquent. Prefer a factory/static constructor pattern:

$data = CustomerData::fromModel($customer);
$customer->fill($data->toArray());

Keep the mapping explicit. Don't try to make DataObject a drop-in replacement for models — it lacks queries, relations, and events, and forcing that abstraction creates more complexity than it removes.

Boundary objects for third-party APIs. This is arguably the strongest pattern for this package. Wrap an external API's response in a DataObject so the rest of your app deals with your shape, not theirs. If the vendor renames a field, you change one fromApiResponse() method.

Use it in queued jobs and events. Job payloads become stable and self-describing. Because they cast cleanly to arrays and JSON, Laravel's queue serialization just works — no special handling needed.

Gotchas and Tips

It is a thin library with low adoption (11 stars). This is not a risk on its own — it's MIT and readable — but it means fewer Stack Overflow answers, no vibrant community, and you should assume you are the maintainer if a Laravel/PHP upgrade breaks it. Budget for this. Pin the version in composer.json and consider vendoring or forking if the project matters long-term.

Magic properties hide typos. If the class relies on __get/__set (common in DTO packages of this era), a typo like $data->emial silently returns null instead of throwing. Mitigate by adding explicit accessor methods or typed getters on your subclasses; don't rely on magic for anything more than trivial passthrough.

Untyped attributes mean untyped data. Since attributes are typically declared as an array of defaults, PHP won't enforce string vs. int vs. Carbon. If your DataObject holds dates or enums, cast them on construction ($this->created_at = Carbon::parse(...)) rather than hoping callers pass the right type. Consider overriding the setter or adding a normalization step in the constructor.

Attribute whitelisting. Most implementations of this pattern ignore unknown keys during fill() to avoid injection of unexpected properties. That is a feature, not a bug — but it means silently dropped fields when you add a key upstream without updating $attributes. When debugging "my field is empty," check the whitelist first.

No validation baked in. If you expected this package to validate like a Form Request, it doesn't. Wrap it: use Form Requests for web input, and add explicit validate() helpers or Laravel's Validator::make() on the DataObject if you need defense in depth inside services.

Serialization differences across contexts. toArray() and jsonSerialize() may behave differently around nulls, nested objects, and empty arrays. If you're producing an API contract, write a test asserting the exact JSON shape. Small package, small surprises — but tests protect you if the implementation changes on an upgrade.

PHP version constraints. Older czim packages often target PHP 7.x. Check composer.json's require block before adding to a modern PHP 8.2+ project — you may need to fork and bump the constraint. This is the single most common blocker for packages at this star level.

Debugging tip. Since the class is small, add a dd($this->attributes) in the constructor when data doesn't behave as expected. There's no deep debugging story here — read the source, it's the fastest path.

When not to use it. For anything needing relations, change tracking, events, or querying, use Eloquent. For simple two-field payloads, a plain array or readonly class is clearer. The DataObject shines at roughly 5–20 fields crossing one or two boundaries — outside that window, its cost/benefit shifts.

Extension points to look at. Before writing your own base class, check whether the package ships traits (e.g., for casting, array access, or serialization). Extending a trait-based layer is often cleaner than fighting the base class's assumptions. If the traits are there, compose them — that's why they exist.

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.
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator