How to Rewrite URLs with mod_rewrite for Apache on Ubuntu 24.04 LTS using PHP
Mod_rewrite is a powerful and flexible module used to perform URL rewriting, allowing you to manipulate URLs as they are requested by clients.
Why Use mod_rewrite
mod_rewrite is an Apache module that provides a powerful and flexible way to rewrite URLs. Here are some common reasons to use it:
Improving SEO: Clean, descriptive URLs are better for search engine optimization (SEO) and user experience. For example, example.com/products/123 can be rewritten to example.com/products/special-widget, making it more readable and relevant.
Model-View-Controller: Model-View-Controller (m-v-c) is a design pattern used in software development. In the case of M-V-C the Uniform Resource Identifier (URI) for https://www.domain.tld/edit/login/1 is the string user/edit/1. User is the controller, edit is the action or method within the controller, and the number 1 is an argument or the user’s id.
Redirecting URLs: It allows for easy redirection of old URLs to new ones. This is particularly useful when you’ve changed the structure of your website or need to redirect traffic from outdated links.
Creating User-Friendly URLs: You can create user-friendly URLs by hiding query strings and parameters. For example, example.com/article?id=456 can be rewritten to example.com/article/456.
Implementing Custom URL Structures: If you have a dynamic website and want to implement a custom URL structure, mod_rewrite can handle the translation of friendly URLs to the underlying script.
Handling Requests Dynamically: It allows for the handling of requests dynamically based on various conditions, such as redirecting requests based on the user agent, geographical location, or other request headers.
Enforcing HTTPS: You can use mod_rewrite to enforce HTTPS by redirecting all HTTP traffic to HTTPS, enhancing security.
Access Control: You can use rewrite rules to control access to certain parts of your site based on IP addresses, user agents, or other criteria.
Cache-Control: You can use it to manage caching by rewriting URLs in a way that incorporates versioning or other mechanisms to control how content is cached.
Overall, mod_rewrite provides a versatile tool for managing URLs and can be an essential part of maintaining a well-organized, user-friendly, and SEO-optimized website.
Steps to Configure mod_rewrite
1) Run this command on the command line: sudo a2enmod rewrite – enables the Apache mod_rewrite module.
2) After enabling the module, you must restart Apache to apply the changes. On the command line run the command sudo systemctl restart apache2.
3) Creating and configuring the .htaccess file. Change the directory to the docroot of the virtual host. Enter cd /var/www/[doman]/public_html/ on the command line. Then enter the command sudo vi .htaccess. Make sure to replace [doman] with your domain name.
Cut and paste the following code into the file being edited by vi.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
# Remove index.php from the URL
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]
</IfModule>
Then save the file.
The .htaccess Directives Explained
<IfModule mod_rewrite.c> : This directive starts a block of configuration that will only be applied if the mod_rewrite module is loaded.
RewriteEngine is a directive used in Apache HTTP Server’s mod_rewrite module. It controls whether URL rewriting rules are enabled or disabled for a particular directory or virtual host.
RewriteBase sets the base URL path for the rewrite rules that follow in the .htaccess file. This is particularly useful when your site is located in a subdirectory, and you need to ensure that your rewrite rules are interpreted correctly relative to that directory.
RewriteCond %{REQUEST_FILENAME} !-f specifies that the rewrite rule following this condition should only be applied if the requested filename does not correspond to an existing file on the server. This is often used in conjunction with RewriteRule to handle URL rewriting, such as redirecting requests to a front controller or a specific script when the requested file isn’t found.
RewriteCond %{REQUEST_FILENAME} !-d is used to apply the following RewriteRule only when the requested URL does not correspond to an existing directory on the server. This is commonly used in scenarios where you want to handle requests dynamically when the requested resource isn’t a real directory, such as routing to a specific script or controller when the directory structure doesn’t match the request.
RewriteRule ^(.*)$ index.php/$1 [L] in summary, this rule tells Apache to redirect any URL request to the root index.php, appending the original URL path to the index.php file for processing. For instance, a request for /something would be internally redirected to index.php, and the string something would be processed accordingly. This setup is commonly used in frameworks or applications where routing is handled by a single entry point, such as index.php, and the rest of the URL is used to determine the specific resource or action(s).
</IfModule> ends the block that was started with the command <IfModule mod_rewrite.c>. All the commands within this block will be applied if the Apache mod_rewrite module is enabled.
The design pattern Model-View-Controller (M-V-C) is a single point of entry model that utilizes the above .htaccess code to transfer the URI entered into the browser, to the root index file. In the case of a PHP M-V-C application, these directives entered into the .htaccess work in conjunction with the PHP function $_SERVER[‘REQUEST_URI’] to determine what controller and method to run along with any arguments. The URL would look something like this your-domain.TLD/controller/method/arg1/argn….
4) For mod_rewrite to work using the above .htaccess directives, you need to configure Apache to allow overrides in your site’s configuration. This is usually done in the <Directory> block of your Apache virtual host configuration files.
At the command line enter cd /etc/apache2/sites-available/.
Enter sudo vi [domain].conf on the command line. Don’t forget to replace [domain] with your domain name.
Insert the following code :
<Directory /var/www/[domain]/public_html/>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
After editing, save the file and exit the editor.
Replace [domain] with your domain name.
This block specifies that the .htaccess file in the directory listed. is allowed to override any server settings for this directory. This works in conjunction with the above .htaccess file directives.
When complete, your virtual host configuration file should look something like this:
<VirtualHost *:80>
ServerAdmin webmaster@[domain]
ServerName [domain]
ServerAlias www.[domain]
DocumentRoot /var/www/[domain]/public_html
<Directory /var/www/[domain]/public_html/>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/[domain].error.log
CustomLog ${APACHE_LOG_DIR}/[domain].access.log combined
</VirtualHost>
Replace [domain] with your domain name.
5) Test the Apache configuration by running apachectl configtest.
When you run apachectl configtest, Apache will check your configuration files for any mistakes and report them back to you, allowing you to fix any errors before restarting or reloading the server.
6) Configure the index.php file. Enter the command line command cd /var/www/[domain]/public_html/.
Then enter the command vi index.php.
Replace what is in the index.php file with the following (or create the file if not there):
<?php
echo '[domain] - ';
echo $_SERVER['REQUEST_URI'];
?>
In PHP, <?php is the PHP opening tag that signals Apache to start processing PHP code.
echo ‘[domain] – ‘;
echo $_SERVER[‘REQUEST_URI’];
The echo command is used to output data to the browser or the console. In this case, it will echo the string ‘[domain] – ‘ and the output of the PHP command $_SERVER[‘REQUEST_URI’].
The PHP command $_SERVER[‘REQUEST_URI’] returns the URI (Uniform Resource Identifier) of the page being requested.
And the last line, ?> signals to Apache to stop processing PHP code.
Anything between <?php and ?> is treated as PHP code.
6) At this point we need to restart Apache so all these changes take effect. On the command line enter the command sudo systemctl restart apache2.
7) Testing
Ensure your rewrite rules are working correctly by testing them in your browser. Open a browser and enter http://[domain]/controller/method/arg1/arg2/arg3 in the URL of the browser and hit enter. You should see the output of the PHP program we created. The output should look like this: [domain] – /controller/method/arg1/arg2/arg3
8) Troubleshooting
If mod_rewrite doesn’t seem to be working:
Run apachectl configtest from the command line. If there is any configuration issues, address them and run apachectl configtest again. Repeat until all issues are corrected.
Another tool that can help you with the Apache mod_rewrite configuration is to run the following command on the command line : sudo tail -f /var/log/apache2/error.log
If there are any errors in the Apache log you can use Google search and/or you can use [https://chatgpt.com/] Artificial Intelligence (AI).
Some other things you can do is :
– Ensure there are no syntax errors in your .htaccess file or Apache configuration.
– Verify that the .htaccess file is in the correct directory : sudo vi /var/www/[domain]/public_html/.htaccess
– Ensure that the AllowOverride directive is set correctly in your Apache configuration : sudo vi /etc/apache2/sites-available/[domain].conf
– Verify the index.php file is configured properly : sudo vi /var/www/[domain]/public_html/index.php
If your Apache virtual host configuration is not working try the following command line commands in order :
– sudo a2enmod rewrite
– sudo systemctl restart apache2
– apachectl configtest
Conclusion
The Apache mod_rewrite module has many reasons for its use. In this article, we cover how to enable the mod_rewrite module, and how to restart Apache. We learned how to create the .htaccess file and we learned what code to put inside of the .htaccess file. We learned what the .htaccess directives mean and what they do. We configured the Apache virtual host configuration file to take advantage of many of the features of the mod_rewrite module. Mostly how it supports the M-V-C design pattern in PHP. Lastly, we learned how to test and troubleshoot the mod_rewrite configuration.