当字段有下划线时,Magic Doctrine2 finders?

Posted

技术标签:

【中文标题】当字段有下划线时,Magic Doctrine2 finders?【英文标题】:Magic Doctrine2 finders when field has underscore? 【发布时间】:2012-03-28 09:20:35 【问题描述】:

当字段中间有下划线时,我在使用 Doctrine2 的 find*() 魔术方法时遇到问题。

$repository->findByName("Hello"); // Works
$repository->findByIsEnabled(true);

实体 'Acme\SecurityBundle\Entity\Package' 没有字段 'isEnabled'。 因此,您不能在实体上调用“findByIsEnabled” 存储库。

这是 YAML 中用于复制错误的简单实体定义:

Acme\SecurityBundle\Entity\Package:
  type: entity
  repositoryClass: Acme\SecurityBundle\Repository\PackageRepository
  table: security_package
  id:
    id:
      type: integer
      generator:  strategy: AUTO 
  fields:
    name:
      type: string
      length: 255
      unique: true
    is_enabled:
      type: boolean

【问题讨论】:

【参考方案1】:

我记得遇到过同样的问题,并认为我通过写这样的东西解决了它:

$repository->findBy(array('is_enabled' => true));

让我们看一下代码:

<?php
/**
 * Adds support for magic finders.
 *
 * @return array|object The found entity/entities.
 * @throws BadMethodCallException  If the method called is an invalid find* method
 *                                 or no find* method at all and therefore an invalid
 *                                 method call.
 */
public function __call($method, $arguments)
   
    if (substr($method, 0, 6) == 'findBy') 
        $by = substr($method, 6, strlen($method));
        $method = 'findBy';
     else if (substr($method, 0, 9) == 'findOneBy') 
        $by = substr($method, 9, strlen($method));
        $method = 'findOneBy';
     else 
        throw new \BadMethodCallException(
            "Undefined method '$method'. The method name must start with ".
            "either findBy or findOneBy!"
        );  
       

    if ( !isset($arguments[0])) 
        // we dont even want to allow null at this point, because we cannot (yet) transform it into IS NULL.
        throw ORMException::findByRequiresParameter($method.$by);
    

    $fieldName = lcfirst(\Doctrine\Common\Util\Inflector::classify($by));

    if ($this->_class->hasField($fieldName) || $this->_class->hasAssociation($fieldName)) 
        return $this->$method(array($fieldName => $arguments[0]));
     else 
        throw ORMException::invalidFindByCall($this->_entityName, $fieldName, $method.$by);
    

重点在这里:

$fieldName = lcfirst(\Doctrine\Common\Util\Inflector::classify($by));

现在让我们看看分类:

<?php
/**
 * Convert a word in to the format for a Doctrine class name. Converts 'table_name' to 'TableName'
 *
 * @param string  $word  Word to classify
 * @return string $word  Classified word
 */
public static function classify($word)

    return str_replace(" ", "", ucwords(strtr($word, "_-", "  ")));

如果你想让它起作用,你似乎应该写你的字段“likeThis”。

【讨论】:

是的,我现在正在做同样的事情(作为一种解决方法),但我更喜欢“神奇”的方式。这是一个错误吗? 你能在文档中找到一个例子吗?我不能。类似问题in this other question,可能是魔法部分被劝阻了。 是的,但是在 Symfony 文档中,请查看:symfony.com/doc/current/book/doctrine.html,页面中间。 我认为这些幻灯片很好地解释了为什么会有“猎巫”:slideshare.net/jwage/doctrine-2-not-the-same-old-php-orm 快速浏览了一下,发现魔法很糟糕......但它没有回答问题:)

以上是关于当字段有下划线时,Magic Doctrine2 finders?的主要内容,如果未能解决你的问题,请参考以下文章

有哪些解决方案可以避免 Doctrine2 中聚合计数字段的 select(n+1) 问题?

A Guide to Python's Magic Methods

Doctrine2-完整创建数据库

在 Doctrine 2 中指定十进制字段类型时,比例和精度是啥意思?

Python笔记 · 魔法函数 / Magic Methods / Dunder Methods

在 Doctrine 2 中加载/保存字段时透明地执行 SQL 函数