Как правильней и лучше сделать ЧПУ?

Я не знаю как правильней сделать ЧПУ, я думал разбивать ссылки в самом коде, а с моделью MVC это сделать вообще становится просто. Но некоторые люди мне говорят, что это не правилльно и делать нужно через htaccess, как по мне это прийдется вручную для каждого адреса прописовать регулярку и это неудобно. В WordPress довольно хорошоо сделан ЧПУ, можно включать и отключать, мне тоже хотелось бы сделать что-то подобное

1 ответов


Под htaccess те самые люди подразумевают применение инструкций mod_rewrite.
Что бы использовать гибко ЧПУ, нужно, что бы существовал некий "контроллер" - обработчик этого ЧПУ. Поэтому при помощи MOD_REWRITE люди обычно перенаправляют все "фиктивные" адреса представленные в виде строки ЧПУ определенному обработчику, в котором разбирается с ним.

.htaccess


<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /
  RewriteRule ^/index\.php$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule . /index.php [L]
</IfModule>

 
URL:

http://mydomain.tld/catalog/items/view/11
 
Может, например, соответствовать следующему:

controller: catalog
scope:      items
operation:  view
id:         11
 

Ну а как этого достичь - примеров море, практически в любом серъезном фреймворке.

Что бы было совсем понятно, прилагаю свой простой, карманный "роутер", который разбирает эту строку на подобные структуры:


// Класс, который помогает использовать URI в качестве оператора контроллера
class router {
        protected $self = array();

  // переменная для хранения синглетона объекта класса
        private static $__instance;

  // путь - URI
  public $_path;

  public $_router;

  public static function getInstance() {
    if (!self::$__instance) {
      self::$__instance = new self();
    }
    return self::$__instance;
  }

  function __construct($config = '') {
    $route = '';
    $this->_router = array('controller', 'action', 'id');
    $this->_path = array();
    $requestURI = explode('/', $_SERVER['REQUEST_URI']);
    $scriptName = explode('/', $_SERVER['SCRIPT_NAME']);

    for($i= 0;$i < sizeof($scriptName);$i++)
          if ($requestURI[$i] == $scriptName[$i]) unset($requestURI[$i]);

    foreach ($requestURI as $value) {
      if (!empty($value)) $route[] = trim($value);
    }

    $this->_path = (!empty($route)) ? array_values($route) : array();
    $this->setRouter($config);
  }

  function setRouter($config = '') {
    $route = '';
    if (!empty($config)) {
      $this->unsetRouter();
      foreach (explode('/', $config) as $value) if (!empty($value)) $route[] = trim($value);
      if (count($route)) {
        $this->_router = $route;
      }
    }

    if (count($this->_router)) {
      foreach ($this->_router as $k => $v) {
        $this->{$v} = (isset($this->_path[$k])) ? $this->_path[$k] : false;
      }
    }
  }

  function unsetRouter() {
    foreach ($this->_router as $var) unset($this->self[$var]);
  }
}
 

Как использовать? в нашем случае , например, инициализация

$router = new router('controller/scope/operation/id');

var_dump($router);
// object:
// controller -> catalog
// scope -> items
// operation -> view
// id -> 11
 

protected $self = array(); // можно объяснить для чего это


private static $__instance; // можно объяснить для чего это



public static function getInstance() {
if (!self::$__instance) {
self::$__instance = new self();
}
return self::$__instance;
} // можно объяснить для чего эта функция

Просто очень интересно) а то копировать без смысла не очень люблю)


спасибо