Идеи и задумки по ЧПУ
Author Message
Amro    

В этой теме будут обсуждаться идеи реализации ЧПУ

Forever unshaven, red-eyed, detached from reality, with his cockroaches in my head. And let it always will be!

Amro    

Итак Ф-ция sed_url()

Нужно убрать лишний параметр alias, оставим только path

// $section - название скрипта, без ".php", например page, list, users.
// $param - список параметров, может быть в виде строки или в виде массива.
// $anchor - якорь вместе со #, например  #comments, #top и т.д.
// $header - ссылка или редирект
// $enableabs - а вот это интересная фишка, при передаче значения false везде заменяется & на & в основном нужно для rss
function sed_url($section, $param = '', $anchor = '', $header = false, $enableabs = true, $path = '') 
{     
    global $cfg, $sys; 
    
    // Убираем лишний & справа, в основном только для $more в PFS
    $param = preg_replace('/&$/', '', $param); //fix $more in PFS 
    
    // Проверям редирект ли это и врублены ли абсолютные урлы или хак для rss при использовании абсолютных урлов ($enableabs = false), там подставляется значение $cfg['mainurl']
    // т.е. для формировании через sed_url() ссылок в rss ленте, даже при использовании абсолютных урлов на сайте, ф-ция должна выдавать относительные ссылки   
    // Для серверного редиректа обязательно нужен абсолютный путь в урле! Сейчас в двигле в редиректах относительные урлы но это не правильно по стандартам
    $section = ($header || ($cfg['absurls'] && $enableabs)) ? $sys['abs_url'].$section : $section;     
    
    // Тут всё просто, если редирект или хак для rss то тока & а вот если ссылка то &
    $param = ($header || !$enableabs) ? $param : str_replace('&', '&', $param); 

    if (!empty($param)) 
        { $res = $section.".php?".$param.$anchor; } 
    else 
        { $res = $section.".php"; } 
    
    return $res; 
} 

Forever unshaven, red-eyed, detached from reality, with his cockroaches in my head. And let it always will be!

Amro    

Дальше нам будет необходима ф-ция разбирающая параметры в ассоциативный массив, ключ — название параметра, значение массива — содержимое параметра

//Разбивка параметров в массив
function sed_parse_str($str) 
{ 
    $res = array(); 
    foreach (explode('&', $str) as $item) 
    { 
        if (!empty($item)) 
        { 
            list($key, $val) = explode('=', $item); 
            $res[$key] = $val; 
        } 
    } 
    return $res; 
}

Forever unshaven, red-eyed, detached from reality, with his cockroaches in my head. And let it always will be!

Amro    

Неплохо бы пустые параметры нахрен отбрасывать у ссылок

такие ссылки: list.php?c=lib&s=count&w=asc&o=&p= меня просто убиваю!

Так что лучше просто уничтожать пустые параметры и преобразовывать урл в list.php?c=lib&s=count&w=asc

//Собираем строку из параметров
function sed_build_str($params)
{
      $res = array();
      foreach ($params as $key => $val)
      { 
           $res[] = $key."=".$val;
      }
      return implode("&", $res);
}  
//Проверка пустых параметров
function sed_check_params($params) {
   $res = array();
   foreach ($params as $key => $val)
    {
       if (!empty($val)) { $res[$key] = $val; }
    }
   return $res; 
} 

Ну и собственно в sed_url() можно будет так изменить:

