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

Doctrine Json Bundle Laravel Package

webit/doctrine-json-bundle

Webit Doctrine JSON Bundle adds JSON column support to Doctrine in Symfony applications. It provides custom DBAL types and query helpers so you can store, retrieve, and query structured JSON data directly from your entities with minimal configuration.

View on GitHub
Deep Wiki
Context7

Getting Started

The package is a Symfony bundle, not a Laravel package — there is no service provider, no config/doctrine-json.php, and no auto-discovery. The first thing to check is whether you actually need it: Doctrine DBAL has shipped a native json type since 2.6, so this bundle's value is (a) backfilling the type on very old DBAL versions and (b) registering DQL functions for querying inside JSON documents.

  1. Install: composer require webit/doctrine-json-bundle
  2. Open vendor/webit/doctrine-json-bundle/ and read src/ first — it is small enough to audit in one sitting. Identify two things: the DBAL type class (usually extends Doctrine\DBAL\Types\JsonType or Type) and the list of custom DQL function classes (typically JSON_CONTAINS, JSON_EXTRACT, JSON_UNQUOTE, JSON_LENGTH).
  3. Symfony: register Webit\DoctrineJsonBundle\WebitDoctrineJsonBundle in config/bundles.php.
  4. Laravel (the mismatch you'll hit immediately): wire it manually in a service provider:
// AppServiceProvider::boot()
use Doctrine\DBAL\Types\Type;
use Doctrine\ORM\EntityManagerInterface;

public function boot(EntityManagerInterface $em)
{
    if (! Type::hasType('json')) {
        Type::addType('json', \Webit\DoctrineJsonBundle\DBAL\Types\JsonType::class);
    }
    $config = $em->getConfiguration();
    $config->addCustomStringFunction('JSON_CONTAINS', \Webit\...\JsonContains::class);
}
  1. First real use case: an entity with a JSON column mapped as type="json" and a property typed as array. Persist an array, read it back — that's the smoke test.
/** @ORM\Column(type="json") */
private array $attributes = [];

Implementation Patterns

Entity mapping. Map the column as json and let the type do the array⇄string conversion. Use nullable=true if you expect docs without the payload, and always initialize to [] so PHP doesn't hand null to an array typed property.

Querying inside the document. The main reason to pull this bundle in is the DQL functions. Typical repository pattern:

$qb->select('p')
   ->from(Product::class, 'p')
   ->where("JSON_CONTAINS(p.attributes, :tag) = 1")
   ->setParameter('tag', json_encode('clearance'));

Read-modify-write. Since Doctrine sees the whole column as one scalar, mutating a nested key requires fetching, $entity->setAttributes([...$attrs, 'k' => $v]), and flushing. Wrap that in a domain method on the entity, not in the controller.

Hybrid pattern for reporting. Use DQL functions for simple predicates, but drop to $em->getConnection()->executeQuery() with native SQL when you need JSON_TABLE, generated columns, or multi-path JSON_EXTRACT in ORDER BY. Mapping the result with ResultSetMapping keeps it honest.

Schema. The bundle doesn't add indexes. If you query JSON paths frequently, add generated columns and indexes by hand in a migration; otherwise these queries table-scan.

Gotchas and Tips

  • It's Symfony-only and effectively unmaintained (1 star, 0 dependents). Expect no PHP 8.2+ / DBAL 3.x compatibility fixes. Pin your DBAL and Doctrine ORM versions and re-test on every upgrade.
  • DBAL 3+ already has json. Adding the type again will either duplicate quietly or throw "type already exists" depending on your guard — check Type::hasType('json') before addType.
  • Hydration surprises with DQL functions. JSON_EXTRACT(...) selected in a DQL SELECT comes back as a raw string, not an array. Decode in PHP or wrap with JSON_UNQUOTE only when you genuinely want a scalar.
  • MySQL vs MariaDB. MariaDB's JSON is an alias for LONGTEXT with a check constraint; some functions (e.g. JSON_TABLE, JSON_OVERLAPS) are missing or behave differently. Test against your actual engine, not just mysql.
  • JSON_CONTAINS needs valid JSON. Passing a raw PHP string ('clearance') fails — pass json_encode($value), or '"clearance"' if it's a JSON string literal. This is the most common silent bug: the function returns 0 instead of erroring.
  • Charset/collation. JSON_UNQUOTE output inherits the connection collation, so WHERE JSON_UNQUOTE(p.attributes->'$.sku') = :sku can miss matches under utf8mb4_general_ci vs utf8mb4_0900_ai_ci.
  • No Laravel tooling. No commands, no config, no migrations, no factories. Budget the manual wiring above.
  • Extension point if you must patch it. Fork and replace the Type class with your own that implements JsonSerializable-aware conversion, then register yours instead — don't subclass the bundle's type, since the parent may break on DBAL bumps.
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.
gmostafa/php-graphql-client
xeviant/paystack
snowsoft/faker
meditationsteps/blogetc
animalyoung/laravel-influxdb
onix-solutions/sms-telera
lonely-lights/prosetta
oxygen/data
oxygen/core
jengo/base
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin
artisan-build/community-prompts
vleroy/smart
ayles-software/laravel-australian-public-holidays
cboxdk/laravel-id-spatie
cboxdk/laravel-id-billing
cboxdk/laravel-id-billing-bridge
simple-as-fuck/php-performance-log