【问题标题】:Is it possible to get the actual class name instead of the proxy class name from a lazy loaded object using Doctrine's MongoDB ODM?是否可以使用 Doctrine 的 MongoDB ODM 从延迟加载的对象中获取实际的类名而不是代理类名?
【发布时间】:2016-11-23 03:13:17
【问题描述】:

在开始升级工作以将我的应用程序更新到 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/bundles:

  • 教义/mongodb ^1.3.0
  • 学说/mongodb-odm ^1.1.0
  • 学说/mongodb-odm-bundle ^3.2.0

【问题讨论】:

  • 澄清一下,您是否希望获得“MyClass”而不是“MongoDBODMProxies\__CG__\\...\\MyClass”?
  • 对不起,我应该更清楚,是和否:我想要 FQCN 没有代理前缀,所以基本上是类的实际 FQCN,所以如果类位于 AcmeBundle\Documents\MyClass并且代理类显示MongoDBODMProxies\\__CG__\\AcmeBundle\\Documents\\MyClass 我想要AcmeBundle\Documents\MyClass 类名。我会更新以增加清晰度。

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


【解决方案1】:

查看ClassUtils 类中的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"

【讨论】:

  • 太棒了。奇怪的是,getRealClass 似乎在类名的末尾提供了额外的数据,看起来像一个位置标记 (@XXXXX) 并且不起作用,但是当我使用类 utils 中的getClass 时,一切正常。这可能只是一个奇怪的副作用。仍然非常感谢您向我指出该实用程序,我以前不知道它!
  • 在仔细阅读 ClassUtils 的代码后,使用 getClass 似乎是正确的。 $source 是一个实例,而不是一个字符串 - 我的错误。很高兴我能帮上忙。谢谢!
猜你喜欢
  • 2018-02-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-04
  • 2022-01-03
相关资源
最近更新 更多