diff --git a/docs/en/cookbook/entities-in-session.rst b/docs/en/cookbook/entities-in-session.rst index b9d9c6656df..25c9779a26a 100644 --- a/docs/en/cookbook/entities-in-session.rst +++ b/docs/en/cookbook/entities-in-session.rst @@ -3,42 +3,69 @@ Entities in the Session There are several use-cases to save entities in the session, for example: -1. User object +1. User data 2. Multi-step forms To achieve this with Doctrine you have to pay attention to some details to get this working. -Merging entity into an EntityManager ------------------------------------- +Updating an entity +------------------ In Doctrine an entity objects has to be "managed" by an EntityManager to be -updateable. Entities saved into the session are not managed in the next request -anymore. This means that you have to register these entities with an -EntityManager again if you want to change them or use them as part of -references between other entities. You can achieve this by calling -``EntityManager#merge()``. +updatable. Entities saved into the session are not managed in the next request +anymore. This means that you have to update the entities with the stored session +data after you fetch the entities from the EntityManager again. -For a representative User object the code to get turn an instance from -the session into a managed Doctrine object looks like this: +For a representative User object the code to get data from the session into a +managed Doctrine object can look like these examples: + +Working with scalars +~~~~~~~~~~~~~~~~~~~~ + +In simpler applications there is no need to work with objects in sessions and you can use +separate session elements. .. code-block:: php merge($user); + if (isset($_SESSION['userId']) && is_int($_SESSION['userId'])) { + $userId = $_SESSION['userId']; + + $em = GetEntityManager(); // creates an EntityManager + $user = $em->find(User::class, $userId); + + $user->setValue($_SESSION['storedValue']); + + $em->flush(); } -.. note:: +Working with custom data transfer objects +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If objects are needed, we discourage the storage of entity objects in the session. It's +preferable to use a `DTO (data transfer object) `_ +instead and merge the DTO data later with the entity. + +.. code-block:: php + + find(User::class, $userDto->getId()); + + $userEntity->populateFromDto($userDto); + + $em->flush(); + } Serializing entity into the session ----------------------------------- @@ -47,22 +74,20 @@ Entities that are serialized into the session normally contain references to other entities as well. Think of the user entity has a reference to their articles, groups, photos or many other different entities. If you serialize this object into the session then you don't want to serialize the related -entities as well. This is why you should call ``EntityManager#detach()`` on this -object or implement the __sleep() magic method on your entity. +entities as well. This is why you shouldn't serialize an entity and use +only the needed values of it. This can happen with the help of a DTO. .. code-block:: php find("User", 1); - $em->detach($user); - $_SESSION['user'] = $user; + $userDto = new UserDto($user->getId(), $user->getFirstName(), $user->getLastName()); + // or "UserDto::createFrom($user);", but don't store an entity in a property. Only its values without relations. -.. note:: + $_SESSION['user'] = $userDto; - When you called detach on your objects they get "unmanaged" with that - entity manager. This means you cannot use them as part of write operations - during ``EntityManager#flush()`` anymore in this request.