Proxy classes and bounded operations to proxy class (instead of the entity class directly) #6017

Closed
opened 2026-01-22 15:24:49 +01:00 by admin · 1 comment
Owner

Originally created by @mvorisek on GitHub (Jul 11, 2018).

Originally assigned to: @Ocramius on GitHub.

Bug Report

If entity is proxied and some manipulation is done with scope set to the proxy class, private properties are not set/read, instead of new public (and duplicate) properties are added.

Summary

It is quite common to use the following scope change construction to operate with private entity properties:

    \Closure::bind(function() {
        $this->updatedAt = new \DateTime();
    }, $entity, $entity)();

The user expects that the private property of the entity is set.

Current behavior

It works if the entity is not proxied. But when the entity is proxied, it currently behave differently - a new public property is set! This can produce very strange results and it is very hard to debug.

Here is a print_r() output for the current implementation:

DoctrineProxies\__CG__\EntityClass Object
(
    [__initializer__] =>
    [__cloner__] =>
    [__isInitialized__] => 1
    [updatedAt:EntityClass:private] => DateTime Object
        (
            [date] => 2018-07-11 00:19:50.840381
            [timezone_type] => 3
            [timezone] => Europe/Prague
        )
    [updatedAt] => DateTime Object
        (
            [date] => 2018-07-11 09:22:07.360275
            [timezone_type] => 3
            [timezone] => Europe/Prague
        )
)

The current workaround is to get the entity class manually (using Doctrine\Common\Util\ClassUtils::getRealClass() method) and then bound the set method to this class explicitly. But this can be very easily forget by the programmer and as this bug is only presented when the entity is proxied, this may be very hard to find later if for some reasons the entity is now lazy loaded and proxied and previously it was not the case.

How to reproduce

  1. take any lazy loaded related entity
  2. set any property using the construct above (using proxy class scope instead the entity scope directly)
  3. check the print_r output

Expected behavior

The expected behaviour is that entity private property is set even if set from proxy scope. The proxy impl. should behave as much as possible as the entity itself.

Expected print_r() output:

DoctrineProxies\__CG__\EntityClass Object
(
    [__initializer__] =>
    [__cloner__] =>
    [__isInitialized__] => 1
    [updatedAt:EntityClass:private] => DateTime Object
        (
            [date] => 2018-07-11 09:22:07.360275
            [timezone_type] => 3
            [timezone] => Europe/Prague
        )
)
Originally created by @mvorisek on GitHub (Jul 11, 2018). Originally assigned to: @Ocramius on GitHub. ### Bug Report If entity is proxied and some manipulation is done with scope set to the proxy class, private properties are not set/read, instead of new public (and duplicate) properties are added. #### Summary It is quite common to use the following scope change construction to operate with private entity properties: \Closure::bind(function() { $this->updatedAt = new \DateTime(); }, $entity, $entity)(); The user expects that the private property of the entity is set. #### Current behavior It works if the entity is not proxied. But when the entity is proxied, it currently behave differently - a new public property is set! This can produce very strange results and it is very hard to debug. Here is a print_r() output for the current implementation: DoctrineProxies\__CG__\EntityClass Object ( [__initializer__] => [__cloner__] => [__isInitialized__] => 1 [updatedAt:EntityClass:private] => DateTime Object ( [date] => 2018-07-11 00:19:50.840381 [timezone_type] => 3 [timezone] => Europe/Prague ) [updatedAt] => DateTime Object ( [date] => 2018-07-11 09:22:07.360275 [timezone_type] => 3 [timezone] => Europe/Prague ) ) The current workaround is to get the entity class manually (using `Doctrine\Common\Util\ClassUtils::getRealClass()` method) and then bound the set method to this class explicitly. But this can be very easily forget by the programmer and as this bug is only presented when the entity is proxied, this may be very hard to find later if for some reasons the entity is now lazy loaded and proxied and previously it was not the case. #### How to reproduce 1. take any lazy loaded related entity 2. set any property using the construct above (using proxy class scope instead the entity scope directly) 3. check the print_r output #### Expected behavior The expected behaviour is that entity private property is set even if set from proxy scope. The proxy impl. should behave as much as possible as the entity itself. Expected print_r() output: DoctrineProxies\__CG__\EntityClass Object ( [__initializer__] => [__cloner__] => [__isInitialized__] => 1 [updatedAt:EntityClass:private] => DateTime Object ( [date] => 2018-07-11 09:22:07.360275 [timezone_type] => 3 [timezone] => Europe/Prague ) )
admin added the BugCan't Fix labels 2026-01-22 15:24:49 +01:00
admin closed this issue 2026-01-22 15:24:49 +01:00
Author
Owner

@Ocramius commented on GitHub (Jul 11, 2018):

@mvorisek this is something that is already fixed in master, but isn't fixable in 2.x due to the proxy system being completely replaced by ocramius/proxy-manager.

If you think you have an edge case that you'd like to have fixed, please check 99542a2c0f/tests/language-feature-scripts and add your scenario there.

@Ocramius commented on GitHub (Jul 11, 2018): @mvorisek this is something that is already fixed in `master`, but isn't fixable in `2.x` due to the proxy system being completely replaced by `ocramius/proxy-manager`. If you think you have an edge case that you'd like to have fixed, please check https://github.com/Ocramius/ProxyManager/tree/99542a2c0fef18e0b460cbed93c5cde63cc2be91/tests/language-feature-scripts and add your scenario there.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#6017