PHPackages                             amadul/json-object - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. amadul/json-object

ActiveLibrary[Database &amp; ORM](/categories/database)

amadul/json-object
==================

Structured, castable, schema-aware JSON objects for Eloquent models

v1.0.3(3mo ago)91MITPHPPHP ^8.2

Since Jan 13Pushed 3mo agoCompare

[ Source](https://github.com/AmadulHaque/json-object)[ Packagist](https://packagist.org/packages/amadul/json-object)[ RSS](/packages/amadul-json-object/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (4)Dependencies (7)Versions (4)Used By (0)

Laravel JSON Object Toolkit
===========================

[](#laravel-json-object-toolkit)

[![Latest Version on Packagist](https://camo.githubusercontent.com/69c007f64752acb96e7bc2adea7ab9ca65f621a106eb851ba3434ec9efc59c97/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f616d6164756c2f6a736f6e2d6f626a6563742e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/amadul/json-object)[![Total Downloads](https://camo.githubusercontent.com/e83e204cd43b348444fa06a75597540c6446ba6e128df7412a7281c874f297b7/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f616d6164756c2f6a736f6e2d6f626a6563742e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/amadul/json-object)[![License](https://camo.githubusercontent.com/164197879a7ebea3bb3fcb43011db21f6f46458832625a0273c9846d6a163782/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f616d6164756c2f6a736f6e2d6f626a6563742e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/amadul/json-object)

**Structured, castable, schema-aware JSON objects for Eloquent models.**

Transform your Eloquent JSON columns from messy arrays into strongly-typed, validated, and behavior-rich objects.

🚀 Features
----------

[](#-features)

- **🛡️ Strongly Typed**: Define classes for your JSON structures.
- **🔄 Eloquent Casting**: Seamless integration (feels like native attributes).
- **✅ Validation**: Built-in Laravel validation logic.
- **🔍 Dirty Tracking**: Know exactly what changed inside the JSON.
- **📝 Logging**: Track modifications automatically.
- **🔌 Extensible**: Plugin architecture via Macros.
- **⚡ Artisan Integration**: `make:json` command for rapid development.

---

📦 Installation
--------------

[](#-installation)

1. **Require the package** via Composer:

    ```
    composer require amadul/json-object
    ```
2. **Publish the configuration** (Optional):

    ```
    php artisan vendor:publish --tag=json-object-config
    ```

    This creates `config/json-object.php` where you can customize paths and global feature flags.

---

🛠️ Full Implementation Guide: Step-by-Step
------------------------------------------

[](#️-full-implementation-guide-step-by-step)

Let's build a real-world example: **Product Attributes** for an E-commerce system. We want to store `color`, `size`, and `metadata` in a single JSON column but interact with them like structured data.

### Step 1: Create the JSON Object Class

[](#step-1-create-the-json-object-class)

Use the Artisan command to scaffold your class.

```
php artisan make:json ProductAttributes
```

This creates `app/Json/ProductAttributes.php`.

### Step 2: Define Structure &amp; Behavior

[](#step-2-define-structure--behavior)

Open the generated file. We will:

1. Define the **Schema** (allowed fields).
2. Define **Casts** (data types).
3. Add **Traits** for extra power (Accessors, Validation, Dirty Tracking).

```
namespace App\Json;

use Amadul\JsonObject\JsonObject;
use Amadul\JsonObject\Concerns\HasAccessors;
use Amadul\JsonObject\Concerns\HasValidation;
use Amadul\JsonObject\Concerns\TracksDirtyAttributes;
use Amadul\JsonObject\Concerns\HasLogging;
use Amadul\JsonObject\Contracts\ValidatesJson;

class ProductAttributes extends JsonObject implements ValidatesJson
{
    // 1. Add Capabilities
    use HasAccessors,
        HasValidation,
        TracksDirtyAttributes,
        HasLogging;

    /**
     * The whitelist of allowed attributes.
     * Any key not here will be filtered out on construction.
     */
    protected array $schema = [
        'color',
        'size',
        'sku',
        'tags',
        'metadata.manufactured_at',
    ];

    /**
     * Type casting for specific attributes.
     */
    protected array $casts = [
        'size' => 'integer',
        'tags' => 'array',
        'metadata.manufactured_at' => 'datetime', // Custom casting can be added
    ];

    /**
     * Validation rules using standard Laravel syntax.
     */
    public function rules(): array
    {
        return [
            'color' => 'required|string|in:red,blue,green',
            'size' => 'required|integer|min:0',
            'sku' => 'required|alpha_dash',
        ];
    }
}
```

### Step 3: Integrate with Eloquent Model

[](#step-3-integrate-with-eloquent-model)

Open your `Product` model and cast the column (e.g., `attributes` or `data`) to your new class.

```
namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use App\Json\ProductAttributes;

class Product extends Model
{
    protected $fillable = ['name', 'attributes'];

    protected $casts = [
        'attributes' => ProductAttributes::class,
    ];
}
```

### Step 4: Usage in Application

[](#step-4-usage-in-application)

Now you can use it in your Controllers, Services, or Jobs.

#### Creating &amp; Saving

[](#creating--saving)

```
$product = new Product();
$product->name = 'T-Shirt';

// Initialize with array
$product->attributes = [
    'color' => 'red',
    'size' => '42', // Will be cast to int 42
    'sku' => 'TS-RED-42'
];

// Validate before saving (Optional but recommended)
try {
    $product->attributes->validate();
} catch (\Illuminate\Validation\ValidationException $e) {
    // Handle errors
}

$product->save();
```

#### Reading &amp; Modifying

[](#reading--modifying)

```
$product = Product::find(1);

// Access with Dot Notation (via HasAccessors)
echo $product->attributes->get('color'); // "red"
echo $product->attributes->get('metadata.manufactured_at');

// Modify values
$product->attributes->set('color', 'blue');

// Check dirty state (via TracksDirtyAttributes)
if ($product->attributes->dirty()) {
    // Returns ['color' => 'blue']
    // Log is automatically triggered if HasLogging is enabled
}

$product->save(); // Eloquent handles serialization automatically
```

---

📚 Deep Dive: Core Concepts
--------------------------

[](#-deep-dive-core-concepts)

### Schema Whitelisting

[](#schema-whitelisting)

By defining `protected $schema`, you ensure strictly structured JSON. Any data passed to the constructor that isn't in the schema is discarded. This prevents "JSON pollution" with random keys.

### Type Casting

[](#type-casting)

The `$casts` property works similarly to Eloquent casts but for internal JSON keys. Supported types: `int`, `integer`, `float`, `real`, `double`, `string`, `bool`, `boolean`, `array`.

### Nested JSON Objects

[](#nested-json-objects)

You can cast attributes to other `JsonObject` classes, allowing for deep, structured JSON hierarchies.

```
// App/Json/ProductMeta.php
class ProductMeta extends JsonObject
{
    protected $schema = ['author', 'year'];
}

// App/Json/ProductAttributes.php
class ProductAttributes extends JsonObject
{
    protected $casts = [
        'meta' => ProductMeta::class, // Nested casting
    ];
}

// Usage
$product->attributes = [
    'color' => 'red',
    'meta' => [
        'author' => 'John Doe',
        'year' => 2023
    ]
];

// Accessing nested objects
echo $product->attributes->get('meta')->get('author'); // "John Doe"
echo $product->attributes->get('meta.author'); // "John Doe" (via dot notation support)
```

### Validation

[](#validation)

Implement `ValidatesJson` and define `rules()`. Call `$object->validate()` anywhere. It uses Laravel's `Validator` under the hood, so all standard rules work.

### Dirty Tracking

[](#dirty-tracking)

Include `TracksDirtyAttributes`.

- `dirty()`: Returns array of changed keys and new values.
- `syncOriginal()`: Called automatically on fetch, resets the baseline.

### Logging

[](#logging)

Include `HasLogging`. Configure the channel in `config/json-object.php`. Use `$this->log('message', ['data'])` inside your JSON object methods to create audit trails of attribute changes.

---

🔌 Advanced: Plugins &amp; Extensibility
---------------------------------------

[](#-advanced-plugins--extensibility)

The `JsonObject` class is `Macroable`. You can add methods at runtime, which is perfect for plugins or app-wide extensions.

**Example: Add an `approve()` method to all JSON objects.**

```
// AppServiceProvider.php
use Amadul\JsonObject\JsonObject;

public function boot()
{
    JsonObject::macro('approve', function () {
        $this->set('status', 'approved');
        $this->set('approved_at', now()->toIso8601String());
        return $this;
    });
}

// Usage
$product->attributes->approve();
```

---

⚙️ Configuration
----------------

[](#️-configuration)

`config/json-object.php`

KeyDescriptionDefault`path`Directory for generated classes`app_path('Json')``namespace`Namespace for generated classes`App\Json``features.validation`Enable/Disable validation trait helpers`true``features.dirty_tracking`Enable/Disable dirty tracking`true``features.logging`Global logging toggle`false``log_channel`Laravel log channel to use`stack`---

🧪 Testing Your JSON Objects
---------------------------

[](#-testing-your-json-objects)

Since these are standard PHP classes, unit testing is straightforward.

```
use App\Json\ProductAttributes;

it('validates product attributes', function () {
    $attr = ProductAttributes::from(['color' => 'invalid-color']);

    expect(fn() => $attr->validate())
        ->toThrow(\Illuminate\Validation\ValidationException::class);
});

it('casts size to integer', function () {
    $attr = ProductAttributes::from(['size' => '42']);
    expect($attr->get('size'))->toBe(42);
});
```

---

🤝 Contributing
--------------

[](#-contributing)

1. Fork the repo.
2. Create your feature branch (`git checkout -b feature/amazing-feature`).
3. Commit your changes (`git commit -m 'Add amazing feature'`).
4. Push to the branch (`git push origin feature/amazing-feature`).
5. Open a Pull Request.

---

📄 License
---------

[](#-license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

37

—

LowBetter than 83% of packages

Maintenance78

Regular maintenance activity

Popularity7

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity49

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~3 days

Total

3

Last Release

119d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/30a70d3f849243fd6b5ea624e533f1a6aa275bcb561195f8f84c082983e77dab?d=identicon)[AmadulHaque](/maintainers/AmadulHaque)

---

Top Contributors

[![AmadulHaque](https://avatars.githubusercontent.com/u/92516695?v=4)](https://github.com/AmadulHaque "AmadulHaque (6 commits)")

###  Code Quality

TestsPest

### Embed Badge

![Health badge](/badges/amadul-json-object/health.svg)

```
[![Health](https://phpackages.com/badges/amadul-json-object/health.svg)](https://phpackages.com/packages/amadul-json-object)
```

###  Alternatives

[tucker-eric/eloquentfilter

An Eloquent way to filter Eloquent Models

1.8k4.8M26](/packages/tucker-eric-eloquentfilter)[clickbar/laravel-magellan

This package provides functionality for working with the postgis extension in Laravel.

423715.4k1](/packages/clickbar-laravel-magellan)[watson/validating

Eloquent model validating trait.

9723.3M47](/packages/watson-validating)[reedware/laravel-relation-joins

Adds the ability to join on a relationship by name.

2121.2M13](/packages/reedware-laravel-relation-joins)[cybercog/laravel-clickhouse

ClickHouse migrations for Laravel

163166.8k](/packages/cybercog-laravel-clickhouse)[aedart/athenaeum

Athenaeum is a mono repository; a collection of various PHP packages

245.2k](/packages/aedart-athenaeum)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
