Learning Objectives – after this chapter you will be able to:
- Explain what an
.htaccessfile is and how Apache applies it. - Enable
.htaccesswithAllowOverridein XAMPP. - Password-protect a folder with HTTP Basic authentication and
htpasswd. - Block access to sensitive files, disable directory listings and add custom error pages.
- Write simple URL-rewriting rules and change PHP settings per folder.
What is .htaccess?
In several web servers – most commonly Apache – .htaccess (hypertext access) is the default name of a directory-level configuration file that allows decentralised management of the web server's configuration. The .htaccess file is placed inside the web tree and can override a subset of the server's global configuration; the extent of this subset is defined by the server administrator.
The original purpose of .htaccess was per-directory access control – for example requiring a password to access the content – hence the name. Nowadays .htaccess can override many other settings, mostly related to content control: content type and character set, error pages, URL rewriting, CGI handlers and so on.
- In Apache, the format of
.htaccessis the same as the server's global configuration file (httpd.conf). - Directives in
.htaccessapply to the current directory and all its sub-directories (unless disabled in the server configuration), but for reasons of performance and security they cannot affect parent directories. - The file name begins with a dot because dot-files are, by convention, hidden files on Unix-like operating systems. (In Windows Explorer you may need to name it
.htaccess.or save it from your editor with All files.) - Apache reads
.htaccesson every request, so changes take effect immediately – no restart needed.
Enabling .htaccess
Apache uses .htaccess files only where httpd.conf allows it with the AllowOverride directive:
| Value | Meaning |
|---|---|
| AllowOverride None | .htaccess files are ignored completely. |
| AllowOverride AuthConfig | Only authentication directives (AuthType, AuthUserFile, Require …) are allowed. |
| AllowOverride All | All directives that are permitted in .htaccess are allowed. |
Old notes say: "Open the httpd.conf file and convert AllowOverride None into AuthConfig". In XAMPP the <Directory "C:/xampp/htdocs"> block already contains AllowOverride All (see Chapter 2), so .htaccess works out of the box. If you change httpd.conf, restart Apache.
Password-Protecting a Folder
HTTP Basic authentication asks the browser to show a login box. Two files are needed: a password file containing user names and encrypted passwords, and the .htaccess file in the folder to protect.
Step 1 – create the password file with htpasswd
Apache's htpasswd program creates the password file. Keep the file outside htdocs, so that it can never be downloaded. Open the XAMPP Shell:
# -c creates a new file; omit -c when adding more users C:\xampp\apache\bin\htpasswd.exe -c C:\xampp\passwords\.htpasswd admin New password: ****** Re-type new password: ****** Adding password for user admin
The same on the Linux test server used for this book (-b takes the password from the command line):
mkdir -p /opt/lampp/passwords htpasswd -cbB /opt/lampp/passwords/.htpasswd admin Secret@123 htpasswd -bB /opt/lampp/passwords/.htpasswd asha Asha@2026 cat /opt/lampp/passwords/.htpasswd | cut -c1-40
admin:$2y$05$5otUW0zH38s/Zoz9mnUg9OW80bG asha:$2y$05$DtzxzsWeOk46ZHlpti8xMu9oO9B2 Adding password for user admin Adding password for user asha
Each line holds username:encrypted-password; -B uses the strong bcrypt algorithm.
Step 2 – create .htaccess in the folder to protect
Create a text file named .htaccess in the directory you want to restrict – here phpbook/ch22/members. It needs only the following lines:
AuthType Basic AuthName "Restricted Area" AuthUserFile /opt/lampp/passwords/.htpasswd Require valid-user
- AuthType Basic – use HTTP Basic authentication.
- AuthName – the text shown in the login box (the "realm").
- AuthUserFile – the full path of the password file (on Windows e.g.
"C:/xampp/passwords/.htpasswd"). - Require valid-user – any user listed in the password file may enter (
Require user adminwould allow only admin).
Older notes wrap Require in <Limit GET POST> … </Limit>; that only protects those two methods and is not needed – a plain Require protects every request method.
<?php echo "<h3>Members area</h3>"; echo "Welcome, " . htmlspecialchars($_SERVER['PHP_AUTH_USER'] ?? $_SERVER['REMOTE_USER'] ?? '') . "!<br>"; echo "Authentication type: " . ($_SERVER['AUTH_TYPE'] ?? ''); ?>
Unauthorized This server could not verify that you are authorized to access the document requested. Either you supplied the wrong credentials (e.g., bad password), or your browser doesn't understand how to supply the credentials required. Apache/2.4.58 (Ubuntu) Server at localhost Port 80
Without a user name and password Apache answers with 401 Unauthorized (above). After entering a valid user name and password in the browser's login box:
Members area Welcome, admin! Authentication type: Basic
A wrong password gives the 401 page again. The browser remembers the credentials until it is closed.
Basic authentication sends the user name and password only Base64-encoded, not encrypted. On a real server always combine it with HTTPS.
Blocking Access to Files and Folders
Hide configuration and template files
Files such as config.php backups, .inc, .phpm and .phtml templates (Chapter 19), .sql dumps or .log files should never be downloadable:
# Block direct access to sensitive file types
<FilesMatch "\.(phtml|phpm|inc|sql|log|bak)$">
Require all denied
</FilesMatch>
# Do not list the contents of folders without an index file
Options -Indexes
# Custom error pages
ErrorDocument 404 /phpbook/ch22/notfound.php
ErrorDocument 403 /phpbook/ch22/forbidden.php
# Pretty URLs: /phpbook/ch22/product/25 -> product.php?id=25
RewriteEngine On
RewriteBase /phpbook/ch22/
RewriteRule ^product/([0-9]+)$ product.php?id=$1 [L,QSA]<?php http_response_code(404); echo "<h3>Sorry, page not found</h3>"; echo "The page " . htmlspecialchars($_SERVER['REQUEST_URI']) . " does not exist. "; echo "<a href='/phpbook/ch22/'>Go to home</a>"; ?>
Requesting the database dump is now refused, and Apache shows our custom 403 page:
Access denied You are not allowed to open /phpbook/ch22/backup.sql.
Disabling directory listings
If a folder has no index.php/index.html, Apache normally shows a list of all its files – an open invitation to attackers. Options -Indexes turns this off:
Access denied You are not allowed to open /phpbook/ch22/docs/.
Custom error pages
ErrorDocument replaces Apache's standard error messages with your own pages:
Sorry, page not found The page /phpbook/ch22/no-such-page.php does not exist. Go to home
URL Rewriting with mod_rewrite
mod_rewrite (enabled in XAMPP) maps friendly URLs to real scripts. The rule in our .htaccess turns product/25 into product.php?id=25:
<?php $id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT); echo "Requested URL: " . htmlspecialchars($_SERVER['REQUEST_URI']) . "<br>"; echo "Script running: product.php<br>"; echo "Product ID received: " . ($id === false || $id === null ? "invalid" : $id); ?>
Requested URL: /phpbook/ch22/product/25 Script running: product.php Product ID received: 25
| Part | Meaning |
|---|---|
| RewriteEngine On | Switches the rewriting engine on. |
| RewriteBase | The URL path of the folder containing .htaccess. |
| ^product/([0-9]+)$ | The pattern (a regular expression, Chapter 12): "product/" followed by digits. |
| product.php?id=$1 | The target; $1 is the text captured by ([0-9]+). |
| [L,QSA] | L – last rule; QSA – append the original query string. |
Other Useful Directives
# Force HTTPS (on a server with an SSL certificate)
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# Allow only one IP address (e.g. an admin folder)
Require ip 192.168.1.25
# Change PHP settings for this folder (Apache module PHP, as in XAMPP)
php_value upload_max_filesize 10M
php_flag display_errors Off
# Default page of the folder
DirectoryIndex home.php index.phpKey Takeaways
.htaccessis Apache's per-directory configuration file; it applies to its folder and sub-folders.- It works only where
AllowOverridepermits it – XAMPP's htdocs hasAllowOverride All. - Password protection: create users with
htpasswd, thenAuthType Basic,AuthName,AuthUserFileandRequire valid-user. - Keep password files outside htdocs and use HTTPS with Basic authentication.
<FilesMatch> … Require all denied,Options -IndexesandErrorDocumentharden a site.RewriteEngine/RewriteRulecreate friendly URLs;php_valuechanges PHP settings per folder.
Program File
Extract the ZIP into C:\xampp\htdocs. It creates the folder phpbook/ch22 used in the file labels above; open the programs at http://localhost/phpbook/… with Apache (and MySQL, where needed) started in the XAMPP Control Panel.
Question / Answer (15 questions)
MCQ Test : Check Your Understanding (5 questions)
Select an option and press Check Answer, or answer all questions and press Submit Test to see your score. Each answer comes with an explanation.
Bibliography/References
The notes on this page are the author’s own compilation from the e-book PHP: Basics to Advance. Every program was run on Apache with PHP 8 and MariaDB, and the output shown is the real result of that run. The works listed below were consulted and are cited for attribution and further reading. Product names and trademarks belong to their respective owners.
- The Apache Software Foundation. (n.d.). Apache HTTP Server Tutorial: .htaccess files. https://httpd.apache.org/docs/2.4/howto/htaccess.html
- The Apache Software Foundation. (n.d.). Authentication and Authorization. https://httpd.apache.org/docs/2.4/howto/auth.html
- The Apache Software Foundation. (n.d.). htpasswd – Manage user files for basic authentication. https://httpd.apache.org/docs/2.4/programs/htpasswd.html
- The Apache Software Foundation. (n.d.). Apache mod_rewrite Introduction. https://httpd.apache.org/docs/2.4/rewrite/intro.html
- The Apache Software Foundation. (n.d.). Apache Core Features – AllowOverride. https://httpd.apache.org/docs/2.4/mod/core.html#allowoverride