2016-02-12 33 views
3

我有一个字段的实体,不包含在表单中,但是基于其他字段值进行计算,该值与输入一起提供。 目前该值设置在生命周期回调:在刷新实体之前计算唯一别名

use Doctrine\ORM\Mapping as ORM; 

/** 
* @ORM\PrePersist 
* @ORM\PreUpdate 
*/ 
public function prePersist() {...} 

我想保持这个值在数据库表列的范围唯一的,并且在保存之前修改它,直到它是一个且只有一个。

  • 我试图用UniqueEntity,但在实体对象创建的时间字段的值为NULL(未知)。所以在验证之后它会保留在表单提交之后。当实际调用prePersist()时,该值显示并且未经验证就进入数据库。

  • 我可能会尝试获取EntityRepository实例,并尝试将检查作为prePersist()的SQL查询,但它看起来非常难看。

  • 我可能会尝试使用一种哈希函数,如md5或sha1,它们主要保证值的唯一性,但哈希函数有冲突,并且我希望保持该值“可读性”。

请向我提出一个“Symfony”风格的解决方案。

+1

我真的不明白你需要什么。你是否想要一个好方法来生成一个自动创建并分配给每个新条目的uniq和可读标识符? – chalasr

+0

“人类可读”是什么意思?你喜欢哪种格式? – Pipe

+0

是的,我需要一种基于用户输入的独特可读标识符生成方式。如果可能的话,它应该更新数据库记录编辑,并且在任何情况下都是唯一的。如果需要,“可读性”意味着易于阅读和记忆(可能部分)。 – anton

回答

1

由于这个话题的答案和评论,我能意识到我解决它与Symfony2的架构冲突的任务:

  • 获得用户从表格输入
  • 验证输入
  • 计算自动字段
  • 再次验证

可接受的溶液看起来像的提出的方法,其中包括一些技巧“人可读性”的组合:别名从由这样的方案输入验证后的形式的参数的子集连接在一起:

use Doctrine\ORM\Mapping as ORM; 

/** 
* @ORM\PrePersist 
* @ORM\PreUpdate 
*/ 
public function prePersist() 
{ 
    ... 
    $alias = "{$param1}-{$param2}-...-{$paramN}-" . md5(time() . rand(0, 9)); 
    ... 
} 

因此,它是独一无二的,因为md5()连接到最终连接而成PARAMS显著降低碰撞的风险。即使我们从列表中更改参数(例如用户使用编辑表单更新实体),该值仍然是唯一的。另外我们得到了消毒,但是可读并且在别名开始处具有感测参数,这有助于在手动调查的情况下记忆。

该解决方案的缺点是可变长度,这取决于参数。但他们可能缩短到固定长度。

+0

您应该接受您的答案,这是一种符合您需要的干净方法。 – chalasr

2

我的第一个想法是:使用doctrine GUID/UUID generator

但是,它只能作为一个标识符出来,你想要一个简单的字段。

另外,我提出的是有点复杂的需求,我明白你不想写很多代码,并有一个复杂的模式。

创建自定义标识特定的实体:

/** 
* @ORM\Entity 
*/ 
class UniqIdentifier 
{ 
    /** 
    * @ORM\Column(type="guid") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="UUID") 
    */ 
    private $id; 
} 

,并添加您的实体如下:

/** 
* @ORM\OneToOne(targetEntity="UniqIdentifier", cascade={"persist", "remove"}, orphanRemoval=true) 
*/ 
protected $uniqId; 
+1

这是一个有趣的方法,谢谢。这很遗憾,但它不允许包含用户数据从请求到UUID生成(我称之为“人工可读性”,并且用于手动事件调查 - 如果别名包含除hash之外的某些单词,则很容易阅读其他)。 – anton

1

,以实例期间避免空值创建:(一点儿也不保证独特id)

md5(uniqid(rand(), true)) 

并且为了始终保持唯一值:

md5(uniqid($your_user_login, true)) 

md5(uniqid($entity_id, true)) 
+0

我同意这种做法。 '时间()。 rand()'也给出了唯一的id。但别名太无意义 - 难以手动搜索和调查某些案例。 – anton

+0

别名是什么意思? entity_id? – CodeIsLife

+0

我的别名是entity_id的替代方法,用于目的,当使用整数ID无效或不安全时。 – anton