What is the most efficient way to route URLs in PHP mvc?

I am developing a simple php mvc that will do a minimum, but work the way I need it, this is my first time using the mvc approach compared to prodcedural, so I am learning how I go ..

During development, I accidentally created it in a strange style, currently the main .htaccess contains almost all physical rewrites, for example a forum:

 RewriteRule ^forum/([a-zA-Z0-9_]+)_([0-9]+)/$ index.php?controller=forum&method=showThread&urlTitle=$1&threadId=$2 [L] RewriteRule ^forum/([a-zA-Z0-9_]+)_([0-9]+)/all/([0-9]+)$ index.php?controller=forum&action=showThread&urlTitle=$1&threadId=$2&page=$3 [L] 

How it works at the moment, all the URLs are directed to index.php, and then it takes which controller and method to use from the url using:

index.php

 $actionName = $_GET['action']; $controllerName = ucfirst(strtolower($_GET['type'])).'controller'; $controller = new $controllerName; $controller->$actionName(); 

controller /forumcontroller.php

 class forumcontroller{ function showThread() { $thread = new Thread($_GET['threadId'], $_GET['uriTitle']); require "templates/thread.php"; } 

but this means that users can go to places where I don’t want them to have access either, for example:

 /public_html/templates/index.php 

What I need?

I think, instead, the main .htaccess should look something like this:

 RewriteEngine on RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ index.php?url=$1 [L,QSA] 

and then in index.php you will use something like:

 $url = explode("/", `$_SERVER['QUERY_STRING']);` $controller = $url[0]; //Returns "forum" $data = $url[1]; //Returns the forum title and id 

but with this approach, I don’t understand how you invoke an action inside the controller with data only?

You did not need to do something like:

  if(!$data) $controller->loadForum(); elseif($data) $controller->loadForumThread($data); 

Conclusion

I just don’t understand how best to perform routing for a site that has a lot of friendly URLs in different formats, I understand how mvc should work, but I'm struggling to understand part of the routing and all the examples that I come across seem extremely complicated!

I'm really trying to figure out how to encode .htaccess and controllers to handle multiple URLs in different formats, for example:

 domain.com domain.com/uploads domain.com/profiles/username domain.com/messages/inbox domain.com/messages/createnew/userId domain.com/forum/all/2 domain.com/forum/title_1/ domain.com/forum/title_1/all/3 
+4
source share
1 answer

Here is an approach similar to your second .htaccess example.

 $request = explode('/', substr($_SERVER['REQUEST_URI'], 1)); // Clean request array of empty elements foreach($request as $k => $v) // Clear any empty elements if(!$v) unset($request[$k]); $request = array_values($request); // Renumber array keys 

This gives a numerical index array representing the requested URI. An application may assume that the first value in the request is the name of the controller:

 if(count($this->request) == 0) $request[] = 'DefaultController'; // Responsible for homepage $this->controller = new $request[0]( $request ); 

I also pass the $context variable to the controller constructor, but this is beyond the scope of this question (it is responsible for connecting to the database, current user data and session data).

After that, it just sends a request: $this->controller->dispatch()

Inside the send method, the controllers themselves know an array of requests. For example, in your list of URLs, consider a third example: domain.com/profiles/username :

The controller will be called "Profiles":

 class Profiles { private $request, $context; public function __construct($request, $context) { $this->request = $request; $this->context = $context; } public function dispatch() { if(count($this->request) == 2 && $this->request[1] == 'username') { // Load data from model for the requested username ($this->request[1]) // Show View } } } 

There are better ways you can map query vectors to actions, but hopefully you get a jist.

+3
source

All Articles