Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 5f3b45e

Browse files
Leverage LazyGhostTrait when possible
1 parent a2b5bae commit 5f3b45e

36 files changed

Lines changed: 429 additions & 373 deletions

.github/workflows/continuous-integration.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ jobs:
4343
- "default"
4444
extension:
4545
- "pdo_sqlite"
46+
proxy:
47+
- "common"
4648
include:
4749
- php-version: "8.0"
4850
dbal-version: "2.13"
@@ -53,6 +55,10 @@ jobs:
5355
- php-version: "8.2"
5456
dbal-version: "default"
5557
extension: "sqlite3"
58+
- php-version: "8.1"
59+
dbal-version: "3@dev"
60+
proxy: "lazy-ghost"
61+
extension: "pdo_sqlite"
5662

5763
steps:
5864
- name: "Checkout"
@@ -72,6 +78,10 @@ jobs:
7278
run: "composer require doctrine/dbal ^${{ matrix.dbal-version }} --no-update"
7379
if: "${{ matrix.dbal-version != 'default' }}"
7480

81+
- name: "Require specific lazy-proxy implementation"
82+
run: "composer require symfony/var-exporter:^6.2 doctrine/persistence:^3.1 --no-update"
83+
if: "${{ matrix.proxy == 'lazy-ghost' }}"
84+
7585
- name: "Install dependencies with Composer"
7686
uses: "ramsey/composer-install@v2"
7787
with:

.github/workflows/static-analysis.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,7 @@ jobs:
6060
if: "${{ matrix.dbal-version != 'default' }}"
6161

6262
- name: "Require specific persistence version"
63-
run: "composer require doctrine/persistence ^${{ matrix.persistence-version }} --no-update"
64-
if: "${{ matrix.persistence-version != 'default' }}"
63+
run: "composer require symfony/var-exporter ^6.2@dev doctrine/persistence ^$([ ${{ matrix.persistence-version }} = default ] && echo '3.1@dev' || echo ${{ matrix.persistence-version }}) --no-update"
6564

6665
- name: "Install dependencies with Composer"
6766
uses: "ramsey/composer-install@v2"
@@ -100,6 +99,9 @@ jobs:
10099
coverage: "none"
101100
php-version: "${{ matrix.php-version }}"
102101

102+
- name: "Require specific persistence version"
103+
run: "composer require symfony/var-exporter ^6.2@dev doctrine/persistence ^3.1@dev --no-update"
104+
103105
- name: "Install dependencies with Composer"
104106
uses: "ramsey/composer-install@v2"
105107
with:

docs/en/cookbook/accessing-private-properties-of-the-same-class-from-different-instance.rst

Lines changed: 0 additions & 74 deletions
This file was deleted.

docs/en/cookbook/implementing-wakeup-or-clone.rst

Lines changed: 0 additions & 78 deletions
This file was deleted.

docs/en/index.rst

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,6 @@ Cookbook
112112
* **Implementation**:
113113
:doc:`Array Access <cookbook/implementing-arrayaccess-for-domain-objects>` |
114114
:doc:`Notify ChangeTracking Example <cookbook/implementing-the-notify-changetracking-policy>` |
115-
:doc:`Using Wakeup Or Clone <cookbook/implementing-wakeup-or-clone>` |
116115
:doc:`Working with DateTime <cookbook/working-with-datetime>` |
117116
:doc:`Validation <cookbook/validation-of-entities>` |
118117
:doc:`Entities in the Session <cookbook/entities-in-session>` |

docs/en/reference/advanced-configuration.rst

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -325,8 +325,9 @@ identifier. You could simply do this:
325325
$cart->addItem($item);
326326
327327
Here, we added an Item to a Cart without loading the Item from the
328-
database. If you invoke any method on the Item instance, it would
329-
fully initialize its state transparently from the database. Here
328+
database. If you access any state that isn't yet available in the
329+
Item instance, the proxying mechanism would fully initialize the
330+
object's state transparently from the database. Here
330331
$item is actually an instance of the proxy class that was generated
331332
for the Item class but your code does not need to care. In fact it
332333
**should not care**. Proxy objects should be transparent to your

docs/en/reference/architecture.rst

Lines changed: 9 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -74,32 +74,13 @@ Entities
7474
An entity is a lightweight, persistent domain object. An entity can
7575
be any regular PHP class observing the following restrictions:
7676

77-
78-
- An entity class must not be final or contain final methods.
79-
- All persistent properties/field of any entity class should
80-
always be private or protected, otherwise lazy-loading might not
81-
work as expected. In case you serialize entities (for example Session)
82-
properties should be protected (See Serialize section below).
83-
- An entity class must not implement ``__clone`` or
84-
:doc:`do so safely <../cookbook/implementing-wakeup-or-clone>`.
85-
- An entity class must not implement ``__wakeup`` or
86-
:doc:`do so safely <../cookbook/implementing-wakeup-or-clone>`.
87-
You can also consider implementing
88-
`Serializable <https://php.net/manual/en/class.serializable.php>`_,
89-
but be aware that it is deprecated since PHP 8.1. We do not recommend its usage.
90-
- PHP 7.4 introduces :doc:`the new magic method <https://php.net/manual/en/language.oop5.magic.php#object.unserialize>`
91-
``__unserialize``, which changes the execution priority between
92-
``__wakeup`` and itself when used. This can cause unexpected behaviour in
93-
an Entity.
77+
- An entity class must not be final nor read-only but
78+
it may contain final methods or read-only properties.
9479
- Any two entity classes in a class hierarchy that inherit
9580
directly or indirectly from one another must not have a mapped
9681
property with the same name. That is, if B inherits from A then B
9782
must not have a mapped field with the same name as an already
9883
mapped field that is inherited from A.
99-
- An entity cannot make use of func_get_args() to implement variable parameters.
100-
Generated proxies do not support this for performance reasons and your code might
101-
actually fail to work when violating this restriction.
102-
- Entity cannot access private/protected properties/methods of another entity of the same class or :doc:`do so safely <../cookbook/accessing-private-properties-of-the-same-class-from-different-instance>`.
10384

