Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/271.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php SilverStripe唯一URL(调试)_Php_Silverstripe - Fatal编程技术网

Php SilverStripe唯一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

在这个数据对象中有一个用户提供的字段Title,必须将其转换为唯一的URL slug

期望的结果:重复URL的值应该有一个后缀。因此,保存标题为
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
}