简体   繁体   English

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

[英]Why does Doctrine\ORM\Configuration's “DoctrineProxies” Object contain the Universe?

In my ORM code I have an Entity with a field fined like so: 在我的ORM代码中,我有一个实体,其字段的罚款如下:

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

I then executed this code: 然后执行以下代码:

//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);

And this is the output I get (skipping few other similar properties): 这是我得到的输出(跳过一些其他类似的属性):

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

Note how there are 6 (six) lines above that came out of print_r() function. 请注意, print_r()函数的上方有六(六)行。

And everything was fine, Until 一切都很好,直到

Next, I have changed the $productId column to ManyToOne Relationship on my Item Entity class, like so: 接下来,我将Item Entity类的$productId列更改为ManyToOne Relationship,如下所示:

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

I ran the same code. 我运行了相同的代码。

OUT CAME THE UNIVERSE OF 2,392,600 LINES, WHAT? 达到2,392,600行的宇宙,这是什么?

Two million, three hundred and ninety two thousand, six hundred lines lines of print_r output. 两百三十二万二千六百行 print_r输出行。

looking at the print-out I see that DoctrineProxies\\__CG__\\Application\\Entity\\Product Object contains 2,392,564 lines printed by print_r 查看打印输出,我看到DoctrineProxies\\__CG__\\Application\\Entity\\Product对象包含由print_r打印的2,392,564

Question: 题:

What is exactly in this object and why is it so big as to take up nearly 300Mb of disk space when printed out? 这个对象到底是什么?为什么它这么大,以至于在打印输出时要占用近300Mb的磁盘空间?

I cannot help but wonder if such complexity is apt to cause performance issues in every-day code. 我忍不住想知道,这种复杂性是否易于在日常代码中引起性能问题。 For example, I am not printing out the contents of the $instance variable in my every-day code, but I surely return the humongousness from a method call. 例如,我没有在日常代码中打印$instance变量的内容,但是我肯定从方法调用中返回了笨拙。 Does that mean it is a 300Mb variable that gets passed from ie the $em->find(Item::class, 2); 这是否意味着它是从$em->find(Item::class, 2);传递的300Mb变量$em->find(Item::class, 2); call above? 在上面打电话吗?

(Very) Partial Listing (非常)部分上市

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]

You can't dump a proxy object without XDebug or similar tools (which limit the dumped object size). 没有XDebug或类似工具(限制了转储对象的大小),您将无法转储代理对象。

The problem is really, really simple: 问题非常非常简单:

Proxy -> references EntityManager -> references UnitOfWork -> contains Proxy 代理->引用EntityManager->引用UnitOfWork->包含代理

This obviously leads to a recursive data-structure dump, which in turn leads to a mess any time you try to dump it without sensible limits. 显然,这会导致递归的数据结构转储,进而在您每次尝试无合理限制地转储时都会导致混乱。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM