Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Domyślne wartości w Routingu PHP
Forum PHP.pl > Forum > PHP
lukasz91
Witam,
piszę klasę do routingu PHP, czyli skrypt ma wybrać odpowiedni kontroler i metodę na podstawie przetwarzania adresu URL. Za bardzo nie wiem jak rozwiązać jeden problem.

Mam taki wzorzec, z którym porównuję aktualnie przetwarzany link:
Kod
http://domena.pl/demo/<id>

Przy wpisaniu:
Kod
http://domena.pl/demo/5

Wszystko jest ok. Natomiast nie wiem jak uzupełnić URL domyślnymi wartościami, czyli mając:
Kod
http://domena.pl/demo/

skrypt powinien stworzyć url np. tak:
Kod
http://domena.pl/demo/1
Turson
przypisz w routingu domyślne <id> =>1
lukasz91
Cytat(Turson @ 17.04.2014, 14:29:15 ) *
przypisz w routingu domyślne <id> =>1

Możesz rozwinąć myśl na przykładzie kodu? Chyba nie do końca rozumiem.
Turson
Zależy jak masz napisany ten routing.

Tak jak w zendzie robiąc routing linku "demo/:id", określasz w tablicy moduł, kontroler, akcje itd, tak możesz również id
lukasz91
Cytat(Turson @ 17.04.2014, 14:33:32 ) *
Zależy jak masz napisany ten routing.

Tak jak w zendzie robiąc routing linku "demo/:id", określasz w tablicy moduł, kontroler, akcje itd, tak możesz również id


Tak chcę również zrobić u siebie, tylko nie mam pojęcia jak "dokleić" domyślne wartości do przetwarzanego adresu. Jako dane mam: wzorzec, przetwarzany link oraz tablicę z domyślnymi wartościami 'klucz' => 'wartość'.
Turson
Pokaż ten kod bo nie zgadniemy nigdy
lukasz91
Route
  1. <?php
  2.  
  3. namespace Avello\System\Engine\Router;
  4.  
  5. /**
  6.  * Klasa zawiera pojedyńczy element do routingu.
  7.  * @package Avello\System\Engine\Router
  8.  * @author Łukasz Socha <kontakt@lukasz-socha.pl>
  9.  * @version 1.0
  10.  */
  11. class Route
  12. {
  13. /**
  14.   * @var string Ścieżka URL
  15.   */
  16. protected $path;
  17. /**
  18.   * @var string Ścieżka do kontrolera
  19.   */
  20. protected $controller;
  21. /**
  22.   * @var string Nazwa klasy
  23.   */
  24. protected $class;
  25. /**
  26.   * @var string Nazwa metody
  27.   */
  28. protected $method;
  29. /**
  30.   * @var array Zawiera wartości domyślne dla parametrów
  31.   */
  32. protected $defaults;
  33. /**
  34.   * @var array Zawiera reguły przetważania dla parametrów
  35.   */
  36. protected $params;
  37.  
  38. /**
  39.   * @param string $path Ścieżka URL
  40.   * @param array $config Tablica ze ścieżką do kontrolera oraz nazwą metody
  41.   * @param array $params Tablica reguł przetważania dla parametrów
  42.   * @param array $defaults Tablica wartości domyślne parametrów
  43.   */
  44. public function __construct($path, $config, $params=array(), $defaults=array()) {
  45. $this->path=HTTP_SERVER.$path;
  46. $this->controller=$config['controller'];
  47. $this->method=$config['method'];
  48. $this->class=$config['class'];
  49. $this->setParams($params);
  50. $this->setDefaults($defaults);
  51. }
  52.  
  53. /**
  54.   * @param string $controller
  55.   */
  56. public function setController($controller)
  57. {
  58. $this->controller = $controller;
  59. }
  60.  
  61. /**
  62.   * @return string
  63.   */
  64. public function getController() {
  65. return $this->controller;
  66. }
  67.  
  68. /**
  69.   * @param string $class
  70.   */
  71. public function setClass($class) {
  72. $this->class = $class;
  73. }
  74.  
  75. /**
  76.   * @return string
  77.   */
  78. public function getClass() {
  79. return $this->class;
  80. }
  81.  
  82. /**
  83.   * @param array $defaults
  84.   */
  85. public function setDefaults($defaults) {
  86. $this->defaults=$defaults;
  87. }
  88.  
  89. /**
  90.   * @return array
  91.   */
  92. public function getDefaults() {
  93. return $this->defaults;
  94. }
  95.  
  96. /**
  97.   * @param string $method
  98.   */
  99. public function setMethod($method) {
  100. $this->method = $method;
  101. }
  102.  
  103. /**
  104.   * @return string
  105.   */
  106. public function getMethod() {
  107. return $this->method;
  108. }
  109.  
  110. /**
  111.   * @param array $params
  112.   */
  113. public function setParams($params) {
  114. $this->params=$params;
  115. }
  116.  
  117. /**
  118.   * @return array
  119.   */
  120. public function getParams() {
  121. return $this->params;
  122. }
  123.  
  124. /**
  125.   * @param string $path
  126.   */
  127. public function setPath($path) {
  128. $this->path = HTTP_SERVER.$path;
  129. }
  130.  
  131. /**
  132.   * @return string
  133.   */
  134. public function getPath() {
  135. return $this->path;
  136. }
  137.  
  138. /**
  139.   * Generuje przyjazny link.
  140.   * @param array $data
  141.   * @return string
  142.   */
  143. public function generateUrl($data) {
  144. $key_data = array_keys($data);
  145. foreach($key_data as $key) {
  146. $data2['<'.$key.'>']=$data[$key];
  147. }
  148. var_dump($data);
  149. var_dump($data2);
  150. $url=str_replace(array('?'), array(''), $this->path);
  151. return str_replace(array_keys($data2), $data2, $url);
  152. }
  153. }


