问题
In my ORM code I have an Entity with a field fined like so:
//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.
And everything was fine, Until
Next, I have changed the $productId
column to ManyToOne
Relationship on my Item
Entity class, like so:
/**
* @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?
Two million, three hundred and ninety two thousand, six hundred lines lines of print_r
output.
looking at the print-out I see that DoctrineProxies\__CG__\Application\Entity\Product
Object contains 2,392,564
lines printed by print_r
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?
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. Does that mean it is a 300Mb variable that gets passed from i.e. the $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]
回答1:
You can't dump a proxy object without XDebug or similar tools (which limit the dumped object size).
The problem is really, really simple:
Proxy -> references EntityManager -> references UnitOfWork -> contains Proxy
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.
回答2:
DoctrineProxies\__CG__\Application\Entity\Product
is a proxy class... which means that doctrine doesn't actually fetch the entity from the database (for performance) unless it is needed (i.e. calling $product->getName()
those proxy Classes are in a recursive loop with eachother and are VERY large as you saw... most of the information there you don't really need unless you are diving deep ... you should never use print_r
... in the new symfony 2.7+ i think there is a function called dump()
in debug mode ... if you use that to print the entity it has loop protection and it just shows reference numbers ... you can also use the \Doctrine\Common\Util\Debug::dump()
that also will print out a smaller list than 2^234234234 lines ...
来源:https://stackoverflow.com/questions/37076711/why-does-doctrine-orm-configurations-doctrineproxies-object-contain-the-unive