Автор | Сообщение |
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! отредактировал(а) Amro: 14-09-13 13:58 GMT |
Amro | |
![]() |
Это всё мысли в слух так сказать были )) Теперь разбирёмся с параметром $path Там ведь нужны не псевдоурлы, значит в него нужно передавать путь до категории например структура такая:
В идеале пути должны быть такими:
Forever unshaven, red-eyed, detached from reality, with his cockroaches in my head. And let it always will be! |
Amro | |
![]() |
Отак, откуда нам брать полный путь например для категории newsfiz Тут два варианта
Я больше склонен ко второму варианту, это и рациональнее и никак на нагрузке сказываться не будет, так что думаю добивить новый ключ в массив под названием 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! отредактировал(а) Amro: 14-09-13 14:54 GMT |
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('&', '&', $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
отредактировал(а) Kaan: 20-10-13 16:03 GMT |