2012-03-29 30 views
14

我有一个Symfony2窗体,其中包含一个可选的文本字段,其中包含一个名为recap的可选文本字段。Symfony2形式将空字符串解释为空

recap场节省了完美时,有它的一些文字,但是当字段为空,我得到这个错误:

SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'recap' cannot be null 

这是正确的 - 列recap不能null。我故意这样设定它。 Null意味着未知。当用户离开recap空白时,recap的值不是未知数;它是空白的。

我的问题是如何得到Symfony保存recap''当它是空白,而不是null

+0

这难道不是更大的问题上学说的结束?在这种情况下,您可以将类的属性的默认值设置为空字符串,我们使用自定义的'DBAL \ Types',它将空值转换为emppty字符串。 – dbrumann 2012-03-29 15:41:01

+0

我认为你说的是​​对的主义的结局是正确的。将默认值设置为空值对我来说不起作用,尽管我已经在多个地方看到了应该起作用的索赔,这让我感到困惑。 – 2012-03-29 16:02:39

回答

15

转到您的实体并转到变量的声明。

/** 
* @var string $name 
* 
* @ORM\Column(type="string", length=50) 
*/ 
public $recap = ''; 

您可以为$摘要分配默认值。

或其他途径,当你有函数setRecap你可以检查是否为空或未设置,并设置你的期望值。

public function setRecap($recap) { 
    $this->recap = !isset($recap) ? '': $recap; 
} 

或者你在你的表单中设置默认值Type键入'',但我认为那么它不是你所期望的。

+0

有趣。你们两个的建议都没有单独工作,但是当他们一起使用时,他们做到了这一点谢谢! – 2012-03-29 15:54:40

+0

不要这样做,Doctrine可以在创建实体时删除您的更改... – 2012-08-12 12:15:03

+2

@ThomasDecaux:那么您应该遵守教义;)那就错了......教义覆盖并只构建不存在的函数。 – Stony 2012-08-12 12:16:22

-1

我也遇到过这个问题。和优雅的解决方案是向我建议是:让这个定义@ORM\Column(type="string", length=50, nullable=true)

+0

不要在数据库中使用可为空的值!它对性能非常不好,更喜欢“”或0. – 2012-08-12 11:52:52

+0

@ThomasDecaux你有任何的参考?这是针对特定的RDBMS吗? – ncatnow 2013-07-25 03:49:09

+1

这里有一个很好的关于NULL值(对于SQL类似)的性能问题的讨论:[link](http://stackoverflow.com/questions/1017239/how-do-null-values-affect-performance-in-a -database-search) – Ben 2013-08-01 03:53:48

6

我认为你正在做这个问题的错误的方式:当用户离开概括空白值未知的,因为没有提供。例如,你不要说空的生日日期字段意味着生日等于'',但生日是未知的。这同样适用于编辑部地址,等...

因此,如果不要求用户填写此字段,它似乎是最相关的反应实际上是在设置你的领域为可空

11

真,失去了它多小时;-(的“转型”是硬编码的组件form.php的行1113!

private function viewToNorm($value) 
{ 
    $transformers = $this->config->getViewTransformers(); 

    if (!$transformers) { 
     return '' === $value ? null : $value; 
    } 

    for ($i = count($transformers) - 1; $i >= 0; --$i) { 
     $value = $transformers[$i]->reverseTransform($value); 
    } 

    return $value; 
} 

在我看来,它是一个大错误(因为是DataTransformer的作用,而不是形式)。因此,解决方案是创建您自己的DataTransformer并将其与文本类型相关联。目前,我失去了这么多的时间与Symfony2中,总是在寻求资源这几样小黑客;-(的

+2

我正在接近记录一个关于这个问题的bug,因为它看起来完全愚蠢。如果你真的仔细阅读他们的文档,它基本上说,如果一个文本字段被标记为需要,一个空字符串将最终作为一个空字符串,但是,如果该字段是可选的,一个空字符串将被转换为'null'。请参阅[empty_data](http://symfony.com/doc/current/reference/forms/types/text.html#empty-data)和[required](http://symfony.com/doc/current/reference/所需表格/类型/ text.html#)。 – jxmallett 2015-12-11 07:00:14

+0

@ thomas-decaux我和Symfony2有同样的痛苦 - 你还在使用它还是找到了更好的解决方案? – PeterB 2016-05-12 09:33:08

+0

@jxmallett你有没有记录过一个错误?它会为Symfony做一个很棒的DX(Developer eXperience)门票 – PeterB 2016-05-12 09:33:14

2

对面类似的错误在Symfony2中传来:

我的实体:

/** 
* @ORM\Column(type="boolean") 
*/ 
protected $Valid; 

我形式:

$builder->add('Valid', 'hidden'); 

现在对于真值,字段与值正确呈现=“1”,但对于假值字段呈现用值=“”,这导致:

SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'Valid' cannot be null 

虽然我期望它呈现为值=“0”。

当然setValid()方法可以增强确立正确的价值:

public function setValid($valid) 
{ 
    $this->Valid = ($valid ? true : false); 
} 

哪些变通的问题,而不是修复它。

7

我对这个问题的另一种解决方案:

创建虚拟类

class EmptyString { 
    public function __toString() { 
     return ''; 
    } 
} 

,并设置

$builder->add('recap', 'text', [ 
    'empty_data' => new EmptyString(), 
]); 

当实体将被存储到数据库,它会自动转换为空字符串。

+0

这也是我的解决方案。我发现空的文本框被视为空值,然后直接强制进入一个sql语句,绕过实体设置器,所以你不能在那里捕获空值。 – 2016-05-03 07:44:36

+1

为什么不做'empty_data'=>''? – 2016-06-16 12:02:36

+0

@the_nuts因为它已经转换为null,至少在symfony 2.4 – glerendegui 2016-09-08 16:27:38

2

在形式,你可以这样做:

$builder 
->add('optionalField', TextType::class, ['required'=>false, 'empty_data'=>''])