Я сделал это для менеджера страниц в PyroCMS, но это нелегкая задача.
Каждая страница имеет свой собственный slug и parent_id, затем, чтобы прочитать правильную страницу, она проходит через каждый из слагов страницы и присоединяется к дочернему элементу. Он знает, сколько детей, поэтому, если есть 5 детей, он выбирает 5-ую таблицу, объединенную самостоятельно.
Вот пример кода:
public function get_by_path($segments = array())
{
// If the URI has been passed as a string, explode to create an array of segments
if(is_string($segments))
{
$segments = explode('/', $segments);
}
// Work out how many segments there are
$total_segments = count($segments);
// Which is the target alias (the final page in the tree)
$target_alias = 'p'.$total_segments;
// Start Query, Select (*) from Target Alias, from Pages
$this->db->select($target_alias.'.*');
$this->db->from('pages p1');
// Loop thorugh each Slug
$level = 1;
foreach( $segments as $segment )
{
// Current is the current page, child is the next page to join on.
$current_alias = 'p'.$level;
$child_alias = 'p'.($level - 1);
// We dont want to join the first page again
if($level != 1)
{
$this->db->join('pages '.$current_alias, $current_alias.'.parent_id = '.$child_alias.'.id');
}
// Add slug to where clause to keep us on the right tree
$this->db->where($current_alias . '.slug', $segment);
// Increment
++$level;
}
// Can only be one result
$this->db->limit(1);
return $this->db->get()->row();
}
Это немного ненормально, но работает отлично. Это может быть очень медленным, поэтому PyroCMS также поддерживает справочную таблицу с идентификатором и URI страницы для быстрого сопоставления.
Вы можете увидеть всю модель здесь:
http://github.com/philsturgeon/pyrocms/blob/master/application/modules/core/pages/models/pages_m.php