You should implement routing in PHP

Url routing in PHP and what it's useful for

Routing is the independent processing of web requests to the server by PHP. For this purpose, individual routes (path information) are created and then assigned to a responsible function or class (also called controller) Web MVC (Model View Controller). This is useful so that you do not have to create a separate file for each page, footers and headers can be included automatically and parameters can be passed more easily, e.g. (see URL above). With Views you can create components so that you can use certain parts of your website everywhere.

If you use the router in combination with a database, you can, for example, immediately check the specification of parameters. HelloCoding checks whether the item ID called up exists or not. If this is not the case, an error message can be output in the same request.

Inquiry types

Depending on the request, your browser also provides data. These are mostly delivered via GET or POST. You have probably heard these words before, if you wanted to submit a form in HTML. GET are normal requests via the URL, POST are encrypted values ​​that are packaged in the request and supplied once, like a kind of cookie.

There are also PUT, DELETE, OPTIONS, PATCH and HEAD which are used more for APIs.

Short digression: APIs are interfaces for external programs, websites or similar which work with the data of your website or your system. Thus you can, for example, implement data processing, which can then be used via a website and an app. Both of them only send web requests to your system, which then interacts with the database.


You don't have to reinvent the router every time in PHP. There are many frameworks that professionally take care of the routing for you. For example, the Bramus router, Nikic's Fastrouter, but also large PHP frameworks such as Laravel and Symfony have integrated routing. Personally, I like the Bramus router best because it is very easy to use.

Install the Bramus router

I use Composer to install Bramus. If you haven't installed Composer yet, you can download it as a ZIP, but I would recommend reading the Composer article first, as Composer makes installation easier and more maintainable. If it is installed, you can install the router using the following command:

Now the router will be installed in your directory and you can use it. If you are using versioning software like Git, you can write the folder in yours, then it will not be pushed. This saves space on the Git server. Now create an index.php file in your web directory and include the Composer Autoloader.

Forward requests to the router

Since the web server does not know by default whether you have a router or not, we have to tell it beforehand where to forward the requests to. For this purpose, all requests should first be routed normally by the server, since images or other CSS or Javascript files do not have to be processed by PHP and no further processing should be triggered to slow down the homepage.

Apache web server

With XAMPP on the local Windows Recher or on Linux in the productive system, a file can be created in the main directory. This is read out and processed with every request, which is why it should be written concisely. A so-called rewrite engine is used here, which, if the file path does not find a file, forwards the request to a file. I've named this file index.php here, but you can also rename it to router.php or main.php. This means that no further changes need to be made in the server configuration. But if you want to save a bit of performance and be able to process 5-10 requests seconds more, you can also set this in the server configuration and then restart the server.

Debug with the integrated web server

If you do not want to test your web server with an Apache virtual host, but rather with the integrated PHP web server, you can start it as follows:

But the integrated web server has a problem: static content such as images are not routed. You must therefore recognize high up in your script, preferably in the first line, whether it should route the file or not.

In this code, I first ask whether it is the local development environment or not. If this is not the case, the if-condition is aborted and not executed any further. If it is, however, in the next step I use a regex to check whether there is "png", "jpg", "jpeg", "css", "js" or "svg" at the end of the file extension. If so, I exit the script with and PHP routes the request normally in the filesystem.

Create routes

Now that you can access the class and all important requests are forwarded to the index.php, create an instance of the class.

I already explained to you above that there are different ways to request a website. As long as you only write a website and no API, GET and POST are sufficient, but you can also route several or all of the HTTP methods.

What are routing patterns

Routing patterns are strings that indicate the route. You define what has to be behind the domain or the URL so that a certain action is carried out. For the homepage one is enough, for the contact form you could enter. I.e. is passed to the function with the parameter and to.

If you want to transfer values ​​via the URL (more on that in a moment), Regex can also be used. If an ID can only be numeric, you could use, or if it can only be a six-digit hexadecimal, then you can specify.

Example GET

To route your main page, I would use GET. Get can be used for all pages that should only display something in the browser. First of all, let's put "Hello World" on your homepage

Pass information via GET

You can also pass information about the URL without having to use a question mark as before ( As explained above, you can now use regex in the pattern to pass a valid value.

Transfer optional parameters via GET

In order not to have to specify three different routes for optional parameters, you can also use subpatterns and subroutes with the Bramus router. Subpatterns are regular expressions, just nested inside each other. If you don't know a regex, you'll have a hard time doing it and I recommend subrouting. But I want you to have seen it at least once anyway.

The pattern defined here means :, however, everything from is optional. The page can be called up with, and. The return at the end just ends the anonymous function and tells PHP the work for this route is done.

I'll come back to submounting again. First the route is defined and through this the instance is made accessible to the router. Further sub-routes can now be used in the route. So now the route and was allowed.

Example POST

Now that you have also installed a contact form on your site, you would like to post these values ​​to your backend. The route "/ contact" is only used for GET requests. If you send your data by post, you can forward your form to the same page, but other processing can now be started:

Create a 404 page

In order to be able to create 404 pages, there is a separate function in the Bramus router. Remember: Always set an error header so that you signal to the client that this request has failed. All requests that cannot be routed will now be forwarded to this route.

Trigger error 404

If a page does not exist, you can process this request directly. In the case of non-defined requests, the function is carried out by default. The 404 page can also be triggered in other pages. To do this, the router instance must also be made accessible. In the example here I want to make the website accessible only during the week. This shouldn't exist on the weekend.

Execute PHP code before the route

If an admin route exists, it should first check whether the user is logged in at all. However, since the session should not be checked individually for every function, the Bramus router can execute code before the route. So everything only has to be programmed once and is constantly reused.

In this example, all GET and POST requests that begin with "admin" are checked to see whether the session variable is set. If this is not the case, the user will be redirected to the log-in page and the request will be terminated. This prevents users who are not logged in from reaching a route that they are not allowed to reach.


Routes are a nice tool for building nice looking urls. Especially in combination with controllers and views, code can also be reused multiple times without having to write redundant, inconsistent code. By adhering to the uniform data structure of larger frameworks (e.g. Laravel, Symfony, Shopware), better maintainability can also be guaranteed. Since I've dealt with routes, I don't want to be without them for larger applications.

Feel free to leave me a comment on the article and how it helped you or what would help you to better understand the topic. Or did you discover a mistake that I should correct? Feel free to write me a feedback on this as well!

Article was last updated on April 21, 2021.
Image source - Many thanks to the creators for this image