【问题标题】:Why does Doctrine\ORM\Configuration's "DoctrineProxies" Object contain the Universe?为什么 Doctrine\ORM\Configuration 的“DoctrineProxies”对象包含 Universe?
【发布时间】:2016-09-01 18:47:14
【问题描述】:

在我的 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);

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

Application\Entity\Item Object
(
    [id:Application\Entity\Item:private] => 2
    [description:Application\Entity\Item:private] => Product Kit
    [productId:Application\Entity\Item:private] => -1
)

请注意上面的 6(六)行是如何从 print_r() 函数中得出的。

一切都很好,直到

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

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

我运行了相同的代码。

出现了 2,392,600 行的宇宙,什么?

两百万、三十九万二千、六百行print_r输出。

查看打印输出,我看到 DoctrineProxies\__CG__\Application\Entity\Product 对象包含由 print_r 打印的 2,392,564

问题:

这个对象到底是什么,为什么打印出来时会占用将近 300Mb 的磁盘空间?

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

(非常)部分列表

Application\Entity\Item Object
(
 [id:Application\Entity\Item:private] => 2
 [description:Application\Entity\Item:private] => Product Kit
 [ProductId:Application\Entity\Item:private] => DoctrineProxies\__CG__\Application\Entity\Product Object
  (
   [__initializer__] => Closure Object
    (
     [static] => Array
      (
       [entityPersister] => Doctrine\ORM\Persisters\Entity\BasicEntityPersister Object
        (
         [class:protected] => Doctrine\ORM\Mapping\ClassMetadata Object
          (
           [name] => Application\Entity\Product
           [namespace] => Application\Entity
           [rootEntityName] => Application\Entity\Product
           [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] => Doctrine\ORM\Id\AssignedGenerator Object
           [reflClass] => ReflectionClass Object
            (
             [name] => Application\Entity\Product
            )

       [namingStrategy:protected] => Doctrine\ORM\Mapping\DefaultNamingStrategy Object
           [instantiator:Doctrine\ORM\Mapping\ClassMetadataInfo:private] => Doctrine\Instantiator\Instantiator Object

          )

     [conn:protected] => Doctrine\DBAL\Connection Object
          (
           [_conn:protected] => Doctrine\DBAL\Driver\PDOConnection Object
            (
            )

       [_config:protected] => Doctrine\ORM\Configuration Object
            (
             [_attributes:protected] => Array
              (
               [metadataCacheImpl] => Doctrine\Common\Cache\ArrayCache Object
                (
                 [data:Doctrine\Common\Cache\ArrayCache:private] => Array
                  (
                   [dc2_b1e855bc8c5c80316087e39e6c34bc26_[Application\Entity\Item$CLASSMETADATA][1]] => Array
                    (
                     [0] => Doctrine\ORM\Mapping\ClassMetadata Object
                      (
                       [name] => Application\Entity\Item
                       [namespace] => Application\Entity
                       [rootEntityName] => Application\Entity\Item
                       [customGeneratorDefinition] => 
                       [customRepositoryClassName] => 
                       [isMappedSuperclass] => 
                       [isEmbeddedClass] => 
                       [parentClasses] => Array

    [BAZILLION LINES redacted for brevity]

【问题讨论】:

    标签: php symfony orm doctrine-orm proxy-classes


    【解决方案1】:

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

    问题真的非常简单:

    代理 -> 引用 EntityManager -> 引用 UnitOfWork -> 包含代理

    这显然会导致递归数据结构转储,这反过来又会在您尝试无合理限制地转储它时导致混乱。

    【讨论】:

      【解决方案2】:

      DoctrineProxies\__CG__\Application\Entity\Product 是一个代理类......这意味着学说实际上不会从数据库中获取实体(为了性能),除非需要它(即调用$product->getName() 这些代理类彼此处于递归循环中并且非常大你看到了......那里的大部分信息你并不真正需要,除非你深入研究......你永远不应该使用print_r......在新的symfony 2.7+中我认为有一个名为dump()的函数在调试模式下...如果您使用它来打印具有循环保护的实体并且它只显示参考号...您还可以使用\Doctrine\Common\Util\Debug::dump(),它也将打印出比 2^234234234 行更小的列表.. .

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-03-03
        • 1970-01-01
        • 2022-08-08
        • 2013-05-12
        • 2015-02-28
        • 1970-01-01
        • 2014-10-10
        相关资源
        最近更新 更多