RouteCollection
  1. <?php
  2.  
  3. namespace Avello\System\Engine\Router;
  4.  
  5. /**
  6.  * Klasa zawiera kolekcję elementów klasy Route.
  7.  * @package Avello\System\Engine\Router
  8.  * @author Łukasz Socha <kontakt@lukasz-socha.pl>
  9.  * @version 1.0
  10.  */
  11. class RouteColletion {
  12. /**
  13.   * @var array Tablica obiektów klasy Route
  14.   */
  15. protected $items;
  16.  
  17. /**
  18.   * Dodaje obgiekt Route do kolekcji
  19.   * @param string $name Nazwa elementu
  20.   * @param Route $item Obiekt Route
  21.   */
  22. public function add($name, $item) {
  23. $this->items[$name]=$item;
  24. }
  25. public function get($name) {
  26. if(array_key_exists($name, $this->items)) {
  27. return $this->items[$name];
  28. } else {
  29. return null;
  30. }
  31. }
  32.  
  33. /**
  34.   * Zwraca wszystkie obiekty kolekcji
  35.   * @return array array
  36.   */
  37. public function getAll() {
  38. return $this->items;
  39. }
  40. }


Router:
  1. <?php
  2.  
  3. namespace Avello\System\Engine\Router;
  4.  
  5. /**
  6.  * Klasa Routera.
  7.  * @package Avello\System\Engine\Router
  8.  * @author Łukasz Socha <kontakt@lukasz-socha.pl>
  9.  * @version 1.0
  10.  */
  11. class Router {
  12. /**
  13.   * @var String URL do przetworzenia
  14.   */
  15. protected $url;
  16. /**
  17.   * @var array Zawiera objekt RouteCollecion.
  18.   */
  19. protected static $collection;
  20. protected $controller;
  21. protected $class;
  22. protected $method;
  23.  
  24. public function __construct($url, $collection=null) {
  25. if($collection!=null) {
  26. Router::$collection = $collection;
  27. }
  28. $this->url = $url;
  29. }
  30.  
  31.  
  32. /**
  33.   * @param array $collection
  34.   */
  35. public function setCollection($collection) {
  36. Router::$collection = $collection;
  37. }
  38.  
  39. /**
  40.   * @return array
  41.   */
  42. public function getCollection() {
  43. return Router::$collection;
  44. }
  45.  
  46. /**
  47.   * @param mixed $class
  48.   */
  49. public function setClass($class)
  50. {
  51. $this->class = $class;
  52. }
  53.  
  54. /**
  55.   * @return mixed
  56.   */
  57. public function getClass()
  58. {
  59. return $this->class;
  60. }
  61.  
  62. /**
  63.   * @param mixed $controller
  64.   */
  65. public function setController($controller)
  66. {
  67. $this->controller = $controller;
  68. }
  69.  
  70. /**
  71.   * @return mixed
  72.   */
  73. public function getController()
  74. {
  75. return $this->controller;
  76. }
  77.  
  78. /**
  79.   * @param mixed $method
  80.   */
  81. public function setMethod($method)
  82. {
  83. $this->method = $method;
  84. }
  85.  
  86. /**
  87.   * @return mixed
  88.   */
  89. public function getMethod()
  90. {
  91. return $this->method;
  92. }
  93.  
  94.  
  95.  
  96. /**
  97.   * @param String $url
  98.   */
  99. public function setUrl($url) {
  100. $this->url = $url;
  101. }
  102.  
  103. /**
  104.   * @return String
  105.   */
  106. public function getUrl() {
  107. return $this->url;
  108. }
  109.  
  110. protected function matchRoute($route) {
  111. $url= $route->getPath();
  112. $url=str_replace(array_keys($route->getParams()), $route->getParams(), $url);
  113. $url=preg_replace('/<\w+>/', '.*', $url);
  114. var_dump($url);
  115. //var_dump($this->url);
  116. preg_match("#^$url$#", $this->url, $results);
  117. //var_dump($results);
  118. if($results) {
  119. $this->controller=$route->getController();
  120. $this->class=$route->getClass();
  121. $this->method=$route->getMethod();
  122. return true;
  123. }
  124. return false;
  125. }
  126.  
  127. public function run() {
  128. foreach(Router::$collection->getAll() as $route) {
  129. if($this->matchRoute($route)) {
  130. return true;
  131. }
  132. }
  133. return false;
  134. }
  135.  
  136.  
  137. }


