是否可以使用Doctrine的MongoDB ODM从延迟加载的对象中获取实际的类名而不是代理类名?

时间:2016-07-20 03:30:28

标签: php mongodb doctrine-orm symfony doctrine-odm

在开始升级工作以将我的应用程序更新到Symfony 3之前,并且在将几个库(包括Doctrine)升级到更新版本之前,我能够将查询中的引用与先前查询的结果进行比较。我能够通过将先前查询的结果中的每个项的派生类名(例如get_class($source))与新查询中的数据库引用上的_doctrine_class_name字段进行匹配来实现此目的。这将适当地过滤掉不正确类型的文档。

自从升级我的依赖项后,当我获得源的派生类名时,我将返回代理而不是实际的类名,例如: MongoDBODMProxies\\__CG__\\AcmeBundle\\Documents\\MyClass代替AcmeBundle\Documents\MyClass

我试图在这种情况下过滤的对象集合是Activity个对象,它们的属性是$source属性,它是一个开放类型,也就是说没有明确的鉴别器映射它,因为我希望它可能能够保存任何文档。我想要再次使用的是一个查询,它使用ID和类名通过匹配的源过滤这些活动。查询代码如下所示:

public function findAllBySource($sources = array(), $date = null, $limit = 50)
{
    $qb = $this->createQueryBuilder()->limit($limit)->sort('date', 'DESC');

    if (!empty($date)) {
        $qb->field('date')->lte($date);
    }

    $qb->addOr($qb->expr()->field('source')->exists(false));
    foreach ($sources as $source) {
        // $source is initialized as a proxy to the real class here
        // using get_class($source) returns the class name to the
        // proxy, not the actual FQCN, e.g. AcmeBundle\Document\MyClass
        $expr = $qb->expr()
            ->field('source.$id')->equals(new \MongoId($source->getId()))
            ->field('source._doctrine_class_name')->equals(get_class($source));
        $qb->addOr($expr);
    }
    $query = $qb->getQuery();
    return array_values($query->execute()->toArray());
}

对于它的价值,我使用以下版本的Doctrine和MongoDB ODM / bundle:

  • doctrine / mongodb ^ 1.3.0
  • doctrine / mongodb-odm ^ 1.1.0
  • doctrine / mongodb-odm-bundle ^ 3.2.0

1 个答案:

答案 0 :(得分:1)

ClassUtils类(Doctrine Common的一部分)中查看getClass:

<?php

// $source is an instance of MongoDBODMProxies\\__CG__\\AcmeBundle\\Documents\\MyClass

$source = Doctrine\Common\Util\ClassUtils::getClass($source);

echo $source; // $source should now be "AcmeBundle\Documents\MyClass"