Professional Documents
Culture Documents
We are thrilled to announce the release of Doctrine ORM 3.0 and DBAL 4.0. These releases are the culmination of over a decade of
hard work across dozens of contributors and the Doctrine maintainers.
What's New
A Slimmer, More Efficient ORM: The new Doctrine ORM 3.0 comes in at 326KB, down from 400KB in ORM 2.18.0. This reduction not
only makes the ORM lighter but also signals our efforts to streamline and optimize every aspect of our library and focus our
maintenance efforts on the core functionality of an ORM and less on tooling and helpers that are only useful by a small number of our
users.
Enhanced Code Quality and Coverage: With ORM 3.0, we've pushed our code coverage from 84% to 89%. For DBAL 4.0, we've
pushed our code coverage from 86% to 94%. This improvement underscores our commitment to reliability and the stability of the
Doctrine ecosystem, ensuring that your applications run smoothly.
Leaner Dependencies: In Doctrine ORM 3.0, we have finally eliminated dependencies on doctrine/cache and doctrine/common. This
change reduces complexity and improves maintainability of Doctrine as we now depend on PSR-6: Caching Interface for our caching
responsibilities. Implementing a PSR means we are more interoperable with other frameworks and easier to use by a broader amount
of users.
A Growing Community: The Doctrine project now boasts 1029 contributors across all its projects. This vibrant community is the
backbone of Doctrine, providing valuable insights, feedback, and contributions that drive the project forward.
Upgrading
We understand that upgrading to a new major version can be difficult. The best way to upgrade is to first upgrade to the latest Doctrine
ORM 2.x and DBAL 3.x version and address any deprecation warnings that are reported. You can read more about how Doctrine
handles deprecations here. Once you have addressed all of the deprecations, you should have a clear path to upgrade.
In addition to that, we've maintained comprehensive documentation about every change, deprecation and BC break to facilitate a
smooth transition to ORM 3.0 and DBAL 4.0.
Looking Forward
ORM 3 and DBAL 4 are a big step forward towards modernizing the API of our libraries, increasing safety with the use of scalar types in
the code base, better error handling and generally cleaning up the code to make it easier to maintain. We look forward to continuing
work on Doctrine and focusing on being the most stable and reliable PHP database persistence related libraries available.
After long consideration, we have decided to archive a number of repositories that have not seen any activity in a while. This affects the
CouchDB and OrientDB ODMs and their respective libraries, as well as the KeyValueStore project. The following repositories and
composer packages are affected:
doctrine/couchdb
doctrine/couchdb-odm
doctrine/couchdb-odm-bundle
doctrine/orientdb-odm
doctrine/key-value-store
The composer packages will remain available and installable, but we will not be making any bug fixes or security fixes in the affected
libraries. If you or your business depends on one of these libraries, please fork them and maintain them yourself in the future.
https://www.doctrine-project.org/blog/index.html 1/10
4/5/24, 11:19 AM Blog - Doctrine: PHP Open Source Project
We have released the first beta of the long awaited Doctrine ORM 3 and a release candidate of DBAL 4.
The target audience for these releases are framework integration and extension library authors. ORM 3 is not yet production ready and
the APIs may change.
Our goal is to release ORM 3.0 as soon as possible and to gather feedback from greenfield project authors first.
This beta release is the result of a lot of work by many contributors, especially Grégoire, Alexander, Claudio and Matthias on ORM,
Sergei and Alexander on DBAL. To iron out the final details, we met in Düsseldorf for a Doctrine Core Team meeting, generously funded
by our sponsors through OpenCollective and GitHub. We also welcomed Matthias as the latest member of the Doctrine Core Team.
We will maintain the latest branch of the 2 line in ORM for at least another 2 years, possibly longer, to give you enough time to upgrade
and us more time to learn from upgrader feedback and improve forward compatibility.
This means that we will be making ORM 2.x work with newer versions of PHP, fixing security bugs, and introducing layers and features
that help with forward compatibility in the upgrade path to ORM 3.
Current users of ORM 2 should note that there is no urgency right now to update to ORM 3, as we are still working on replacement APIs
and forward compatibility, and do not intend to ship them all with ORM 3.0, but with later versions.
But there is already work to be done as an ORM 2 user: to help you find all the places where things may be deprecated or changing
behaviour, we have created the doctrine/deprecations library and integrated it heavily into DBAL, ORM and other components.
It allows the use of deprecated behaviour to be logged at runtime with low overhead, automatic suppression of the same deprecation
occurring multiple times, and a way to ignore selected deprecations for the time being. Each deprecation message always links to a
GitHub issue with more details.
Many deprecated features have no replacement, such as Mapping Exporters, Generate Mapping from Database, Named Queries.
For some of the deprecations in ORM, we are still planning replacement APIs, especially:
There is currently no way to limit the number of entities that the flush operation considers changed. Flush will currently always
calculate change sets on all entities that are not read-only.
As a replacement for removing PARTIAL object hydration, we are looking at making embeddable objects lazy, perhaps improving
nesting of the new DTO expression in DQL. We are also looking to introduce subselect or batch loading for collections for more
efficient multi-level hydration.
These will be released in 2.x as forward compatible APIs so that you can switch to using them before upgrading to ORM 3.
We are organizing a Doctrine ORM Core Team Meetup in Düsseldorf, Germany from Monday, 9.10.2023 to Wednesday, 11.10.2023 at
the offices of one of our primary sponsors Tideways GmbH.
The goal is to get the current team together, discuss and work on the missing pieces for the long-awaited Doctrine ORM 3.0 release that
is planned for later this year.
Last month, we migrated the tests of the ORM from annotations to attributes. Let us look back on what lead to this moment.
Annotations
Let's go 22 years back in time. In October 2000, Ulf Wendel introduces phpdoc comments at the PHP-Kongress. These comments
follow a structure that allows to produce API documentation from them. They are inspired by javadoc.
https://www.doctrine-project.org/blog/index.html 2/10
4/5/24, 11:19 AM Blog - Doctrine: PHP Open Source Project
In 2002, Alex Buckley, a Specification lead for the Java language publishes JSR-175, thus proposing to add user-defined annotations to
the language, allowing to tag language elements with extra information. 2 years later, it gets approved and Java 1.5, also known as
Java 5 is released, with support for annotations.
4 more years elapse and in 2006, Jano Suchal publishes Addendum, a PHP library that adds support for using "Docblock/JavaDoc" as
annotations, meaning that contrary to what is done in Java, Addendum annotations are contained inside phpdoc comments, like this:
/** @test */
function test_it_throws_on_invalid_argument(): void
{}
That is because they are implemented in userland, without requiring a change in PHP itself.
Doctrine ORM 2.0 is not released yet at that point, but the library is used to build an annotation driver in Doctrine 2 in early 2009. At that
time, Doctrine was a project in a single repository, with Common, DBAL and ORM as top-level namespaces. Addendum is replaced 6 months
later, with a new namespace under Common called Annotations.
In the summer of 2010, Guilherme Blanco and Pierrick Charron submit an RFC to add annotations support to PHP, but it gets declined.
The RFC already mentions the need for annotations in PHPUnit, Symfony, Zend Framework, FLOW3 and of course, Doctrine.
Late 2010, Doctrine 2 is tagged, and the single repository is split into 3 repositories.
Finally, in 2013, the namespace above is isolated in its own repository, and doctrine/annotations 1.0.0 is tagged.
Today, the package is widely used in the PHP ecosystem and has a little short of 300 million downloads on Packagist, and is depended
on by over 2 thousand packages, including major frameworks and tools. It is fair to say annotations have proven valuable to many
users.
Attributes
The RFC mentioned above is only one among many. As mentioned before, annotations were implemented as phpdoc comments, which
has several drawbacks:
The comments are necessary to run the code, and need to be kept in the opcode cache.
They are obtained at runtime, by using the reflection API, and because of that, can only be detected as invalid at runtime.
They are not well supported by IDEs if at all.
They clutter comments, which were originally intended for humans.
They can be confused with phpdoc, which are something else entirely.
In March 2020, Benjamin Eberlei resurrects Dmitry Stogov's attributes RFC and submits the seventh RFC on this topic, introducing
attributes to PHP.
A few rounds of RFCs about syntax later, PHP 8.0 is released, with a notable feature missing: nested attributes. PHP 8.0 attributes use
a syntax that is forward-compatible with them though, and finally, with PHP 8.1, nested attributes are supported.
Enter Rector. Rector is a standalone tool that is invaluable when it comes to performing such migrations: it is able to understand PHP
code and apply so-called Rectors to it. It is extensible, so it is possible to define such Rectors in order to address upgrades for anything,
including Doctrine.
What's more, it comes with batteries included: when you install rector/rector, what you get is code from rector/rector-src and its
official extensions, among which you will find rector/rector-doctrine. That's right, there is already an entire extension dedicated to
Doctrine.
Rules are grouped together in sets, and the set that interests us here is
Rector\Doctrine\Set\DoctrineSetList::ANNOTATIONS_TO_ATTRIBUTES.
https://www.doctrine-project.org/blog/index.html 3/10
4/5/24, 11:19 AM Blog - Doctrine: PHP Open Source Project
<?php
declare(strict_types=1);
use Rector\Config\RectorConfig;
use Rector\Doctrine\Set\DoctrineSetList;
Or at least, it was the plan, because some annotations were not perfectly migrated. All in all, I found only 2 bugs, which looks great
given how so many edge cases should appear in our test suite.
I went on and reported those 2 bugs, and this is where the experience went from great to stellar: the issue template leads to a
playground, much like the one you can find for other tools such as Psalm or PHPStan.
This one comes with 2 buttons: "Create an issue", which pre-fills the Github issue with useful information, and "Create a test", that lets
you create a test in the right directory (and also, the right repository, which is rectorphp/rector-src, and not rectorphp/rector).
If you want to add a new test for the bug you reported, you should let the official tutorial walk you through that, it is very well written.
Anyway, now that these 2 bugs are fixed and you know how to migrate, plan that migration, and let us know how it goes! Happy
Rectoring!
New Release: Doctrine DBAL 3.4.0
Posted on August 6, 2022 by Sergei Morozov
Doctrine is proud to announce the release of Doctrine DBAL 3.4.0. Below is a summary of the most noteworthy changes in the new
release:
As of this release, the entire schema is introspected in a fixed number of queries. The more tables the schema contains, the more
noticeable this optimization should be.
It was impossible to make these optimizations while using the schema introspection platform methods (e.g.
getListTableColumnsSQL()). As a result, although these methods are kept in the codebase for backward compatibility, the DBAL itself
no longer uses them. The SQL queries used for schema introspection are no longer considered part of the public DBAL API.
For example, when a foreign key constraint is declared, platforms like MySQL require that the referenced table must already exist. To
support creating tables with mutually referencing constraints, the DBAL would create the tables first and create the constraints via ALTER
TABLE … ADD FOREIGN KEY ….
This approach doesn't work with SQLite since it doesn't allow adding constraints to an existing table. Fortunately, it doesn't require the
referenced table to exist at the time of creating the foreign key either.
https://www.doctrine-project.org/blog/index.html 4/10
4/5/24, 11:19 AM Blog - Doctrine: PHP Open Source Project
The new DBAL release introduces a new API for building CREATE TABLE and DROP TABLE statements for multiple tables which could be
tailored to the requirements of a given platform. The AbstractPlatform::supportsForeignKeys() method is now deprecated since the
DBAL supports foreign key constraints on all supported platforms.
As of the new release, the default TEXT and BLOB values are supported on MariaDB but are still unsupported on MySQL, even though
MySQL supports them as of release 8.0.13.
Deprecations
In light of the DBAL 4 release planned for later this year, the 3.4.0 release introduces over 30 deprecations which, as usual, focus on
cleaning up obsolete features and making the API more robust and clearer from the static analysis standpoint.
To learn more about upgrading your application, see the upgrade notes. You can find the full list of changes in the release milestone.
On Doctrine Sponsoring with the help of OpenCollective
Posted on March 24, 2022 by Benjamin Eberlei
To simplify our own administrative burden, we have decided to move over the funds to OpenCollective, primarily motivated by the
success and positive experience of the new PHP Foundation.
We have started raising money for the Doctrine Project in 2019 through Patreon and Github Sponsors to support the project. It was
planned to organize core team get-togethers/hackathons, but due to the pandemic we haven't been able to do this. In addition the legal
and tax implications of raising money also caused us some headaches.
The move to OpenCollective will allow us to delegate much of the administrative work to them for a small percentage of the raised
capital. The fee is a much smaller amount than the taxes that we had to pay on the raised money previously, so it is a win-win for us.
We want to assure our sponsors that we still plan to make use of the funds to further the Doctrine project and we are actively looking to
increase our funding for these goals:
Regularly organize hackathons for Doctrine Core team contributors, including 3-4 days of accommodation, food and travel for
roughly 10-15 people.
If the budget increases significantly we might be able to pay someone part- or full-time to do maintenance work such as
responding to and processing issues, prepare for new PHP releases and general cleanups of the codebase.
As such we hope to convince you to sponsor Doctrine through either our Github Sponsors or OpenCollective directly.
Since the release of Doctrine DBAL 3.0.0 in November 2020, the 2.x release series effectively went into the maintenance mode. In the
past year, we've been accepting mostly the following types of patches for DBAL 2:
https://www.doctrine-project.org/blog/index.html 5/10
4/5/24, 11:19 AM Blog - Doctrine: PHP Open Source Project
Except for dependency updates, at the moment, there are no known issues in DBAL 2 that would fall into any of the above categories.
Many projects that depend on Doctrine DBAL depend on it indirectly via Doctrine ORM which until release 2.10.0 didn't support DBAL 3.
It was one of the blockers of the DBAL 3 adoption which is no longer the case.
With all that said, the DBAL team announces the plan for sunsetting DBAL 2 in 6 months as of the ORM 2.10.0 release which is April 3,
2022. After that date, we plan to release DBAL 2 only to address security related and other critical issues for at most a year.
All Doctrine DBAL users are encouraged to upgrade to the latest stable version which is 3.3.0 as of the time of this writing.
For migrating from DBAL 2 to 3, see our two blog posts on DBAL 2.13 Forward Compatibility Layer:
New Release: Doctrine DBAL 2.13 with Deprecations and Forward Compatibility
New Release: Doctrine DBAL 2.13.1 and 3.1.0 with important Forward Compatibility fix
New Release: Doctrine ORM 2.11 with Enums, Virtual Columns, Read-Only Properties,
Nested Attributes and more
Posted on January 11, 2022 by Benjamin Eberlei
We have released a new minor version 2.11 of Doctrine ORM with several improvements and new features.
This blog post gives an overview over all the new features and improvements that are user facing. Please see the changelog and
UPGRADE notes for new deprecations.
The support is not integrated on DBAL Type level, but using a new mapping option called enumType on column/field declaration level:
#[Entity]
class Card
{
/** ... */
We have worked along the lines of Java Persistence API support of insertable, updatable and generated options for field mappings.
https://www.doctrine-project.org/blog/index.html 6/10
4/5/24, 11:19 AM Blog - Doctrine: PHP Open Source Project
#[Entity]
class User
{
#[ManyToOne(targetEntity: Country:class), JoinColumn(name: "country_code", referencedColumnName: "country_code")]
public $country;
#[Entity]
class Article
{
#[Column(type: "datetime",
columnDefinition: "TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP",
insertable: false,
updatable: false,
generated: "ALWAYS")]
public $created;
}
With ORM 2.11 the support now works as you would expect with no additional mapping options necessary:
#[Column]
private readonly string $name;
}
With the support now available in PHP 8.1 we have added these attributes.
https://www.doctrine-project.org/blog/index.html 7/10
4/5/24, 11:19 AM Blog - Doctrine: PHP Open Source Project
<?php
use Doctrine\ORM\Mapping\AssociationOverride;
use Doctrine\ORM\Mapping\AssociationOverrides;
use Doctrine\ORM\Mapping\AttributeOverride;
use Doctrine\ORM\Mapping\AttributeOverrides;
use Doctrine\ORM\Mapping\Column;
use Doctrine\ORM\Mapping\Entity;
#[AssociationOverrides([
new AssociationOverride(
name: "groups",
joinTable: new JoinTable(
name: "ddc964_users_admingroups",
),
joinColumns: [new JoinColumn(name: "adminuser_id")],
inverseJoinColumns: [new JoinColumn(name: "admingroup_id")]
)
])]
#[AttributeOverrides([
new AttributeOverride(
name: "id",
column: new Column(name: "guest_id", type: "integer", length: 140)
)])]
class DDC964Admin extends DDC964User
{
}
For PHP 8.0 we have already moved Index and JoinColumn mappings to the top level to avoid nesting and decided not to allow nesting
for these to mimic annotation support.
<?php
$config->setSchemaIgnoreClasses([$fqcn]);
$config->getSchemaIgnoreClasses();
New Release: Doctrine MongoDB ODM 2.3 with Attributes, JSON Schema Validation,
and more
Posted on December 4, 2021 by Ion Bazan
We have released a new minor version 2.3 of Doctrine MongoDB ODM, the first version with support for using PHP 8 Attributes as a
new driver for mapping documents and several other changes. See all changes and contributors in the Changelog on GitHub.
https://www.doctrine-project.org/blog/index.html 8/10
4/5/24, 11:19 AM Blog - Doctrine: PHP Open Source Project
#[MongoDB\Document(repositoryClass: PostRepository::class)]
class Post
{
#[MongoDB\Id]
private string $id;
#[MongoDB\Field(type: Type::BOOLEAN)]
private bool $published = false;
#[MongoDB\Field(type: Types::COLLECTION)]
private array $text = [];
#[MongoDB\ReferenceOne(targetDocument: User::class)]
public $author;
#[MongoDB\ReferenceMany(targetDocument: Tag::class)]
public Collection $tags;
}
You may want to use Rector with DoctrineSetList::DOCTRINE_ODM_23 set to convert all your annotation mappings to attributes in
seconds!
Doctrine MongoDB ODM now provides a way to take advantage of this functionality thanks to the new #[Validation] mapping.
#[MongoDB\Document]
#[MongoDB\Validation(
validator: SchemaValidated::VALIDATOR,
action: ClassMetadata::SCHEMA_VALIDATION_ACTION_WARN
)]
class SchemaValidated
{
public const VALIDATOR = <<<'EOT'
{
"$jsonSchema": {
"required": ["name"],
"properties": {
"name": {
"bsonType": "string",
"description": "must be a string and is required"
}
}
},
"$or": [
{ "phone": { "$type": "string" } },
{ "email": { "$regex": { "$regularExpression" : { "pattern": "@mongodb\\.com$", "options": "" } } } },
{ "status": { "$in": [ "Unknown", "Incomplete" ] } }
]
}
EOT;
}
https://www.doctrine-project.org/blog/index.html 9/10
4/5/24, 11:19 AM Blog - Doctrine: PHP Open Source Project
Once defined, those options will be added to the collection after running the odm:schema:create or odm:schema:update command.
Psalmified APIs
In-code documentation has been immensely improved to make sure static analysis tools and IDEs know about the right document
classes returned from DocumentManager, ClassMetadata, and other public APIs. This includes generics support for your own
repositories extending DocumentRepository.
use Doctrine\ODM\MongoDB\Repository\DocumentRepository;
use App\Document\User;
/**
* @template-extends DocumentRepository<User>
*/
class UserRepository extends DocumentRepository
{
}
Deprecations
Doctrine MongoDB ODM 2.3 introduces several minor deprecations:
https://www.doctrine-project.org/blog/index.html 10/10