Przykład
  1. $collection = new \Avello\System\Engine\Router\RouteColletion();
  2.  
  3. $collection->add('demo', new \Avello\System\Engine\Router\Route(
  4. 'demo(/<id>)?',
  5. 'controller' => 'kontroler',
  6. 'method' => 'metoda'
  7. ),
  8. 'id' => '\d+'
  9. ),
  10. 'id' => 0
  11. )
  12. ));
  13. $collection->add('product_one', new \Avello\System\Engine\Router\Route(
  14. '<slug>?-p-<id>?',
  15. 'controller' => DIR_CATALOG.'controller/catalog/product.php',
  16. 'method' => 'index',
  17. 'class' => 'ControllerProductProduct'
  18. ),
  19. 'slug' => '\w+',
  20. 'id' => '\d+'
  21. ),
  22. 'slug' => '',
  23. 'id' => 0
  24. )
  25. ));
  26. $collection->add('cart', new \Avello\System\Engine\Router\Route(
  27. 'koszyk',
  28. 'controller' => DIR_CATALOG.'controller/checkout/cart.php',
  29. 'method' => 'index',
  30. 'class' => 'ControllerCheckoutCart'
  31. )
  32. ));
  33. $collection->add('login', new \Avello\System\Engine\Router\Route(
  34. 'logowanie',
  35. 'controller' => DIR_CATALOG.'controller/account/login.php',
  36. 'method' => 'index',
  37. 'class' => 'ControllerAccountLogin'
  38. )
  39. ));
  40.  
  41. $router = new \Avello\System\Engine\Router\Router($_SERVER['REQUEST_URI'], $collection);
jackraymund
Niezbyt się zagłębiałem w ten skrypt.
Lecz mógłbyś samemu sobie zrobić router i wszystko po kolei zrobić.
  1. <?php
  2. class SmartUrl {
  3. public $args = array();
  4.  
  5. public function __construct($FILE) {
  6. $url_all = trim($_SERVER['REQUEST_URI'],'/');
  7. $file_name = str_replace(__DIR__ . DIRECTORY_SEPARATOR,null,$FILE);
  8. $dir = str_replace($file_name,null,$_SERVER['SCRIPT_NAME']);
  9. $dir = substr($dir,1);
  10. $url_all = str_replace($dir,null,$url_all);
  11. $this->args = explode('/',$url_all);
  12. }
  13. }
  14. ?>
  15. $SmartUrl = new SmartUrl(__FILE__);
  16. $SU = $SmartUrl->args;
  17. ?>

