Приложение блога Codeigniter: избегайте повторяющихся ошибок ввода для слаг

Я работаю над базовым блоговое приложение в Codeigniter 3.1.8 и Bootstrap 4. posts стол имеет slug столбец, который я намерен использовать при создании SEO-дружественных URL.

Поскольку слаг каждого отдельного сообщения будет частью его URL, slug колонка, конечно, уникальный. Я использую КИ url_title() метод для сделать из заголовка поста:

$slug = url_title($this->input->post('title'), 'dash', TRUE);

Учитывая вышеописанную ситуацию, очевидно, что возникает проблема, когда 2 сообщения имеют одинаковый заголовок («Кто любит бабочку?»):

Duplicate entry 'who-loves-a-butterfly' for key 'slug'

Мне нужен способ заставить дублирующийся титульный пост генерировать «пронумерованный» слаг: «who-loves-a-butterfly-1» и так далее, если это необходимо.

Документация Codeigniter 3 не предоставляет такой способ для url_title() метод? Есть ли способ, которым я мог бы изменить его или альтернативу?

1

Решение

Есть много творческих подходов, которые вы могли бы использовать. Все зависит от ваших личных предпочтений.

Первый, с включенным построителем запросов, будет использовать встроенный form_validation и проверьте, соответствует ли ваш слаг is_unique и если это не так, измените его немного и перепроверьте, пока проверка не пройдет. Даже если form_validation используется в основном для проверки и дезинфекции пользовательского ввода, вы можете использовать его практически для чего угодно.

Другой подход заключается в том, чтобы всегда убедиться, что вы получаете уникальный слаг с первой попытки, добавив одноразовый номер, случайное число или какой-то другой уникальный параметр к сгенерированному слагу перед вставкой. Например:

$slug = url_title($this->input->post('title'), 'dash', TRUE).strtotime(date('Y-m-d H:i:s'));

Вышеприведенный, который, возможно, является самым простым из возможных подходов, будет работать до тех пор, пока в одну и ту же секунду не будут созданы две записи с одинаковым названием. Это уменьшит вероятность столкновения (почти) полностью.

Третье решение, немного более громоздкое, будет включать расчет основного слагаемого с помощью $slug = url_title($this->input->post('title'), 'dash', TRUE); а потом:

1.- передать слаг в простой запрос к базе данных (либо прямо в контроллере, либо внутри модели, на ваш выбор)

$this->db->select('count(*) as slugcount');
$this->db->from('your_table');
$this->db->where('slug', $slug);

$query = $this->db->get();
return $query->row(0)->slugcount;

Если слаг действительно уникален, вам будет возвращено 0, если есть одна предыдущая запись, вам будет возвращено 1 и так далее.

После этого вы выбираете:
Когда вы в первый раз создаете слаг, добавьте «-0» или «-1» (в зависимости от того, что лучше для SEO)
Во второй раз вы добавляете «-1» или «-2» (в зависимости от того, что вы определили в предыдущем)
И так далее, и так далее

Так, например, вы бы изменили свой слизень с

$slug = $slug."-".$slugcount;

это будет работать?

1

Другие решения

Я использую пользовательскую функцию sanitize () — обычно в модели — для создания этой уникальной записи слага:
пожалуйста, прочитайте комментарий к коду, так как он документирует поток

function sanitize($string,$table='posts'){
// sanitize string, remove Latin chars like 'ç ' and add - instead of white-space
// based on: http://stackoverflow.com/a/2103815/2275490
$str= strtolower(trim(preg_replace('~[^0-9a-z]+~i', '-', html_entity_decode(preg_replace('~&([a-z]{1,2})(?:acute|cedil|circ|grave|lig|orn|ring|slash|th|tilde|uml);~i', '$1', htmlentities($string, ENT_QUOTES, 'UTF-8')), ENT_QUOTES, 'UTF-8')), '-'));
// check how often header exists in table "posts"// add counted suffix to pretty_url if already exists
$query = $this->db  ->where('slug', $string)
->get($table);
if($query->num_rows()>0)
$str=$str.'-'.$query->num_rows(); // allways returns the latest number for same slug

return $str;
}
0

Вот полное решение, примененное в моем приложении блога:

в Posts_model модель:

public function slug_count($slug){
$this->db->select('count(*) as slugcount');
$this->db->from('posts');
$this->db->where('slug', $slug);
$query = $this->db->get();
return $query->row(0)->slugcount;
}

public function create_post($post_image, $slug) {
$data = [
'title' => $this->input->post('title'),
'slug' => $slug,
'description' => $this->input->post('desc'),
'content' => $this->input->post('body'),
'post_image' => $post_image,
'author_id' => $this->session->userdata('user_id'),
'cat_id' => $this->input->post('category'),
'created_at' => date('Y-m-d H:i:s')
];
return $this->db->insert('posts', $data);
}

в Сообщений контроллер:

// Create slug (from title)
$slug = url_title($this->input->post('title'), 'dash', TRUE);
$slugcount = $this->Posts_model->slug_count($slug);
if ($slugcount > 0) {
$slug = $slug."-".$slugcount;
}
0
По вопросам рекламы [email protected]