function sed_url($section, $param = '', $anchor = '', $header = false, $enableabs = true, $path = '') 
{     
    global $cfg, $sys; 
    
    // Убираем лишний & справа, в основном только для $more в PFS
    $param = preg_replace('/&$/', '', $param); //fix $more in PFS 
    
    // если в ф-цию передаётся массив параметров, оставляем как есть, а если строка то разбираем
    $param = is_array($param) ? $param : sed_parse_str($param);
    
    //Проверяем урл на пустые параметры и собираем строку с параметрами из массива
    $param = sed_build_str(sed_check_params($param));
    
    // Проверям редирект ли это и врублены ли абсолютные урлы или хак для rss при использовании абсолютных урлов ($enableabs = false), там подставляется значение $cfg['mainurl']
    // т.е. для формировании через sed_url() ссылок в rss ленте, даже при использовании абсолютных урлов на сайте, ф-ция должна выдавать относительные ссылки   
    // Для серверного редиректа обязательно нужен абсолютный путь в урле! Сейчас в двигле в редиректах относительные урлы но это не правильно по стандартам
    $section = ($header || ($cfg['absurls'] && $enableabs)) ? $sys['abs_url'].$section : $section;     
    
    // Тут всё просто, если редирект или хак для rss то тока & а вот если ссылка то &
    $param = ($header || !$enableabs) ? $param : str_replace('&', '&', $param); 

    if (!empty($param)) 
        { $res = $section.".php?".$param.$anchor; } 
    else 
        { $res = $section.".php"; } 
    
    return $res; 
} 
?>

Forever unshaven, red-eyed, detached from reality, with his cockroaches in my head. And let it always will be!


This post was edited by Amro (14-09-13 13:58 GMT, 1917 days ago)
Amro    

Это всё мысли в слух так сказать были ))

Теперь разбирёмся с параметром $path

Там ведь нужны не псевдоурлы, значит в него нужно передавать путь до категории

например структура такая:

1. Новости news
1.1.Новости науки newscience
1.1.1 Новости физики newsfiz
И типа новость кака нить с алиасом «newsone» или айди равным 1

В идеале пути должны быть такими:

news/
news/newscience
news/newscience/newsfiz
news/newscience/newsfiz/newsone
или news/newscience/newsfiz/1

 

 

Forever unshaven, red-eyed, detached from reality, with his cockroaches in my head. And let it always will be!

Amro    

Отак, откуда нам брать полный путь например для категории newsfiz

Тут два варианта

  • либо написать ф-цию которая будет каждый раз бадяжить массив $sed_cat
  • либо уже в самом $sed_cat сделать путь!!

Я больше склонен ко второму варианту, это и рациональнее и никак на нагрузке сказываться не будет, так что думаю добивить новый ключ в массив под названием spath

выглядить будет так:

/* ------------------ */

function sed_load_structure()
	{
	global $db_structure, $cfg, $L;

	$res = array();
	$sql = sed_sql_query("SELECT * FROM $db_structure ORDER BY structure_path ASC");

	while ($row = sed_sql_fetchassoc($sql))
		{
		if (!empty($row['structure_icon']))
			{ $row['structure_icon'] = "<img src=\"".$row['structure_icon']."\" alt=\"\" />"; }

		$path2 = mb_strrpos($row['structure_path'], '.');

		$row['structure_tpl'] = (empty($row['structure_tpl'])) ? $row['structure_code'] : $row['structure_tpl'];

		if ($path2>0)
			{
			$path1 = mb_substr($row['structure_path'],0,($path2));
			$spath = $path[$path1]; //new sed175
      $path[$row['structure_path']] = $path[$path1].'.'.$row['structure_code'];
			$tpath[$row['structure_path']] = $tpath[$path1].' '.$cfg['separator'].' '.$row['structure_title'];
			$row['structure_tpl'] = ($row['structure_tpl']=='same_as_parent') ? $parent_tpl : $row['structure_tpl'];
			}
		else
			{
			$path[$row['structure_path']] = $row['structure_code'];
			$tpath[$row['structure_path']] = $row['structure_title'];
      $spath = ""; //new sed175
			}

		$order = explode('.',$row['structure_order']);
		$parent_tpl = $row['structure_tpl'];

		$res[$row['structure_code']] = array (
			'path' => $path[$row['structure_path']],
			'tpath' => $tpath[$row['structure_path']],
      'spath' => $spath, //new sed175
			'rpath' => $row['structure_path'],
			'tpl' => $row['structure_tpl'],
			'title' => $row['structure_title'],
			'desc' => $row['structure_desc'],
			'icon' => $row['structure_icon'],
			'group' => $row['structure_group'],
			'allowcomments' => $row['structure_allowcomments'],
			'allowratings' => $row['structure_allowratings'],
			'order' => $order[0],
			'way' => $order[1]
				);
		}
  
  return($res);
	}