10485
Entities support inheritance, polymorphic associations, and
10586
polymorphic queries. Both abstract and concrete classes can be
@@ -159,17 +140,13 @@ Serializing entities
159140

160141
Serializing entities can be problematic and is not really
161142
recommended, at least not as long as an entity instance still holds
162-
references to proxy objects or is still managed by an
163-
EntityManager. If you intend to serialize (and unserialize) entity
164-
instances that still hold references to proxy objects you may run
165-
into problems with private properties because of technical
166-
limitations. Proxy objects implement ``__sleep`` and it is not
167-
possible for ``__sleep`` to return names of private properties in
168-
parent classes. On the other hand it is not a solution for proxy
169-
objects to implement ``Serializable`` because Serializable does not
170-
work well with any potential cyclic object references (at least we
171-
did not find a way yet, if you did, please contact us). The
172-
``Serializable`` interface is also deprecated beginning with PHP 8.1.
143+
references to proxy objects or is still managed by an EntityManager.
144+
By default, serializing proxy objects does not initialize them. On
145+
unserialization, resulting objects are detached from the entity
146+
manager and cannot be initialiazed anymore. You can implement the
147+
``__serialize()`` method if you want to change that behavior, but
148+
then you need to ensure that you won't generate large serialized
149+
object graphs and take care of circular associations.
173150

174151
The EntityManager
175152
~~~~~~~~~~~~~~~~~

docs/en/reference/dql-doctrine-query-language.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -180,10 +180,10 @@ not need to lazy load the association with another query.
180180

181181
Doctrine allows you to walk all the associations between
182182
all the objects in your domain model. Objects that were not already
183-
loaded from the database are replaced with lazy load proxy
184-
instances. Non-loaded Collections are also replaced by lazy-load
183+
loaded from the database are replaced with lazy-loading proxy
184+
instances. Non-loaded Collections are also replaced by lazy-loading
185185
instances that fetch all the contained objects upon first access.
186-
However relying on the lazy-load mechanism leads to many small
186+
However relying on the lazy-loading mechanism leads to many small
187187
queries executed against the database, which can significantly
188188
affect the performance of your application. **Fetch Joins** are the
189189
solution to hydrate most or all of the entities that you need in a

docs/en/reference/limitations-and-known-issues.rst

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -177,27 +177,3 @@ MySQL with MyISAM tables
177177
Doctrine cannot provide atomic operations when calling ``EntityManager#flush()`` if one
178178
of the tables involved uses the storage engine MyISAM. You must use InnoDB or
179179
other storage engines that support transactions if you need integrity.
180-
181-
Entities, Proxies and Reflection
182-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
183-
184-
Using methods for Reflection on entities can be prone to error, when the entity
185-
is actually a proxy the following methods will not work correctly:
186-
187-
- ``new ReflectionClass``
188-
- ``new ReflectionObject``
189-
- ``get_class()``
190-
- ``get_parent_class()``
191-
192-
This is why ``Doctrine\Common\Util\ClassUtils`` class exists that has similar
193-
methods, which resolve the proxy problem beforehand.
194-
195-
.. code-block:: php
196-
197-
<?php
198-
use Doctrine\Common\Util\ClassUtils;
199-
200-
$bookProxy = $entityManager->getReference('Acme\Book');
201-
202-
$reflection = ClassUtils::newReflectionClass($bookProxy);
203-
$class = ClassUtils::getClass($bookProxy)¸

docs/en/reference/working-with-objects.rst

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -162,28 +162,6 @@ your code. See the following code:
162162
echo "This will always be true!";
163163
}
164164
165-
A slice of the generated proxy classes code looks like the
166-
following piece of code. A real proxy class override ALL public
167-
methods along the lines of the ``getName()`` method shown below:
168-
169-
.. code-block:: php
170-
171-
<?php
172-
class UserProxy extends User implements Proxy
173-
{
174-
private function _load(): void
175-
{
176-
// lazy loading code
177-
}
178-
179-
public function getName(): string
180-
{
181-
$this->_load();
182-
return parent::getName();
183-
}
184-
// .. other public methods of User
185-
}
186-
187165
.. warning::
188166

189167
Traversing the object graph for parts that are lazy-loaded will
@@ -414,14 +392,6 @@ Example:
414392
// $entity now refers to the fully managed copy returned by the merge operation.
415393
// The EntityManager $em now manages the persistence of $entity as usual.
416394
417-
.. note::
418-
419-
When you want to serialize/unserialize entities you
420-
have to make all entity properties protected, never private. The
421-
reason for this is, if you serialize a class that was a proxy
422-
instance before, the private variables won't be serialized and a
423-
PHP Notice is thrown.
424-
425395
426396
The semantics of the merge operation, applied to an entity X, are
427397
as follows:

0 commit comments

Comments
 (0)