为什么Doctrine\ORM\Configuration的"DoctrineProxies"对象包含宇宙?



在我的ORM代码中,我有一个实体,它的字段定义如下:

//part of entity class Item:
/** @Column(name="product_id", type="integer") */
private $productId;

然后我执行了这个代码:

//3 lines ~straight out of Doctrine configuration to get EntityManager
include 'config/doctrine-config.php';
$config = Setup::createAnnotationMetadataConfiguration($paths, $isDevMode);
$em = EntityManager::create($dbParams, $config);
//my own code to retrieve an entity instance:
$instance = $em->find(Item::class, 2);
print_r($instance);

这是我得到的输出(跳过其他一些类似的属性):

ApplicationEntityItem Object
(
    [id:ApplicationEntityItem:private] => 2
    [description:ApplicationEntityItem:private] => Product Kit
    [productId:ApplicationEntityItem:private] => -1
)

请注意,上面有6(六)行来自print_r()函数。

一切都很好,直到

接下来,我在Item实体类上将$productId列更改为ManyToOne关系,如下所示:

/** 
 * @ManyToOne(targetEntity="Product", inversedBy="id")
 * @JoinColumn(name="product_id", referencedColumnName="id")
 */
private $productId;

我运行了相同的代码。

2392600行的宇宙出现了,什么

2000000九万二千六百行print_r输出行。

查看打印输出,我发现DoctrineProxies__CG__ApplicationEntityProduct对象包含print_r 打印的2,392,564

问题:

这个物体到底是什么?为什么它这么大,打印出来时会占用近300Mb的磁盘空间?

我不禁想知道,这种复杂性是否会导致日常代码出现性能问题。例如,我并没有在日常代码中打印$instance变量的内容,但我肯定会从方法调用中返回巨大的内容。这是否意味着它是从上面的$em->find(Item::class, 2);调用传递的300Mb变量?

(非常)部分上市

ApplicationEntityItem Object
(
 [id:ApplicationEntityItem:private] => 2
 [description:ApplicationEntityItem:private] => Product Kit
 [ProductId:ApplicationEntityItem:private] => DoctrineProxies__CG__ApplicationEntityProduct Object
  (
   [__initializer__] => Closure Object
    (
     [static] => Array
      (
       [entityPersister] => DoctrineORMPersistersEntityBasicEntityPersister Object
        (
         [class:protected] => DoctrineORMMappingClassMetadata Object
          (
           [name] => ApplicationEntityProduct
           [namespace] => ApplicationEntity
           [rootEntityName] => ApplicationEntityProduct
           [inheritanceType] => 1
           [generatorType] => 5
           [fieldMappings] => Array
            (
             [id] => Array
              (
               [fieldName] => id
               [type] => integer
               [scale] => 0
               [length] => 
               [unique] => 
               [nullable] => 
               [precision] => 0
               [columnName] => id
               [id] => 1
              )
           [fieldNames] => Array
            (
             [id] => id
             [description] => description
            )
       [columnNames] => Array
            (
             [id] => id
             [description] => description
            )
       [idGenerator] => DoctrineORMIdAssignedGenerator Object
           [reflClass] => ReflectionClass Object
            (
             [name] => ApplicationEntityProduct
            )
       [namingStrategy:protected] => DoctrineORMMappingDefaultNamingStrategy Object
           [instantiator:DoctrineORMMappingClassMetadataInfo:private] => DoctrineInstantiatorInstantiator Object
          )
     [conn:protected] => DoctrineDBALConnection Object
          (
           [_conn:protected] => DoctrineDBALDriverPDOConnection Object
            (
            )
       [_config:protected] => DoctrineORMConfiguration Object
            (
             [_attributes:protected] => Array
              (
               [metadataCacheImpl] => DoctrineCommonCacheArrayCache Object
                (
                 [data:DoctrineCommonCacheArrayCache:private] => Array
                  (
                   [dc2_b1e855bc8c5c80316087e39e6c34bc26_[ApplicationEntityItem$CLASSMETADATA][1]] => Array
                    (
                     [0] => DoctrineORMMappingClassMetadata Object
                      (
                       [name] => ApplicationEntityItem
                       [namespace] => ApplicationEntity
                       [rootEntityName] => ApplicationEntityItem
                       [customGeneratorDefinition] => 
                       [customRepositoryClassName] => 
                       [isMappedSuperclass] => 
                       [isEmbeddedClass] => 
                       [parentClasses] => Array
    [BAZILLION LINES redacted for brevity]

如果没有XDebug或类似工具(限制转储对象的大小),就无法转储代理对象。

问题非常非常简单:

Proxy->引用EntityManager->引用UnitOfWork->包含Proxy

这显然会导致递归数据结构转储,而当您试图在没有合理限制的情况下转储它时,这反过来又会导致混乱。

DoctrineProxies__CG__ApplicationEntityProduct是代理类。。。这意味着条令实际上不会从数据库中获取实体(为了性能),除非需要(即调用$product->getName(),这些代理类彼此处于递归循环中,并且如您所见非常大……那里的大多数信息除非您深入研究,否则您并不真正需要……您永远不应该在新的symfony 2.7+中使用print_r……我认为在调试模式下有一个名为dump()的函数……如果您使用它来打印实体,它具有循环保护,并且它只显示参考参考号。。。你也可以使用DoctrineCommonUtilDebug::dump(),它也会打印出比2^234234234行更小的列表。。。

相关内容

  • 没有找到相关文章

最新更新