Doctrine array vs simple_array vs json_array
For your problem simple_array
is the right way, the right way may also create seven boolean fields.
However here's a little vademecum:
The best way to see how a type works in doctrine is to read the code of the type, this is because there are several details that are taken for granted or are not really explained in the documentation.
So you can go into
/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/Type.php
find your type and check if its methods work as you want.
Here some details:
simple_array
in /vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/SimpleArrayType.php
return implode(',', $value);
it's just a implode()
/explode()
of items, stores only the values and it's useful because you can easily query the database.
array
in /vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/ArrayType.php
return serialize($value);
calls PHP to serialize()
/unserialize()
, it's faster than json_array
. Looking at the code I think it also works with objects. Obviously if you see the field as plain text it's uncomprensible.
json_array
in /vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/JsonArrayType.php
return json_encode($value);
it calls json_encode()
/json_decode()
, if you look in the field you can see a unformatted JSON array but it's more readable than PHP's serialized object and is really more portable (JSON exists everywhere).
June 2018 update
- now there is a complete and more updated documentation here
- json_array is deprecated in favor of json type, it will leverage on new database features for json fields
Another consideration: The most efficient way to represent a small set of true/false values like the ones presented here would be a bitfield.
That way you're only storing one integer instead of a full string. And you avoid the encode/decode overhead.
See https://stackoverflow.com/a/5412214/827254 for a good example.
The best solution for your problem, as stated, would be to use an array mapping of type array
or json_array
but not simple_array
. The reason is that the serialization method of simple_array
is just a call to implode(',', $array)
and that would retain only the values and not the keys of the array, thus invalid for your situation where you have an associative array.
However, you could also model your $days
attribute as a 0-based array (i.e. monday would be zero, tuesday would be 1, etc.). In that case, it would work because the deserializing with explode(',', $serialized);
generates a 0-based array with the serialised values.
According to the Documentation:
Doctrine ORM > Basic Mapping > Doctrine Mapping Types
You have 3 choices regaring array data:
array
Type that maps a SQL CLOB to a PHP array usingserialize()
andunserialize()
.simple_array
Type that maps a SQL CLOB to a PHP array usingimplode()
andexplode()
, with a comma as delimiter.IMPORTANT: Only use this type if you are sure that your values cannot contain a
,
.json_array
Type that maps a SQL CLOB to a PHP array usingjson_encode()
andjson_decode()
.
So, if you are sure about not having ,
(comma) in your array values, use simple_array
. If you have a simple array structure (linear), use array
and if you have more complex key-value arrays, use json_array
.