Doctrine中的默认值

Jie*_*eng 321 php orm doctrine-orm

如何在Doctrine 2中设置默认值?

小智 508

<?php
/**
 * @Entity
 */
class myEntity {
    /**
     * @var string
     *
     * @ORM\Column(name="myColumn", type="integer", options={"default" : 0})
     */
    private $myColumn;
    ...
}
Run Code Online (Sandbox Code Playgroud)

请注意,这使用SQL DEFAULT,某些字段(如BLOB和)不支持TEXT.

  • 这应该是选定的答案! (22认同)
  • 我使用这个和接受的答案来涵盖所有基础.还有一个注意事项,您也可以这样做:`options = {"default":0}`小心使用"而不是",因为它会导致我的学说版本出错. (5认同)
  • 接得好!似乎官方文档中没有选项= {"default"= 0}选项 (4认同)
  • 使用迁移时,这绝对是所需的解决方案,否则`doctrine:migrations:diff` 将无法理解您设置了默认值,因为它只扫描注释/元数据而不是 PHP 默认值。 (3认同)
  • 仅供参考,`options`参数对于`unsigned`值也很有用.看到这个[答案](http://stackoverflow.com/questions/7692686/doctrine-2-unsigned-value/14221973#14221973) (2认同)
  • @Matt他可能会说,因为它是一个没有记录的功能,而且未展开的功能很容易被删除.正如现在所记录的那样,您应该安全地使用它. (2认同)

rom*_*anb 374

数据库默认值不受"支持"支持.使用数据库缺省值的唯一方法是通过columnDefinitionmapping属性,您可以在其中为字段映射到的列指定SQL代码段(DEFAULT包括原因).

您可以使用:

<?php
/**
 * @Entity
 */
class myEntity {
    /**
     * @var string
     *
     * @Column(name="myColumn", type="string", length="50")
     */
    private $myColumn = 'myDefaultValue';
    ...
}
Run Code Online (Sandbox Code Playgroud)

首选PHP级别的默认值,因为它们也适用于新创建的和持久化的对象(在持久保存新对象以获取默认值后,Doctrine不会返回到数据库).

  • @artragis将您的instanciation放在实体构造函数中 (46认同)
  • 使用此方法进行迁移时必须小心,因为任何现有行都将导致迁移失败. (12认同)
  • 但这里有一个问题:如果我设置"日期时间"类型怎么办? (11认同)
  • 不要使用实例化区域来设置变量......相信我,会发生坏事.请改用构造函数区域. (6认同)
  • 我建议在注释中使用columnDefinition,否则有人将使用mysql客户端或phpmyadmin,这些值将是错误的... (3认同)
  • 你还需要做 , options={"default" : 0} 如果你不想在不可为空的字段上搞砸你的迁移 (2认同)

Jer*_*cks 62

在您的实体中设置构造函数并在其中设置默认值.

  • Doctrine推荐的解决方案:http://www.doctrine-project.org/docs/orm/2.1/en/reference/faq.html (26认同)
  • 有关该主题的常见问题解答的新链接:https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/faq.html#entity-classes (4认同)
  • 如果添加需要具有默认值的新字段,则不会更新现有实体.所以这不应该是答案.取决于你究竟需要做什么 (3认同)

Sta*_*kyi 53

使用:

options={"default":"foo bar"}
Run Code Online (Sandbox Code Playgroud)

并不是:

options={"default"="foo bar"}
Run Code Online (Sandbox Code Playgroud)

例如:

/**
* @ORM\Column(name="foo", type="smallint", options={"default":0})
*/
private $foo
Run Code Online (Sandbox Code Playgroud)

  • 对不起,你是对的.所以你可以在这个页面上找到解释:[doctrine-orm annotations-reference](http://doctrine-orm.readthedocs.io/projects/doctrine-orm/en/latest/reference/annotations-reference.html#column ) (2认同)
  • 上面评论中的链接已失效。尝试[这个](https://www.doctrine-project.org/projects/doctrine-orm/en/2.8/reference/annotations-reference.html#column)。 (2认同)

Cal*_*ino 50

更新

阅读 Symfony 文档的另一个原因永远不会超出趋势.对于我的具体情况有一个简单的解决方案,并将field type选项empty_data设置为默认值.

同样,此解决方案仅适用于表单中的空输入将DB字段设置为null的情况.

背景

以前的答案都没有帮助我解决我的具体情况,但我找到了解决方案.

我有一个表单字段需要表现如下:

  1. 不需要,可以留空.(使用'required'=> false)
  2. 如果留空,则应默认为给定值.为了获得更好的用户体验,我没有在输入字段上设置默认值,而是使用了html属性"占位符",因为它不那么突兀.

然后我尝试了这里给出的所有建议.让我列出一下:

  • 为entity属性设置默认值:
<?php
/**
 * @Entity
 */
class myEntity {
    /**
     * @var string
     *
     * @Column(name="myColumn", type="string", length="50")
     */
    private $myColumn = 'myDefaultValue';
    ...
}
Run Code Online (Sandbox Code Playgroud)
  • 使用选项注释:
@ORM\Column(name="foo", options={"default":"foo bar"})
Run Code Online (Sandbox Code Playgroud)
  • 在构造函数上设置默认值:
/**
 * @Entity
 */
class myEntity {
    ...
    public function __construct()
    {
        $this->myColumn = 'myDefaultValue';
    }
    ...
}
Run Code Online (Sandbox Code Playgroud) 它们都不起作用,因为Symfony如何使用您的Entity类.

重要

Symfony表单字段覆盖在Entity类上设置的默认值. 这意味着,您的数据库架构可以定义一个默认值,但如果在提交表单时将非必填字段留空,则方法form->handleRequest()内部form->isValid()将覆盖Entity类上的默认值并将它们设置为输入字段值.如果输入字段值为空,则将Entity属性设置为null.

http://symfony.com/doc/current/book/forms.html#handling-form-submissions

我的解决方法

form->handleRequest()form->isValid()方法内部设置控制器上的默认值:

...
if ($myEntity->getMyColumn() === null) {
    $myEntity->setMyColumn('myDefaultValue');
}
...
Run Code Online (Sandbox Code Playgroud)

不是一个漂亮的解决方案但它的工作 我可能会做一个validation group但是可能会有人把这个问题视为数据转换而不是数据验证,我留给你决定.


覆盖Setter(不起作用)

我也试图以Entity这种方式覆盖setter:

...
/**
 * Set myColumn
 *
 * @param string $myColumn
 *
 * @return myEntity
 */
public function setMyColumn($myColumn)
{
    $this->myColumn = ($myColumn === null || $myColumn === '') ? 'myDefaultValue' : $myColumn;

    return $this;
}
...
Run Code Online (Sandbox Code Playgroud)

即使它看起来更干净,但它不起作用.原因是邪恶form->handleRequest()方法不使用Model的setter方法来更新数据(深入form->setData()了解更多细节).


Gig*_*ili 23

以下是如何在 PHP 8 中使用属性来做到这一点。

#[ORM\Column(type: Types::BOOLEAN, nullable: false, options: ['default' => false])]
#[Assert\NotNull()]
private bool $isFavorite = false;
Run Code Online (Sandbox Code Playgroud)


Jie*_*eng 16

我使用的解决方法是LifeCycleCallback.还在等待,看看是否还有更多的"原生"方法@Column(type="string", default="hello default value").

/**
 * @Entity @Table(name="posts") @HasLifeCycleCallbacks
 */
class Post implements Node, \Zend_Acl_Resource_Interface {

...

/**
 * @PrePersist
 */
function onPrePersist() {
    // set default date
    $this->dtPosted = date('Y-m-d H:m:s');
}
Run Code Online (Sandbox Code Playgroud)

  • 对于未来的读者,不要依赖生命周期回调 :) 甚至 Marco Pivetta 也反对他们。 (3认同)

And*_*lin 13

您也可以使用xml来完成:

<field name="acmeOne" type="string" column="acmeOne" length="36">
    <options>
        <option name="comment">Your SQL field comment goes here.</option>
        <option name="default">Default Value</option>
    </options>
</field>
Run Code Online (Sandbox Code Playgroud)


Put*_*tna 8

以下是我为自己解决的问题.下面是一个具有MySQL默认值的Entity示例.但是,这还需要在实体中设置构造函数,并在此处设置默认值.

Entity\Example:
  type: entity
  table: example
  fields:
    id:
      type: integer
      id: true
      generator:
        strategy: AUTO
    label:
      type: string
      columnDefinition: varchar(255) NOT NULL DEFAULT 'default_value' COMMENT 'This is column comment'
Run Code Online (Sandbox Code Playgroud)


小智 7

在mysql数据库上也适用于我:

Entity\Entity_name:
    type: entity
    table: table_name
    fields: 
        field_name:
            type: integer
            nullable: true
            options:
                default: 1
Run Code Online (Sandbox Code Playgroud)


met*_*152 6

这些都不适合我.我在doctrine的网站上找到了一些文档,说明直接设置值来设置默认值.

http://doctrine-orm.readthedocs.io/projects/doctrine-orm/en/latest/reference/faq.html

private $default = 0;
Run Code Online (Sandbox Code Playgroud)

这插入了我想要的值.