и всё, теперь у нас в $sed_cat есть путь который можно использовать, например для категорий в sed_url так:

  if ($section == "list") {
     $cpath = $sed_cat[$params['c']]['spath'];
     $path = (!empty($cpath)) ? str_replace(".", "/", $cpath).'/' : '';      
  }

Forever unshaven, red-eyed, detached from reality, with his cockroaches in my head. And let it always will be!


This post was edited by Amro (14-09-13 14:54 GMT, 1917 days ago)
Amro    

И вот ещё думка, я не стороннки всякого Г в htaccess по типу

RewriteEngine On 
RewriteBase /  
RewriteRule (datas|images|js|skins|plugins|system)/(.*)$ $1/$2 [L] 
RewriteRule ^admin/([a-z]+)$	 admin.php?m=$1 [NC,NE,QSA,L] 
RewriteRule ^login$ users.php?m=auth [NC,NE,QSA,L] 
RewriteRule ^logout/(.*)$ users.php?m=logout&x=$1 [NC,NE,QSA,L] 
RewriteRule ^users$ users.php [NC,NE,QSA,L] 
RewriteRule ^users/group:([0-9]+)$ users.php?gm=$1 [NC,NE,QSA,L] 
RewriteRule ^users/maingroup:([0-9]+)$ users.php?g=$1 [NC,NE,QSA,L] 
RewriteRule ^users/group:([0-9]+)/sort:([a-z]+)-(asc|desc)$ users.php?gm=$1&s=$2&w=$3 [NC,NE,QSA,L]
RewriteRule ^users/maingroup:([0-9]+)/sort:([a-z]+)-(asc|desc)$ users.php?g=$1&s=$2&w=$3 [NC,NE,QSA,L] 
RewriteRule ^users/group:([0-9]+)/filter:(.*)$ users.php?gm=$1&f=$2 [NC,NE,QSA,L] 
RewriteRule ^users/maingroup:([0-9]+)/filter:(.*)$ users.php?g=$1&f=$2 [NC,NE,QSA,L] 
RewriteRule ^users/group:([0-9]+)/filter:(.*)/sort:([a-z]+)-(asc|desc)$ users.php?gm=$1&f=$2&s=$3&w=$4 [NC,NE,QSA,L] 
RewriteRule ^users/maingroup:([0-9]+)/filter:(.*)/sort:([a-z]+)-(asc|desc)$ users.php?g=$1&f=$2&s=$3&w=$4 [NC,NE,QSA,L] 
RewriteRule ^users/sort:([a-z]+)-(asc|desc)$ users.php?s=$1&w=$2 [NC,NE,QSA,L] 

по моему это чрезмерно сложно

я бы обратный реврайт предложил сделать так:

AddDefaultCharset UTF-8 
Options -Indexes 
RewriteEngine On 
RewriteBase / 
RewriteCond %{REQUEST_FILENAME} !-f 
RewriteCond %{REQUEST_FILENAME} !-d 
RewriteRule ^(.*)$ rewriteurl.php 

И уже самими средствами PHP в rewriteurl разбирать URL и подрубать index.php, forums.php, list.php

Хотя ХЗ можно ли так

Forever unshaven, red-eyed, detached from reality, with his cockroaches in my head. And let it always will be!

Amro    

Пример правил и их поиск

$params = is_array($params) ? $params : sed_parse_str($params);

// Массив аргументов ссылки                  
$args = sed_check_params($params);  // без пустых аргументов                  
                  
$ruler['list'][] = array('part' => 'list', 
                 'params' => sed_parse_str('c=*&s=*&w=*&o=*&p=*'), 
                 'rewrite' => '{c}/?s={s}&w={w}&o={o}&p={p}');
                  
$ruler['list'][] = array('part' => 'list', 
                 'params' => sed_parse_str('c=*&s=*&w=*'), 
                 'rewrite' => '{c}/?s={s}&w={w}');
                 
$ruler['list'][] = array('part' => 'list', 
                 'params' => sed_parse_str('c=*&s=*'), 
                 'rewrite' => '{c}/?s={s}');                   
                 
