11## Integration with Doctrine
22
3+ This guide covers integration with Doctrine DBAL 3.x/4.x and ORM 2.14+/3.x. For older versions, please refer to previous documentation versions.
34
4- * Register the DBAL types you plan to use *
5+ ### Register DBAL Types
56
6- Full set of the available types can be found [ here ] ( AVAILABLE-TYPES.md ) .
7+ Register the DBAL types you plan to use. The ** full set** of available types can be found in [ AVAILABLE-TYPES.md ] ( AVAILABLE-TYPES.md ) .
78
89``` php
910<?php
1011
1112use Doctrine\DBAL\Types\Type;
1213
14+ // Array types
1315Type::addType('bool[]', "MartinGeorgiev\\Doctrine\\DBAL\\Types\\BooleanArray");
1416Type::addType('smallint[]', "MartinGeorgiev\\Doctrine\\DBAL\\Types\\SmallIntArray");
1517Type::addType('integer[]', "MartinGeorgiev\\Doctrine\\DBAL\\Types\\IntegerArray");
1618Type::addType('bigint[]', "MartinGeorgiev\\Doctrine\\DBAL\\Types\\BigIntArray");
17-
1819Type::addType('double precision[]', "MartinGeorgiev\\Doctrine\\DBAL\\Types\\DoublePrecisionArray");
1920Type::addType('real[]', "MartinGeorgiev\\Doctrine\\DBAL\\Types\\RealArray");
20-
2121Type::addType('text[]', "MartinGeorgiev\\Doctrine\\DBAL\\Types\\TextArray");
22+
23+ // JSON types
2224Type::addType('jsonb', "MartinGeorgiev\\Doctrine\\DBAL\\Types\\Jsonb");
2325Type::addType('jsonb[]', "MartinGeorgiev\\Doctrine\\DBAL\\Types\\JsonbArray");
2426
27+ // Network types
2528Type::addType('cidr', "MartinGeorgiev\\Doctrine\\DBAL\\Types\\Cidr");
2629Type::addType('cidr[]', "MartinGeorgiev\\Doctrine\\DBAL\\Types\\CidrArray");
2730Type::addType('inet', "MartinGeorgiev\\Doctrine\\DBAL\\Types\\Inet");
2831Type::addType('inet[]', "MartinGeorgiev\\Doctrine\\DBAL\\Types\\InetArray");
2932Type::addType('macaddr', "MartinGeorgiev\\Doctrine\\DBAL\\Types\\Macaddr");
3033Type::addType('macaddr[]', "MartinGeorgiev\\Doctrine\\DBAL\\Types\\MacaddrArray");
3134
35+ // Spatial types
3236Type::addType('point', "MartinGeorgiev\\Doctrine\\DBAL\\Types\\Point");
3337Type::addType('point[]', "MartinGeorgiev\\Doctrine\\DBAL\\Types\\PointArray");
3438Type::addType('geometry', "MartinGeorgiev\\Doctrine\\DBAL\\Types\\Geometry");
3539Type::addType('geometry[]', "MartinGeorgiev\\Doctrine\\DBAL\\Types\\GeometryArray");
3640Type::addType('geography', "MartinGeorgiev\\Doctrine\\DBAL\\Types\\Geography");
3741Type::addType('geography[]', "MartinGeorgiev\\Doctrine\\DBAL\\Types\\GeographyArray");
3842
43+ // Range types
3944Type::addType('daterange', "MartinGeorgiev\\Doctrine\\DBAL\\Types\\DateRange");
4045Type::addType('int4range', "MartinGeorgiev\\Doctrine\\DBAL\\Types\\Int4Range");
4146Type::addType('int8range', "MartinGeorgiev\\Doctrine\\DBAL\\Types\\Int8Range");
@@ -45,9 +50,9 @@ Type::addType('tstzrange', "MartinGeorgiev\\Doctrine\\DBAL\\Types\\TstzRange");
4550```
4651
4752
48- * Register the functions you'll use in your DQL queries *
53+ ### Register DQL Functions
4954
50- Full set of the available functions and extra operators can be found in the [ Available Functions and Operators] ( AVAILABLE-FUNCTIONS-AND-OPERATORS.md ) documentation and its specialized sub-pages:
55+ Register the functions you'll use in your DQL queries. The full set of available functions and operators can be found in the [ Available Functions and Operators] ( AVAILABLE-FUNCTIONS-AND-OPERATORS.md ) documentation and its specialized sub-pages:
5156- [ Array and JSON Functions] ( ARRAY-AND-JSON-FUNCTIONS.md )
5257- [ PostGIS Spatial Functions] ( SPATIAL-FUNCTIONS-AND-OPERATORS.md )
5358- [ Text and Pattern Functions] ( TEXT-AND-PATTERN-FUNCTIONS.md )
@@ -189,7 +194,7 @@ $configuration->addCustomStringFunction('REGEXP', MartinGeorgiev\Doctrine\ORM\Qu
189194$configuration->addCustomStringFunction('IREGEXP', MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\IRegexp::class);
190195$configuration->addCustomStringFunction('NOT_REGEXP', MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\NotRegexp::class);
191196$configuration->addCustomStringFunction('NOT_IREGEXP', MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\NotIRegexp::class);
192- $configuration->addCustomStringFunction('REGEXP_LIKE', MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\FlaggedRegexpLike ::class);
197+ $configuration->addCustomStringFunction('REGEXP_LIKE', MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\RegexpLike ::class);
193198$configuration->addCustomStringFunction('REGEXP_COUNT', MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\RegexpCount::class);
194199$configuration->addCustomStringFunction('REGEXP_INSTR', MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\RegexpInstr::class);
195200$configuration->addCustomStringFunction('REGEXP_SUBSTR', MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\RegexpSubstr::class);
@@ -217,54 +222,102 @@ $configuration->addCustomStringFunction('TO_TIMESTAMP', MartinGeorgiev\Doctrine\
217222$em = EntityManager::create($dbParams, $configuration);
218223```
219224
220- * Then you need to register type mappings like below, based on [ documentation] ( https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/cookbook/custom-mapping-types.html ) *
225+ ### Register Platform Type Mappings
226+
227+ Register type mappings between PostgreSQL and Doctrine types. This is required for schema introspection and migrations. Based on the [ Doctrine documentation] ( https://www.doctrine-project.org/projects/doctrine-orm/en/current/cookbook/custom-mapping-types.html ) .
221228
222229``` php
230+ <?php
231+
223232$platform = $em->getConnection()->getDatabasePlatform();
224233
225- $platform->registerDoctrineTypeMapping('bool[]','bool[]');
226- $platform->registerDoctrineTypeMapping('_bool','bool[]');
227- $platform->registerDoctrineTypeMapping('smallint[]','smallint[]');
228- $platform->registerDoctrineTypeMapping('_int2','smallint[]');
229- $platform->registerDoctrineTypeMapping('integer[]','integer[]');
230- $platform->registerDoctrineTypeMapping('_int4','integer[]');
231- $platform->registerDoctrineTypeMapping('bigint[]','bigint[]');
232- $platform->registerDoctrineTypeMapping('_int8','bigint[]');
233-
234- $platform->registerDoctrineTypeMapping('double precision[]','double precision[]');
235- $platform->registerDoctrineTypeMapping('_float8','double precision[]');
236- $platform->registerDoctrineTypeMapping('real[]','real[]');
237- $platform->registerDoctrineTypeMapping('_float4','real[]');
238-
239- $platform->registerDoctrineTypeMapping('text[]','text[]');
240- $platform->registerDoctrineTypeMapping('_text','text[]');
241- $platform->registerDoctrineTypeMapping('jsonb','jsonb');
242- $platform->registerDoctrineTypeMapping('jsonb[]','jsonb[]');
243- $platform->registerDoctrineTypeMapping('_jsonb','jsonb[]');
244-
245- $platform->registerDoctrineTypeMapping('cidr[]','cidr[]');
246- $platform->registerDoctrineTypeMapping('_cidr','cidr[]');
247- $platform->registerDoctrineTypeMapping('inet[]','inet[]');
248- $platform->registerDoctrineTypeMapping('_inet','inet[]');
249- $platform->registerDoctrineTypeMapping('macaddr[]','macaddr[]');
250- $platform->registerDoctrineTypeMapping('_macaddr','macaddr[]');
251-
252- $platform->registerDoctrineTypeMapping('point','point');
253- $platform->registerDoctrineTypeMapping('point[]','point[]');
254- $platform->registerDoctrineTypeMapping('_point','point[]');
255- $platform->registerDoctrineTypeMapping('geometry','geometry');
256- $platform->registerDoctrineTypeMapping('geometry[]','geometry[]');
257- $platform->registerDoctrineTypeMapping('_geometry','geometry[]');
258- $platform->registerDoctrineTypeMapping('geography','geography');
259- $platform->registerDoctrineTypeMapping('geography[]','geography[]');
260- $platform->registerDoctrineTypeMapping('_geography','geography[]');
261-
262- $platform->registerDoctrineTypeMapping('daterange','daterange');
263- $platform->registerDoctrineTypeMapping('int4range','int4range');
264- $platform->registerDoctrineTypeMapping('int8range','int8range');
265- $platform->registerDoctrineTypeMapping('numrange','numrange');
266- $platform->registerDoctrineTypeMapping('tsrange','tsrange');
267- $platform->registerDoctrineTypeMapping('tstzrange','tstzrange');
268- ...
234+ // Array type mappings
235+ $platform->registerDoctrineTypeMapping('bool[]', 'bool[]');
236+ $platform->registerDoctrineTypeMapping('_bool', 'bool[]');
237+ $platform->registerDoctrineTypeMapping('smallint[]', 'smallint[]');
238+ $platform->registerDoctrineTypeMapping('_int2', 'smallint[]');
239+ $platform->registerDoctrineTypeMapping('integer[]', 'integer[]');
240+ $platform->registerDoctrineTypeMapping('_int4', 'integer[]');
241+ $platform->registerDoctrineTypeMapping('bigint[]', 'bigint[]');
242+ $platform->registerDoctrineTypeMapping('_int8', 'bigint[]');
243+ $platform->registerDoctrineTypeMapping('double precision[]', 'double precision[]');
244+ $platform->registerDoctrineTypeMapping('_float8', 'double precision[]');
245+ $platform->registerDoctrineTypeMapping('real[]', 'real[]');
246+ $platform->registerDoctrineTypeMapping('_float4', 'real[]');
247+ $platform->registerDoctrineTypeMapping('text[]', 'text[]');
248+ $platform->registerDoctrineTypeMapping('_text', 'text[]');
249+
250+ // JSON type mappings
251+ $platform->registerDoctrineTypeMapping('jsonb', 'jsonb');
252+ $platform->registerDoctrineTypeMapping('jsonb[]', 'jsonb[]');
253+ $platform->registerDoctrineTypeMapping('_jsonb', 'jsonb[]');
254+
255+ // Network type mappings
256+ $platform->registerDoctrineTypeMapping('cidr', 'cidr');
257+ $platform->registerDoctrineTypeMapping('cidr[]', 'cidr[]');
258+ $platform->registerDoctrineTypeMapping('_cidr', 'cidr[]');
259+ $platform->registerDoctrineTypeMapping('inet', 'inet');
260+ $platform->registerDoctrineTypeMapping('inet[]', 'inet[]');
261+ $platform->registerDoctrineTypeMapping('_inet', 'inet[]');
262+ $platform->registerDoctrineTypeMapping('macaddr', 'macaddr');
263+ $platform->registerDoctrineTypeMapping('macaddr[]', 'macaddr[]');
264+ $platform->registerDoctrineTypeMapping('_macaddr', 'macaddr[]');
265+
266+ // Spatial type mappings
267+ $platform->registerDoctrineTypeMapping('point', 'point');
268+ $platform->registerDoctrineTypeMapping('point[]', 'point[]');
269+ $platform->registerDoctrineTypeMapping('_point', 'point[]');
270+ $platform->registerDoctrineTypeMapping('geometry', 'geometry');
271+ $platform->registerDoctrineTypeMapping('geometry[]', 'geometry[]');
272+ $platform->registerDoctrineTypeMapping('_geometry', 'geometry[]');
273+ $platform->registerDoctrineTypeMapping('geography', 'geography');
274+ $platform->registerDoctrineTypeMapping('geography[]', 'geography[]');
275+ $platform->registerDoctrineTypeMapping('_geography', 'geography[]');
276+
277+ // Range type mappings
278+ $platform->registerDoctrineTypeMapping('daterange', 'daterange');
279+ $platform->registerDoctrineTypeMapping('int4range', 'int4range');
280+ $platform->registerDoctrineTypeMapping('int8range', 'int8range');
281+ $platform->registerDoctrineTypeMapping('numrange', 'numrange');
282+ $platform->registerDoctrineTypeMapping('tsrange', 'tsrange');
283+ $platform->registerDoctrineTypeMapping('tstzrange', 'tstzrange');
284+ ```
285+
286+ ### Usage in Entities
287+
288+ Once types are registered, you can use them in your Doctrine entities:
289+
290+ ``` php
291+ <?php
292+
293+ use Doctrine\ORM\Mapping as ORM;
294+ use MartinGeorgiev\Doctrine\DBAL\Types\ValueObject\DateRange;
295+ use MartinGeorgiev\Doctrine\DBAL\Types\ValueObject\NumericRange;
296+ use MartinGeorgiev\Doctrine\DBAL\Types\ValueObject\Point;
297+ use MartinGeorgiev\Doctrine\DBAL\Types\ValueObject\WktSpatialData;
298+
299+ #[ORM\Entity]
300+ class MyEntity
301+ {
302+ #[ORM\Column(type: 'jsonb')]
303+ private array $metadata = [];
304+
305+ #[ORM\Column(type: 'text[]')]
306+ private array $tags = [];
307+
308+ #[ORM\Column(type: 'point')]
309+ private Point $location;
310+
311+ #[ORM\Column(type: 'geometry')]
312+ private WktSpatialData $shape;
313+
314+ #[ORM\Column(type: 'numrange')]
315+ private NumericRange $priceRange;
316+
317+ #[ORM\Column(type: 'daterange')]
318+ private DateRange $validPeriod;
269319
320+ #[ORM\Column(type: 'inet')]
321+ private string $ipAddress;
322+ }
270323```
0 commit comments