我有多个对象,我希望通过人类可读的URL访问,因此我为所有数据库记录生成别名(例如blog.com/this-is-an-alias/)。
自动生成这些内容的最佳做法是什么?
我目前正在勾选模型的'values()'方法并在那里生成一个新的别名(基于所需的'name'字段),但我不禁觉得这可以更优雅地使用,比如说,Kohana的内置过滤器。
这是精简模型:
class Model_Category extends ORM {
// relevant rules:
public function rules(){
return array(
'alias' => array(
array('max_length', array(':value', 63)),
array(array($this, 'unique'), array(':field', ':value')),
),
'name' => array(
array('max_length', array(':value', 63)),
),
// (...)
);
}
// overrides default method:
public function values(array $values, array $expected = NULL){
if(!$this->_loaded){
if($values['name'] && !$values['alias'])
$values['alias'] = Helper_Form::to_alias($values['name']);
}
return parent::values($values, $expected);
}
}
仅供参考,to_alias函数看起来像这样:
return strtolower(substr(trim(preg_replace('/[^0-9a-zA-Z]+/','-',$str),'-'),0,63));
所以,我的问题:
答案 0 :(得分:5)
我会像你提到的那样使用过滤器进行自动生成。以下是我这样做的概念。对于过滤功能,您可以传递一些特定参数,例如:model
,:value
,:field
,在这种情况下我会使用:model
来访问当前模型&#39 ; s属性。
class Model_Category extends ORM {
public function filters()
{
return array(
'slug' => array(
array(array($this, 'create_slug'), array(':model')),
),
);
}
public function create_slug($model)
{
$model = ($model instanceof ORM) ? $model : $this;
$number = 1;
$slug = UTF8::transliterate_to_ascii($model->name);
$slug = preg_replace("/[^a-zA-Z0-9\/_|+ -]/", '', $slug);
$slug = UTF8::strtolower(trim($slug, '-'));
$slug = preg_replace("/[\/_|+ -]+/", '-', $slug);
while ( ! $this->unique_slug($slug))
{
if ( ! preg_match('/\d+$/', $slug))
{
$slug .= '-'.$number;
}
$slug = preg_replace('/\d+$/', $number++, $slug);
}
return $slug;
}
public function unique_slug($slug)
{
return (bool) DB::select(array('COUNT("*")', 'total_count'))
->from($this->_table_name)
->where('slug', '=', $slug)
->where($this->_primary_key, '!=', $this->pk())
->execute($this->_db)
->get('total_count');
}
}
以上示例可能不完全正常,但我希望您明白这一点。