不推荐: 主义 ORM 映射 UnderscoreNamingStrategy 不要让它知道数字

我正在使用 Symfony 4.3.8,但是我找不到任何关于这些反对意见的信息:

不支持用户: 不支持创建原则 ORM 映射 UnderscoreNamingStrategy 而不支持使用原则 ORM 3.0中的原则 ORM 映射 UnderscoreNamingStrategy 并将删除原则 ORM 3.0中的原则 ORM 映射 UnderscoreNamingStrategy 而不支持使用原则 ORM 映射 UnderscoreNamingStrategy。

不支持在不知道数字的情况下创建 Doctrine ORM Mapping UnderscoreNamingStrategy,并将在 Doctrine ORM 3.0中删除。

我在 Stacktrace 里搜索了一下,发现了这个:

class UnderscoreNamingStrategy implements NamingStrategy
{
private const DEFAULT_PATTERN      = '/(?<=[a-z])([A-Z])/';
private const NUMBER_AWARE_PATTERN = '/(?<=[a-z0-9])([A-Z])/';


/**
* Underscore naming strategy construct.
*
* @param int $case CASE_LOWER | CASE_UPPER
*/
public function __construct($case = CASE_LOWER, bool $numberAware = false)
{
if (! $numberAware) {
@trigger_error(
'Creating ' . self::class . ' without making it number aware is deprecated and will be removed in Doctrine ORM 3.0.',
E_USER_DEPRECATED
);
}


$this->case    = $case;
$this->pattern = $numberAware ? self::NUMBER_AWARE_PATTERN : self::DEFAULT_PATTERN;
}

在这个类中,构造函数总是在没有参数的情况下调用,所以 $numberAware 总是 false。

这个类是在文件中调用的,它是由 Symfony 依赖注入自动生成的,所以我不能“编辑”它..。

我想也许是在教义里:

doctrine:
orm:
auto_generate_proxy_classes: true
naming_strategy: doctrine.orm.naming_strategy.underscore
auto_mapping: true
mappings:
App:
is_bundle: false
type: annotation
dir: '%kernel.project_dir%/src/Entity'
prefix: 'App\Entity'
alias: App

但我没有找到任何选择,让数字意识到: (

21370 次浏览

In most cases I would just answer this sort of question with a comment but I suspect other developers might run into this issue. I poked around a bit and could not find any explicit documentation on this issue. Perhaps because the DoctrineBundle is under the control of the Doctrine folks and not the Symfony developers. Or maybe I am just a bad searcher.

In any event, between 4.3 and 4.4 the service name for the underscore naming strategy was changed.

# doctrine.yaml
orm:
# 4.3
naming_strategy: doctrine.orm.naming_strategy.underscore
# 4.4
naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware

And a deprecated message was added to warn developers to change the name. Would have been nice if the message was just a tiny bit more explicit but oh well. So if you are upgrading an existing app to 4.4 and beyond then you will probably need to manually edit your doctrine.yaml file to make the depreciation message go away.

Some more info (thanks @janh) on why the change was made: https://github.com/doctrine/orm/blob/2.8.x/UPGRADE.md#deprecated-number-unaware-doctrineormmappingunderscorenamingstrategy https://github.com/doctrine/orm/issues/7855

Still not really clear on why "they" chose to do things this way but oh well. You probably want to run "bin/console doctrine:schema:update --dump-sql" just to see if this impacts your database column names and adjust accordingly. The changes has been out for several weeks now and there does not seem to be many howls of outrage over the change so I guess most column names don't have embedded numbers. So far at least.

For those who works with symfony4.3 and still want this warning disapear you can add add new new service defintion in service.yaml

    custom_doctrine_orm_naming_strategy_underscore:
class: Doctrine\ORM\Mapping\UnderscoreNamingStrategy
arguments:
- 0
- true

and change the configuration of doctrine.yaml like this:

orm:
naming_strategy: custom_doctrine_orm_naming_strategy_underscore

before going straight forward committing this change I would suggest you to verify that passing true to the Doctrine\ORM\Mapping\UnderscoreNamingStrategy doesn't affect the expected behavior of your code.

// class UnderscoreNamingStrategy
/**
* Underscore naming strategy construct.
*
* @param int $case CASE_LOWER | CASE_UPPER
*/
public function __construct($case = CASE_LOWER, bool $numberAware = false)
{
if (! $numberAware) {
@trigger_error(
'Creating ' . self::class . ' without making it number aware is deprecated and will be removed in Doctrine ORM 3.0.',
E_USER_DEPRECATED
);
}


$this->case    = $case;
$this->pattern = $numberAware ? self::NUMBER_AWARE_PATTERN : self::DEFAULT_PATTERN;
}

Quick hint:

passing true to the c'tor will make the class use the NUMBER_AWARE_PATTERN instead of the DEFAULT_PATTERN

private const DEFAULT_PATTERN      = '/(?<=[a-z])([A-Z])/';
private const NUMBER_AWARE_PATTERN = '/(?<=[a-z0-9])([A-Z])/';