Php SilverStripe唯一URL(调试)
在这个数据对象中有一个用户提供的字段Title,必须将其转换为唯一的URL slug 期望的结果:重复URL的值应该有一个后缀。因此,保存标题为Php SilverStripe唯一URL(调试),php,silverstripe,Php,Silverstripe,在这个数据对象中有一个用户提供的字段Title,必须将其转换为唯一的URL slug 期望的结果:重复URL的值应该有一个后缀。因此,保存标题为Foo的两条记录应导致一条记录的Foo列值为URL,第二条记录的同一列值应为Foo-2 public function onBeforeWrite() { parent::onBeforeWrite(); // Sanitize Title field to use for URL $filter = URLSegmentFil
Foo
的两条记录应导致一条记录的Foo
列值为URL
,第二条记录的同一列值应为Foo-2
public function onBeforeWrite() {
parent::onBeforeWrite();
// Sanitize Title field to use for URL
$filter = URLSegmentFilter::create();
$this->URL = $filter->filter($this->Title);
// If URL is not unique, add suffix
$i = 1;
while($this->uniqueURL($this->URL)) {
$i++;
$this->URL = $this->URL . "-" . $i;
}
}
方法:uniqueURL(在同一类中)
保存Foo
两次将导致Foo
和Foo-2
当保存两个标题相同的记录时,Foo会产生两个URL字段,其中包含
Foo
为什么有两个Foo
URL?
如果在插入所有记录之前检查数据库,这意味着该检查将无法在记录批上工作
不要使用循环计数唯一URL
您不需要每次循环检查并增加计数($i
)。在性能方面,最好在查询中执行COUNT()
,并在下次插入时使用该值
// The following does exactly the same with just 1 query. No loop needed.
$count = DB::query("SELECT COUNT(*) FROM Table WHERE Title LIKE '{$filteredTitle}'")->value();
if ($count > 1) {
$filteredTitle .= "-" . $count;
}
$this->URL = $filteredTitle
解决方案
要执行此操作,唯一的可能是在保存数据之前查询数据并检查记录
或者,一个具有相同结果的更简单的解决方案是,您可以更改onAfterWrite()
中的url,并选中“使用与数字相同的标题数量”
public function onAfterWrite() {
parent::onAfterWrite();
// Sanitize Title field to use for URL
$filter = URLSegmentFilter::create();
$filteredTitle= $filter->filter($this->Title);
$count = DB::query("SELECT COUNT(*) FROM Table WHERE Title LIKE '{$filteredTitle}'")->value();
if ($count > 1) {
$filteredTitle .= "-" . $count;
}
$this->URL = $filteredTitle
}
你的问题是什么,第一种情况是否需要是
foo
和foo-2
以及第二种情况?或者在这两种情况下都是foo-1
和foo-2
?foo
用于第一种情况,而foo-2
用于第二种情况,效果非常好。else
语句是必需的,否则$this->URL
在唯一时将为空。啊,我错过了你绝对正确的答案,我更改了答案以确保正确。现在看起来好多了;)
public function onAfterWrite() {
parent::onAfterWrite();
// Sanitize Title field to use for URL
$filter = URLSegmentFilter::create();
$filteredTitle= $filter->filter($this->Title);
$count = DB::query("SELECT COUNT(*) FROM Table WHERE Title LIKE '{$filteredTitle}'")->value();
if ($count > 1) {
$filteredTitle .= "-" . $count;
}
$this->URL = $filteredTitle
}