Router

dakata__92

Super Moderator
Колеги, помогнете ми да уeднаквя добавяните адреси с тези които трябва да търся в този клас. Ще дам и примерите.

PHP:
<?php
namespace user\router;

class Route{
	private $allowedMethods = array("ANY", "GET", "HEAD", "POST", "PUT");
	private $routesTree = array();
	
	public function __construct(){
	
	}
	
	public function addRoute($method,$route,$action){
		$method = strtoupper(trim($method));
		if(in_array($method,$this->allowedMethods)){
			if($method == "ANY"){
				$method = array_diff($this->allowedMethods,array($method));
			}
			$this->routesTree[] = array(
				"method" => $method,
				"route" => strtolower(trim($route)),
				"action" => $action
			); 
		}else{
			throw new \Exception("Method (".$method.") is not allowed!", 500);
		}
	}
	
	public function findRoute($method,$uri){
		$method = strtoupper(trim($method));
		$uri = strtolower(trim($uri));
		foreach($this->routesTree as $route){
			if($route["route"] == $uri){
				switch($method){
					case $route["method"]:
						return $route;
						break;
					case is_array($route["method"]) and in_array($method,$route["method"]):
						return $route;
						break;
					default: throw new \Exception("Method $method on this route $uri is not allowed!", 500);
				}
			}
		}
	}
	
	public function getRoutesTree(){
		return $this->routesTree;
	}
}

Примери:

PHP:
$r = new \user\router\Route();
$r->addRoute('get', '/', new stdClass());
$r->addRoute('get', '/id', 'home-id');
$r->addRoute('get', '/?test=proba', 'home-opt-id');
$r->addRoute('get', '/user', 'user');
$r->addRoute('post', '/user/?id=2', 'user-id');
$r->addRoute('post', '/user/id', 'user-id-post');
$r->addRoute('any', '/user/id/edit', 'user-id-edit');
$r->addRoute('get', '/user/id/name/group/ord', 'user-id-name-group-opt-ord');

print "<br>";
$f = $r->findRoute($_SERVER["REQUEST_METHOD"],$_SERVER["QUERY_STRING"]);
print_r($f);
print_r($r->getRoutesTree());
 
Какво означава "уеднаквя" - да ползваш regex-и ли? Погледна ли някой от рутерите, които дадох в другата ти тема?
 
djman каза:
Какво означава "уеднаквя" - да ползваш regex-и ли? Погледна ли някой от рутерите, които дадох в другата ти тема?
Създадох ето този метод
PHP:
public function sameStructure($route){
		if(mb_substr($route, 0, 1) != '/'){
			$route = '/' . $route;
		}
		if(mb_substr($route, -1, 1) == '/'){
			$route = substr($route, 0, -1);
		}
		return $route;
	}
като го викам и в addRoute и във findRoute. Чудя се само как да преработя $_SERVER["QUERY_STRING"] така че да матчва и $r->addRoute('get', '/user/?id=2', new stdClass()); във метода findRoute. Тоест в момента $_SERVER["QUERY_STRING"] връща user/&id=2 което не е равно на /user/?id=2 създадено във дървовидната структора на пътищата.
 
Така възможно ли е по някакъв начин да добавям само страници като директориии в рутера и вече самите параметри на гет и пост да се подават но да не се налага да описвам всичките позволени параметри на страницата. Примерно:
http://example.com/page/
http://example.com/page/?id=1
http://example.com/page/?id=2&session=true
http://example.com/page/?id=3

тоест искам да опиша само страницата
$r->addRoute('/page/', 'home-id');
без да се налага да описвам параметрите и . Кода ми позволява да използвам всичките методи или само Гет или Пост примерно или Пут там за конзолата. Въпроса ми е как вбихте постъпили. Впрочем веднага се сещам за структората:
http://example.com/page/page2/ която трябва да се опише все едно имаме втора страница а първата е директория вече. Сложно го обяснявам май. :D
Дайте примери и код по това което съм скалъпил и така проблеми и критика по него. :?:
 
Използвай $_SERVER['QUERY_STRING'], за да получиш чист REQUEST_URI - така ще имаш само "папките".
Аз пак ще попитам, ти погледна ли някой от много рутери, които дадох от github? :D Има от съвсем прости до по-сложни, примери много...
 
dakata__92 каза:
Дайте примери и код по това което съм скалъпил и така проблеми и критика по него. :?:
Като за начало всичко това:

Код:
if(mb_substr($route, 0, 1) != '/'){
                        $route = '/' . $route;
                }
                if(mb_substr($route, -1, 1) == '/'){
                        $route = substr($route, 0, -1);
                }
                return $route;

може да стане така:

PHP:
return '/'.trim($route, '/');

:D:D:D
 
anonimen каза:
dakata__92 каза:
Дайте примери и код по това което съм скалъпил и така проблеми и критика по него. :?:
Като за начало всичко това:

Код:
if(mb_substr($route, 0, 1) != '/'){
                        $route = '/' . $route;
                }
                if(mb_substr($route, -1, 1) == '/'){
                        $route = substr($route, 0, -1);
                }
                return $route;

може да стане така:

PHP:
return '/'.trim($route, '/');

:D:D:D
Забравил съм да постна по-новата версия на коoа в метода:
$route = strtolower(trim(trim($route),"/"))."/"; И аз се сетих, че онова е излишно писане и върши същото, че даже и по-малко. Реално trim премахва множеството ////t//// от двете страни. :)
djman каза:
Използвай $_SERVER['QUERY_STRING'], за да получиш чист REQUEST_URI - така ще имаш само "папките".
Аз пак ще попитам, ти погледна ли някой от много рутери, които дадох от github? :D Има от съвсем прости до по-сложни, примери много...
Да погледнах ги. Този даже е от един подобен рутер там. Преразгледах много от тях и ти благодаря за линка но все пак те са различни, а аз пиша нещо по средата. :D :D :D Ползвам .htaccess и за двете сървърни стойности се получава примерно:
PHP:
print $_SERVER['REQUEST_URI']; //1
print "<br>";
print $_SERVER["QUERY_STRING"]; //2
1 - /framework/user/test/tree/?id=1
2 - user/test/tree/&id=1
 
