Форум → Сообщество → Профессиональная деятельность → Взаимопомощь → Нужен разбор URL как в WP
Нужен разбор URL как в WP
-
29 апреля 2009 г. 13:26, спустя 4 минуты 16 секунд
ну вобщем зачет. свой вариант я выложу позже. он пока только вызревает в головеιιlllιlllι унц-унц -
29 апреля 2009 г. 14:11, спустя 45 минут 19 секунд
phpdude, я уже привел свои доводы, что в полные условия для универсального модуля вписаться невозможно, если не менять моск на два полужопия (в смысле, если писать так, чтоб оно работало и быстро и корректно и чтоб потом можно было поправить что-то). А твой пример вполне понятен. Хотя я сам делал все по-другому (у меня была четкая привязка к структуре движка, и ниипет). -
29 апреля 2009 г. 14:36, спустя 24 минуты 57 секунд
Givi, ну обрисуй как у тебя работает, хотя тема про настраиваемые правила, можно сравнить для полноты картины с жесткими.ιιlllιlllι унц-унц -
29 апреля 2009 г. 14:39, спустя 2 минуты 25 секунд
<?
$url = "/archive/2009/27/08/256/buy viagra.html";
$pattern = "/archive/%date%/%id%/%title%";
class WPUrls
{
private $_groups;
private $_params;
public function parse($url,$pattern)
{
if(!preg_match("#^".$this->compileRegexp($pattern)."#ism",$url,$m))
{
return false;
}
$return = array();
foreach($this->_groups as $group=>$null)
{
$return[$group] = $m[++$i];
}
return $return;
}
public function addParam($name,$regexp)
{
$this->_params[$name] = $regexp;
}
private function compileRegexp($pattern)
{
$this->_groups = array();
if(!$this->_params)
{
return $pattern;
}
foreach($this->_params as $i=>$reg)
{
if(($pos = stripos($pattern,"%$i")) !== false)
{
$this->_groups[$i] = $pos;
$pattern = str_ireplace("%$i%",$reg,$pattern,$replaced);
}
}
asort($this->_groups);
return $pattern;
}
}
$wpurls = new WPUrls();
$wpurls->addParam('date','(\d{4}/\d{2}/\d{2})');
$wpurls->addParam('title','(.*?)(?:\.html)?$');
$wpurls->addParam('id','(\d+)');
$params = $wpurls->parse($url,$pattern);
print_r($params);
как вам такой классец? ;)
имхо ахуеннее в разы :)Сапожник без сапог -
-
29 апреля 2009 г. 14:47, спустя 1 минуту 19 секунд
+ реализация значительно пооптимизированнее ))) ибо выкинул лишние регулярки.
рано плюсанул чтоли? :)Сапожник без сапог -
29 апреля 2009 г. 14:58, спустя 11 минут 38 секунд
я бы чуть подправил:
$wpurls = new WPUrls($url);
…
foreach($patterns as $p)
if ($result = $wpurls->parse($p))
break;ιιlllιlllι унц-унц -
19 мая 2009 г. 9:02, спустя 19 дней 18 часов 3 минуты
helldude, я тебя боюсь :) еще раз спасибо за код. я на его основе сделал себе такой класс:
<?php
class QB_Url
{
public static
$controller = NULL,
$params = NULL;
public static function lookupRoute($uri = NULL)
{
if (is_null($uri))
{
/*
// IIS is troublemaker
if (!isset($_SERVER['REQUEST_URI']))
{
// for IIS7
if (isset($_SERVER['HTTP_X_ORIGINAL_URL']))
{
$_SERVER['REQUEST_URI'] = $_SERVER['HTTP_X_ORIGINAL_URL'];
}
// for IIS6 /
else
{
$_SERVER['REQUEST_URI'] = $_SERVER['PHP_SELF'];
if (isset($_SERVER['QUERY_STRING']) && !empty($_SERVER['QUERY_STRING']))
$_SERVER['REQUEST_URI'] .= '?'.$_SERVER['QUERY_STRING'];
}
}
*/
$uri = $_SERVER['REQUEST_URI'];
}
if (!isset(QB::$config['routes']) || !isset(QB::$config['route_tokens']))
trigger_error('Routes are not set', E_USER_ERROR);
$basePath = QB::$config['path'];
if (($len = strlen($basePath)) > 0 && strpos($uri, $basePath) === 0)
$uri = substr($uri, $len);
$routes = QB::$config['routes'];
self::$_tokens = QB::$config['route_tokens'];
/*
echo 'uri="'.$uri.'"<br /><br />'."\n";
*/
foreach ($routes as $routeId => $pattern)
{
$compiled = self::compileRoute($pattern);
/*
echo '<i>'.$routeId.'</i>: "'.$pattern.' => "'.$compiled.'", ';
print_r(self::$_vars);
echo "<br />\n";
*/
if(preg_match('#^'.$compiled.'#ism', $uri, $matches))
{
self::$params = array();
$i = 0;
foreach(array_keys(self::$_vars) as $id)
self::$params[$id] = $matches[++$i];
return self::$controller = $routeId;
}
}
return self::$controller = FALSE;
}
/* — private section – */
private static
$_vars,
$_tokens;
private static function compileRoute($pattern)
{
self::$_vars = array();
if(empty(self::$_tokens))
return $pattern;
foreach(self::$_tokens as $id => $reg)
{
if(($pos = stripos($pattern, '%'.$id)) !== FALSE)
{
self::$_vars[$id] = $pos;
$pattern = str_ireplace('%'.$id.'%', $reg, $pattern);
}
}
asort(self::$_vars);
return $pattern;
}
}
как видно из текста, класс "статический".
вызываю вот так:
$ctrl = QB_Url::lookupRoute();
if ($ctrl)
{
if (file_exists(QB::$appDir.'ctrl/'.$ctrl.'.php'))
include QB::$appDir.'ctrl/'.$ctrl.'.php';
else
include QB::$appDir.'ctrl/default.php';
}
else
trigger_error('No route for this URL', E_USER_ERROR);
здесь неявно присутствует еще один "статический" класс QB. я использую его в качестве namespace для базовых параметров системы, в т.ч. таблицы маршрутов.
пример маршрутов и токенов для подстановки в них:
array(
'base_url' => 'http://test1.ru/minimal',
'path' => '/minimal',
'profiler' => 1,
'route_tokens' => array(
'date' => '(\d{4}/\d{2}/\d{2})',
'title' => '(.*?)(?:\.html)?$',
'id' => '(\d+)',
'kind' => '(forum|gallery|blog)'
),
'routes' => array(
'post_new' => '/topic/%id%/new_post.html',
'post_edit' => '/post/%id%/edit.html',
'topic' => '/topic/%id%.html',
'new_topic' => '/%kind%/%id%/new_topic.html',
'board' => '/%kind%/%id%.html',
'board_list' => '/%kind%/',
'index' => '/$',
)
);
работает всё в-целом так:
если найден подходяший маршрут из таблицы маршрутов, то либо подключаем соответствующий модуль, либо модуль по-умолчанию. если соответствие URL и маршрута не найдено, генерируем ошибку.ιιlllιlllι унц-унц -
19 мая 2009 г. 9:08, спустя 6 минут 23 секунды
а вот как выглядит "контроллер по умолчанию" /ctrl/default.php:
<?php
function dump()
{
ob_start();
$num = func_num_args();
for ($i = 0; $i < $num; ++$i)
{
print_r(func_get_arg($i));
echo "\n\n";
}
$ret = trim(ob_get_contents());
ob_end_clean();
return $ret;
}
$view = QB::$appDir.'view/'.QB_Url::$controller.'.tpl';
if (file_exists($view))
{
$data = array(
'base_url' => QB::$config['base_url'],
);
QB_Template::out($view, $data);
}
else
{
$vars = dump(QB_Url::$controller, QB_Url::$params);
echo <<<EOT
<pre>
Default controller
no assotiated view
==================
{$vars}
</pre>
EOT;
}
чисто отладочный вариант. если для вычисленного маршрута есть соответствующий шаблон, то выводим его. если нет — выводим дамп результатов рабора URL.
перекликается с темой "сначала пишем вью, потом модель"ιιlllιlllι унц-унц -
-
19 мая 2009 г. 9:19, спустя 1 минуту 32 секунды
function dump()
{
ob_start();
$num = func_num_args();
for ($i = 0; $i < $num; ++$i)
{
print_r(func_get_arg($i));
echo "\n\n";
}
$ret = trim(ob_get_contents());
ob_end_clean();
return $ret;
}
и вот более разумный вариант. ошибка не в <pre> или тп, а в том, что ob_start(); = print_r($var,true);function debug()
{
$params = func_get_args();
echo "<pre>";
foreach($params as $param)
{
print_r($param);
echo "<hr/>";
}
global $start;
echo "generation time: ".(microtime(1)-$start);
die();
}
УХАХАХАХА!!! БОЙСЯ МЕНЯ!!!!Сапожник без сапог -
19 мая 2009 г. 9:21, спустя 1 минуту 47 секунд
да, чтото подобное я хотел организовать в бесплатном SMCMS Portal.Сапожник без сапог -
19 мая 2009 г. 9:30, спустя 9 минут 16 секунд
а, про print_r(…, true) я как-то не знал :) пару строк можно сэкономить
ошибка - громко сказано, неоптимально, согласен.
исправил на
function dump()
{
for ($ret = '', $num = func_num_args(), $i = 0; $i < $num; ++$i)
$ret .= print_r(func_get_arg($i), true) . "\n\n";
return $ret;
}ιιlllιlllι унц-унц -
19 мая 2009 г. 9:35, спустя 5 минут
уху :)
а, про print_r(…, true) я как-то не знал :) пару строк можно сэкономить
ошибка - громко сказано, неоптимально, согласен.
исправил на
function dump()
{
for ($ret = '', $num = func_num_args(), $i = 0; $i < $num; ++$i)
$ret .= print_r(func_get_arg($i), true) . "\n\n";
return $ret;
}Сапожник без сапог -
19 мая 2009 г. 9:36, спустя 32 секунды
QB - что за сокращение, не подскажешь? должно же это чтото значить? ;)Сапожник без сапог
Пожалуйста, авторизуйтесь, чтобы написать комментарий!