Hello. Part of the URL is duplicated when clicking on links other than the root. My site is not located in the root directory, but in a separate folder.

Here is the address of the main page:

http: // localhost / testTaskForCodeIt /

Here I go to the registration page for the first time:

http: // localhost / testTaskForCodeIt / user / register (so far, so good)

Here I press the registration button again:

http: // localhost / testTaskForCodeIt / user / user / register

And here the user part begins to be duplicated.

.htacces

AddDefaultCharset utf-8 RewriteEngine on RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ index.php [L,QSA] 

file with routes:

 return array( 'user/register' => 'user/register', 'user/login' => 'user/login', 'user/logout' => 'user/logout', '' => 'application/index', ); 

Here is the router itself:

 <?php class Router { private $routes; public function __construct() { $routesPath = ROOT . '/config/routes.php'; $this->routes = include($routesPath); } /** * Returns request string */ private function getURI() { if (!empty($_SERVER['REQUEST_URI'])) { return trim($_SERVER['REQUEST_URI'], '/'); } } public function run() { // Получить строку запроса $uri = $this->getURI(); // Проверить наличие такого запроса в routes.php foreach ($this->routes as $uriPattern => $path) { // Сравниваем $uriPattern и $uri if (preg_match("~$uriPattern~", $uri)) { //var_dump(strpos($uri, $uriPattern)); // Получаем внутренний путь из внешнего согласно правилу. $internalRoute = preg_replace("~^$uriPattern~", $path, $uri); // Определить контроллер, action, параметры $segments = explode('/', $internalRoute); $controllerName = array_shift($segments) . 'Controller'; $controllerName = ucfirst($controllerName); $actionName = 'action' . ucfirst(array_shift($segments)); $parameters = $segments; // Подключить файл класса-контроллера $controllerFile = ROOT . '/controllers/' . $controllerName . '.php'; if (file_exists($controllerFile)) { include_once($controllerFile); } // Создать объект, вызвать метод (т.е. action) $controllerObject = new $controllerName; $result = call_user_func_array(array($controllerObject, $actionName), $parameters); if ($result) { break; } } } } 

}

Please advise what can be done in this situation.

    3 answers 3

    Well, everything is obvious here:

     'user/register' => 'user/register', 

    Explaining well, without a front slash, the line is added to the current line.

    You need to specify the full path:

     /testTaskForCodeIt/user/user/register 

    Pay attention to the front slash.

    • Please tell me, if I have a current directory, where the project is located can change, how can I prescribe the full path? And where to prescribe it? In the list where I declare all the routes? or only when using this route in html-code? - kittycat_13
    • I just do not understand a little how the absolute path should look in this case. - kittycat_13

    My telepathic abilities tell me what to look for in your code:

    1. header('Location: user/register') in the controller code;

    2. <form action='user/register'> in the view code.

    If you do not place the code at the root, then you cannot afford relative paths. You must use only absolute paths everywhere.

    • I have a problem with just the conversion in the view code. I do not understand a bit, how is the absolute way to register in this case? It is necessary to prescribe taking into account the fact that the name of the current directory where the project is located may change. - kittycat_13

    Thank you all for the advice. Here is my solution if someone comes in handy.

    Router.php

     <?php class Router { private $routes; public function __construct() { $routesPath = ROOT . '/config/routes.php'; $this->routes = include($routesPath); } /** * Returns request string */ public static function getURI() { if (!empty($_SERVER['REQUEST_URI'])) { return trim($_SERVER['REQUEST_URI'], '/'); } } public function run() { // Получить строку запроса $uri = $this->getURI(); $url = []; $url = explode('/', $uri); // Вырезаю название своей текущей папки $direct = array_shift($url); // Создаю константу с названием этой папки define('DIRECT', $direct); $route = implode('/', $url); // Проверить наличие такого запроса в routes.php foreach ($this->routes as $uriPattern => $path) { // Сравниваем $uriPattern и $uri if (preg_match("~$uriPattern~", $route)) { // Получаем внутренний путь из внешнего согласно правилу. $internalRoute = preg_replace("~^$uriPattern~", $path, $route); // Определить контроллер, action, параметры $segments = explode('/', $internalRoute); $controllerName = array_shift($segments) . 'Controller'; $controllerName = ucfirst($controllerName); $actionName = 'action' . ucfirst(array_shift($segments)); $parameters = $segments; // Подключить файл класса-контроллера $controllerFile = ROOT . '/controllers/' . $controllerName . '.php'; if (file_exists($controllerFile)) { include_once($controllerFile); } // Создать объект, вызвать метод (т.е. action) $controllerObject = new $controllerName; $result = call_user_func_array(array($controllerObject, $actionName), $parameters); if ($result) { break; } } } } } 

    Next, I use this constant to create an absolute path:

     <li><a href="/<?php echo DIRECT ?>/user/register">Register</a></li> <li><a href= "/<?php echo DIRECT ?>/user/login">Login</a></li> 
    • 1) a little bit wrong logic for the route. 2) Next time, when the comments are not addressed to the author of the question, put @ <NICK> (In my case: "@Manitikyl, .....") so that I can be notified about your comments and help you. - Manitikyl
    • @Manitikyl, thank you very much) I haven’t figured out all these features yet. And then you can ask, how would you remake the route? I personally do not like how I insert the name of the current directory in the path. But I have not thought about this task globally yet. - kittycat_13
    • It’s a long time to describe the correctness of the route and not enough characters) You can either see the implementation of the routes yourself, or write me a personal message, we will contact you in some way and I will tell you. - Manitikyl