Отново ще досаждам със съкращаване на код, простете ми :D

PHP:
$route = strtolower(trim(trim($route),"/"))."/";
// ===
$route = strtolower(trim($route, "\s/"))."/";
 
anonimen каза:
Отново ще досаждам със съкращаване на код, простете ми :D

PHP:
$route = strtolower(trim(trim($route),"/"))."/";
// ===
$route = strtolower(trim($route, "\s/"))."/";
Какво значи "\s/"? \s
 
dakata__92 каза:
anonimen каза:
Отново ще досаждам със съкращаване на код, простете ми :D

PHP:
$route = strtolower(trim(trim($route),"/"))."/";
// ===
$route = strtolower(trim($route, "\s/"))."/";
Какво значи "\s/"? \s
http://php.net/manual/en/function.trim.php
PHP:
string trim ( string $str [, string $character_mask = " \t\n\r\0\x0B" ] )
По навик пиша \s за всичките whitespace-ове, но в случая точно това няма да сработи май. Но така ще стане:

PHP:
trim($route, "/ \t\n\r\0\x0B");
 
anonimen каза:
dakata__92 каза:
anonimen каза:
Отново ще досаждам със съкращаване на код, простете ми :D

PHP:
$route = strtolower(trim(trim($route),"/"))."/";
// ===
$route = strtolower(trim($route, "\s/"))."/";
Какво значи "\s/"? \s
http://php.net/manual/en/function.trim.php
PHP:
string trim ( string $str [, string $character_mask = " \t\n\r\0\x0B" ] )
По навик пиша \s за всичките whitespace-ове, но в случая точно това няма да сработи май. Но така ще стане:

PHP:
trim($route, "/ \t\n\r\0\x0B");
след малък тест да не сработва:
PHP:
$route = "///id/// ";
$route = strtolower(trim($route, "\s/"))."/";
print $route;

по старият начин да:
PHP:
$route = "///id/// ";
$route = strtolower(trim(trim($route),"/"))."/";
print $route;

С последният код стана! :)
 
Айде кажи кое не работи :D
http://ideone.com/KkV524
Не видя ли последния пост? :wink:

А, едитнал си се докато съм писал ...
 
anonimen каза:
Айде кажи кое не работи :D
http://ideone.com/KkV524
Не видя ли последния пост? :wink:
Поправих си поста преди да добавиш този. През това време го и тествах и да работи си нормално. Прочетох и ръководството веднага защото си спомням, че нямаше \s което е за regex. Мързелската го правех с два трима аз за да не пиша стринга но да така е по-правилно и опростено. :)
 
dakata__92 каза:
PHP:
print $_SERVER['REQUEST_URI']; //1
print "<br>";
print $_SERVER["QUERY_STRING"]; //2
1 - /framework/user/test/tree/?id=1
2 - user/test/tree/&id=1

Какво ти е съдържанието на .htaccess?
При мен е такъв резултата:

Код:
[REQUEST_URI] => /htaccesstest/page/two?id=1&var=b
[QUERY_STRING] => id=1&var=b

следния .htaccess:

Код:
Options +FollowSymLinks
Options -MultiViews

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
 
Код:
RewriteEngine On
RewriteBase /framework/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

RewriteRule ^(.+)$ ?$1 [QSA,L]

Като RewriteBase /framework/ се ползва само защото съм на локалният хост иначе би било единствено RewriteBase / . :)
 
Много ти е странен rewrite rule. Пробвай с моя. :roll: Пък и вземи ползвай VirtualHosts (@eLite написа в друга твоя тема как), не се занимавай с rewritebase, освен ако не е наложително...
 
djman каза:
Много ти е странен rewrite rule. Пробвай с моя. :roll: Пък и вземи ползвай VirtualHosts (@eLite написа в друга твоя тема как), не се занимавай с rewritebase, освен ако не е наложително...
print $t = str_replace("?".$_SERVER["QUERY_STRING"],"",$_SERVER['REQUEST_URI']);
и това работи.
Да с твоя стана сега проблема е направо страшен. Понеже е писан на база старият htaccess рутера в момента прави проблем при намирането.
PHP:
public function findRoute($method,$uri){
		if(!$method){
			throw new \Exception("No method!",500);
		}
		$method = strtoupper(trim($method));
		$uri = $this->sameStructure($uri);
		foreach($this->routesTree as $route){
			if($route["route"] == $uri){
				switch($method){
					case $route["method"]:
						return $route;
						break;
					case is_array($route["method"]) and in_array($method,$route["method"]):
						return $route;
						break;
					default: throw new \Exception("Method $method on this route $uri is not allowed!", 500);
				}
				break;
			}
		}
	}
	
	public function sameStructure($route){
		$route = strtolower(trim($route,"/ \t\n\r\0\x0B"))."/";
		return $route;
	}

В момента какъв стринг трябва да подавам за да пасне на стринга от addRoute във FindRoute. if($route["route"] == $uri){ вече не са равни и незнам как да го направя да са равни и какъв стринг да подавам на метода и от къде да го взимам тоест от QUERY_STRING или от REQUEST_URI и така нататък за да го направя да пасне с този подаден във дървото на страниците.
 

Back
Горе