$ruler['list'][] = array('part' => 'list', 
                 'params' => sed_parse_str('c=*'), 
                 'rewrite' => '{c}');
                 
$rule = array(); 


// Если секция с правилами присутствует
if(!empty($ruler[$section])) 
{ 
    // Извлекаем каждое правило
    foreach($ruler[$section] as $rule) 
    {        
        // По-умолчанию типа правило найдено
        $matched = true; 
        // сравниваем наличие параметров в обоих массивах
        foreach($rule['params'] as $key => $val) 
        {             
            if(empty($args[$key]) 
                || (!array_key_exists($key, $args))  
                || ($val != '*' && $args[$key] != $val))
            { 
                $matched = false; 
                break; 
            } 
        } 
        // Если правило найдено и кол-во параметров в сылке и в правиле одинаковое
        if($matched && (count($args) == count($rule['params']))) 
        { 
            $url = $rule['rewrite']; 
            break; 
        } 
    } 
} 

Forever unshaven, red-eyed, detached from reality, with his cockroaches in my head. And let it always will be!

Amro    

Ну и дальше уже прогоняем правило и делаем замены

// ищем в правиле {параметр замены}
if(preg_match_all('#\{(.+?)\}#', $url, $matches, PREG_SET_ORDER)) 
    { 
        // Ну а тут найденное заменяем из массива $args     
    }

Forever unshaven, red-eyed, detached from reality, with his cockroaches in my head. And let it always will be!

Amro    
//Собираем строку без пустых параметров
function sed_build_str($params)
{
      $res = array();
      foreach ($params as $key => $val)
      { 
           $res[] = $key."=".$val;
      }
      return implode("&", $res);
}  

//Проверка пустых параметров
function sed_check_params($params) {
   $res = array();
   foreach ($params as $key => $val)
    {
       if (!empty($val)) { $res[$key] = $val; }
    }
   return $res; 
} 

/* ------------------ */  // new in 175

