Apache on Localhost
Apache HTTP Server is the most widely deployed web server in the world and the default choice in PHP-focused development stacks. It's bundled in XAMPP, WAMP, MAMP, and Laragon — on Windows especially, these one-click stacks make Apache+PHP+MySQL available in minutes. Apache's big advantage over Nginx for local development is per-directory configuration via .htaccess, which means most PHP frameworks and CMSs work out of the box without touching the main config file.
Config File Locations by Stack
| Stack | Platform | Apache Config | Web Root |
|---|---|---|---|
| XAMPP | Windows/Mac/Linux | C:\xampp\apache\conf\httpd.conf | C:\xampp\htdocs\ |
| WAMP | Windows | C:\wamp64\bin\apache\apache2.4.x\conf\httpd.conf | C:\wamp64\www\ |
| MAMP | Mac | /Applications/MAMP/conf/apache/httpd.conf | /Applications/MAMP/htdocs/ |
| Laragon | Windows | C:\laragon\bin\apache\version\conf\httpd.conf | C:\laragon\www\ |
| Ubuntu apt | Linux | /etc/apache2/apache2.conf | /var/www/html/ |
| macOS Homebrew | Mac | /usr/local/etc/httpd/httpd.conf | /usr/local/var/www/ |
Enabling mod_rewrite
mod_rewrite is required by WordPress, Laravel, CodeIgniter, and almost every PHP framework for clean URLs. Without it, you get URLs like index.php?page=about instead of /about.
# In httpd.conf — uncomment this line (remove the #)
LoadModule rewrite_module modules/mod_rewrite.so
# Also ensure AllowOverride is set to All (not None)
# Find the <Directory> block for your web root:
<Directory "C:/xampp/htdocs">
AllowOverride All # <-- change None to All
Require all granted
</Directory>
On Ubuntu: sudo a2enmod rewrite && sudo systemctl restart apache2
Virtual Hosts for Multiple Projects
Virtual hosts let you run multiple sites simultaneously — project1.local, project2.local — each pointing to a different folder. Much cleaner than localhost/project1/ subdirectories.
# Add to httpd-vhosts.conf (or end of httpd.conf)
<VirtualHost *:80>
ServerName project1.local
DocumentRoot "C:/xampp/htdocs/project1/public"
<Directory "C:/xampp/htdocs/project1/public">
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
Then add to hosts file (C:\Windows\System32\drivers\etc\hosts on Windows, /etc/hosts on Mac/Linux):
127.0.0.1 project1.local
.htaccess — Common Patterns
.htaccess files sit inside a directory and apply Apache config to that directory without touching the main config. Requires AllowOverride All to work.
# WordPress pretty permalinks
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
# Laravel / Symfony / most PHP frameworks
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
# Force HTTPS locally
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
PHP Configuration
Apache uses mod_php to execute PHP files directly — simpler than Nginx's PHP-FPM setup. Find your php.ini location:
<?php phpinfo(); ?> // Create this as test.php in your web root
Common php.ini tweaks for local development:
display_errors = On
error_reporting = E_ALL
max_execution_time = 120
upload_max_filesize = 64M
post_max_size = 64M
memory_limit = 256M
Troubleshooting
| Problem | Fix |
|---|---|
| Port 80 in use (usually Skype or IIS on Windows) | Change Apache to port 8080 in httpd.conf: Listen 8080 |
| mod_rewrite not working | Confirm LoadModule line is uncommented AND AllowOverride All is set for the directory |
| .htaccess ignored | AllowOverride must be All, not None — check the <Directory> block covering your folder |
| Virtual host not resolving | Add the domain to /etc/hosts — DNS lookup happens before Apache routing |
| Check Apache error log | XAMPP: C:\xampp\apache\logs\error.log | Ubuntu: /var/log/apache2/error.log |