Prosta klasa, zmienna $SU dla linku domena/demo/1
Powinna mieć $SU[0] = demo, $SU[1] = 1
Dla domena/demo/
$SU[0] = demo, $SU[1] nie ustawi tej wartości

Wtedy tylko zrobić if'y.
np.
  1. if($SU[0] == 'demo'){
  2. //wykonajmy teraz warunek co zrobić gdy niema następnej wartości
  3. if(!isset($SU[1]){
  4. $strona = 1;
  5. }else{
  6. $strona = $SU[1];
  7. }
  8. (wczytujemy strone)
  9.  
  10. }

Jak potrzebujesz validacji, to nie problem ją napisać, poduczysz się może czegoś nowego.
Tutaj masz świetny tutorial wyrażeń regularnych http://www.gajdaw.pl/php/wyrazenia-regular.../print.html#R23
A jak nie to zostają ci funkcje str albo is_ (np. is_numeric is_float itd.)
lukasz91
Cytat(jackraymund @ 17.04.2014, 15:38:06 ) *
Niezbyt się zagłębiałem w ten skrypt.
Lecz mógłbyś samemu sobie zrobić router i wszystko po kolei zrobić.


To jest właśnie mój Router tongue.gif Twój skrypt niestety nie rozwiązuje problemu. Zakładasz, że po każdym '/' jest nowy argument, a tak wcale nie musi być.
by_ikar
Nie widzę sensu w próbie napisania routera z symfony od nowa, bo tamten już jest wystarczająco dobry.
Prezi2907
Cytat(by_ikar @ 17.04.2014, 18:43:29 ) *
Nie widzę sensu w próbie napisania routera z symfony od nowa, bo tamten już jest wystarczająco dobry.


Bez urazy ale offtopic. Używanie FrameWorków do PHP to jak robienie sobie sepuku smile.gif 2 razy więcej kodu, 2 razy więcej do ładowania, 2 razy większy bałagan a to z czym się męczysz to 5 minut pracy z .httaccess i 2 plikami php. Plik ruting.php oraz Plik main.php smile.gif

Na uczelni 3 razy potwierdziłem tezę że każdy FrameWork PHP nie zwiększa wydajności a pokazuje lenistwo piszącego portal i brak jego własnych bibliotek do budowania danej struktury smile.gif

Samo to stosowanie Templatów itd można osiągnąć w dużo wygodniejsze sposoby smile.gif Ale to moje indywidualne zdanie i chciałem się z Panami podzielić uwagami smile.gif
by_ikar
Nikt ci nie każe używać całego frameworka, zbór bibliotek to też swego rodzaju framework.. Napisałem ci że nie ma sensu przepisywać, bo sam kiedyś przepisałem, czegoś się tam nauczyłem ale z czasem stwierdziłem że to jest bezsensu..

"kompiler" regułek routingu w symfony podczas budowania regexa rozdziela "zmienne/parametry" domyślnie względem pierwszego separatora i powstaje regexp w którym jakieś parametry mogą być domyślne, co sam regexp to umożliwia. Dla twojego przykładu regexp mógłby wyglądać tak:

Kod
#/demo(?:/(?=P<id>[\d]+))#s


powyższy regex złapie adres /demo jak i /demo/1. Wartości domyślne, które podajesz w regułce routingu są łączone z tablicą wartości dopiero po dopasowaniu odpowiedniej regułki.

Sam korzystam z klas routingu symfony, lecz router napisałem inny, aby pisanie regułek było nieco czytelniejsze i mnie to wygląda tak dla twojego przykładu:

  1. <?php
  2.  
  3. return array(
  4. 'news' => array(
  5. 'path' => '/news/{page}',
  6. 'defaults' => array('_controller' => '\SomeApp\Controller\NewsController::show', 'page' => 1),
  7. 'requirements' => array('page' => '[\d]+'),
  8. ),
  9. );
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.