function sed_url($section, $params = '', $anchor = '', $header = false, $enableabs = true, $path = '')
	{	
  global $cfg, $sys, $sed_cat;
  
  $params = preg_replace('/&$/', '', $params); //fix $more in PFS 
  
  $params = is_array($params) ? $params : sed_parse_str($params);
  
  if ($section == "list") {
     $cpath = $sed_cat[$params['c']]['spath'];
     $path = (!empty($cpath)) ? str_replace(".", "/", $cpath).'/' : '';      
  }
  
  $args = sed_check_params($params);  // без пустых аргументов
  
  
  $section = ($header || ($cfg['absurls'] && $enableabs)) ? $sys['abs_url'].$section : $section;    
 // $params = ($header || !$enableabs) ? $params : str_replace('&', '&amp;', $params); 
  
//$params = is_array($params) ? $params : sed_parse_str($params);

// Массив аргументов ссылки                  
$args = sed_check_params($params);  // без пустых аргументов                  
                  

// Правила, думаю нужно будет их вынести в отдельный файл, причеём в этом же массиве можно хранить и правила для обратного преобразования

$ruler['list'][] = array('part' => 'list', 
                 'params' => sed_parse_str('c=*&s=*&w=*&o=*&p=*'), 
                 'rewrite' => '{c}/?s={s}&w={w}&o={o}&p={p}');
                  
$ruler['list'][] = array('part' => 'list', 
                 'params' => sed_parse_str('c=*&s=*&w=*'), 
                 'rewrite' => '{c}/?s={s}&w={w}');
                 
$ruler['list'][] = array('part' => 'list', 
                 'params' => sed_parse_str('c=*&s=*'), 
                 'rewrite' => '{c}/?s={s}');                   
                 
$ruler['list'][] = array('part' => 'list', 
                 'params' => sed_parse_str('c=*'), 
                 'rewrite' => '{c}');
                                  
$ruler['page'][] = array('part' => 'page', 
                 'params' => sed_parse_str('id=*'), 
                 'rewrite' => '{id}');                 
                 
$ruler['page'][] = array('part' => 'page', 
                 'params' => sed_parse_str('al=*'), 
                 'rewrite' => '{al}');  
                                  
$ruler['forums'][] = array('part' => 'forums', 
                 'params' => sed_parse_str('m=posts&q=*'), 
                 'rewrite' => '{m}/{q}');
                                  
$ruler['users'][] = array('part' => 'users', 
                 'params' => sed_parse_str('m=details&id=*'), 
                 'rewrite' => 'users/details/{id}');                                  
                                  
$ruler['plug'][] = array('part' => 'plug', 
                 'params' => sed_parse_str('plug.php?e=*'), 
                 'rewrite' => 'plug/{e}');                                    
                                  
$ruler['polls'][] = array('part' => 'polls', 
                 'params' => sed_parse_str('id=*'), 
                 'rewrite' => 'poll/{id}');  
                 
$ruler['*'][] = array('part' => '*', 
                 'params' => sed_parse_str('*'), 
                 'rewrite' => '*');                  
                 
$url = $ruler['*'][0]['rewrite']; // default rule


$rule = array(); 


// Если секция с правилами присутствует
if(!empty($ruler[$section])) 
{ 
    // Извлекаем каждое правило
    foreach($ruler[$section] as $rule) 
    {        
        // По-умолчанию типа правило найдено
        $matched = true; 
        // сравниваем наличие параметров в обоих массивах
        foreach($rule['params'] as $key => $val) 
        {             
            // тут проверку надо делать как-то по другому
            if(empty($args[$key]) 
                || (!array_key_exists($key, $args))  
                || ($val != '*' && $args[$key] != $val))
            { 
                $matched = false; 
                break; 
            } 
        } 
        // ?? Проверять на одинаковое кол-во параметров незнаю, тоже наверное не вариант 
        // Если правило найдено и кол-во параметров в сылке и в правиле одинаковое
        if($matched && (count($args) == count($rule['params']))) 
        { 
            $url = $rule['rewrite']; 
            break; 
        } 
    } 
} 


if(preg_match_all('#\{(.+?)\}#', $url, $matches, PREG_SET_ORDER)) 
{ 
        foreach($matches as $m) 
        { 
        
        $var = $m[1];
        $url = str_replace($m[0], urlencode($args[$var]), $url); 
        unset($args[$var]); 
         
        }
}

if ($url == "*") {

  $params = sed_build_str($args);
  
  if (!empty($params)) 
		{ $res = $section.".php?".$params.$anchor; }
	else
		{ $res = $section.".php"; }
    
    return $res;

}

return($url);

Forever unshaven, red-eyed, detached from reality, with his cockroaches in my head. And let it always will be!

Amro    

Редиректилка вах в конце common.php

if ($cfg['sefurls'])
{
   if ($findphp = mb_strpos($sys['request_uri'], '.php'))
   {
      $params = $_SERVER['QUERY_STRING'];    
      $params_arr = sed_parse_str($params);
      $section = mb_substr($sys['request_uri'], 1, $findphp-1);
      if ($section == 'list') { $sys['catcode'] = $params_arr['c']; }
      if ($section == 'page') {        
        if (!empty($params_arr['al']))
      	 { 
          $pal = $params_arr['al'];
          $sql = sed_sql_query("SELECT page_cat FROM $db_pages WHERE page_alias='$pal' LIMIT 1"); 
          $pag = sed_sql_fetchassoc($sql);
          $sys['catcode'] = $pag['page_cat'];
         }
        elseif (!empty($params_arr['id']))
      	 {  
          $pid = $params_arr['id'];
          $sql = sed_sql_query("SELECT page_cat FROM $db_pages WHERE page_id='$pid'"); 
          $pag = sed_sql_fetchassoc($sql);
          $sys['catcode'] = $pag['page_cat'];
         }
      }      
      $redirect301 = sed_url($section, $params, "", true);   
      header("HTTP/1.1 301 Moved Permanently");
      header("Location: ".$redirect301);
      exit;   
   }
}

Forever unshaven, red-eyed, detached from reality, with his cockroaches in my head. And let it always will be!

Kaan    

Please write in English

$cfg['sefurls'

system/functions.admin.php On or off? 


This post was edited by Kaan (20-10-13 16:03 GMT, 1881 days ago)