If one Apache virtual host serves PHP correctly while another downloads .php files, displays source code, or returns a 502/503, troubleshoot in this order: prove which virtual host handled the request, identify whether that host uses PHP-FPM or mod_php, then install the matching PHP handler in that host and point it at the real PHP-FPM endpoint. A correct PHP directive in the wrong virtual host has no effect.
Antihost offers Linux VPS plans with full root access, unlimited traffic on a 1 Gbps port and a 14-day free trial.
What is actually failing?
Apache handles a PHP request in two separate decisions. First, it selects a virtual host from the connection’s IP address and port, then compares the request’s Host header with ServerName and ServerAlias. Only after that selection do the directives in the chosen virtual host apply. Second, Apache must map the resulting .php filename to a PHP execution handler.
As an Amazon Associate I earn from qualifying purchases.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
That separation explains most confusing reports. If Apache selects the wrong host, you may see another site’s HTML, another host’s logs, or a default document even though the PHP configuration you edited looks correct. If Apache selects the right host but no PHP handler is loaded there, it may send the file as a download or return its source as plain text. If a handler exists but points to an unavailable PHP-FPM socket or port, the result is commonly a 502 or 503.
The reliable fix is therefore not “add a PHP line somewhere.” It is to verify the request-to-vhost mapping, choose one supported PHP integration model, configure it in the selected host, and test the complete path.
#1 Best Overall
How Apache chooses the virtual host
IP address and port come first
Apache first finds the virtual hosts listening on the destination IP address and port. A host listening on *:80 is not the same mapping as one listening on a specific address or on *:443. If the request reaches a different listener than expected, the correct-looking name directives will never be considered.
The Host header chooses among name-based hosts
For name-based virtual hosting, Apache compares the request’s Host header against each candidate’s ServerName and ServerAlias. The hostname typed into a browser is normally converted into that header, but testing the header explicitly removes DNS, proxy, and browser variables from the diagnosis.
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallCrashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteIf no candidate matches the hostname, Apache uses the first virtual host for that IP-and-port group as the default. This is why a typo, missing alias, or duplicate name can make a request appear to “ignore” its PHP settings: the request is being processed by a different host.
Inspect the parsed map, not just the files you remember editing
Run:
apachectl -S
On some distributions the equivalent command is supplied through the distribution’s Apache control wrapper. The output shows parsed virtual hosts, their IP-and-port bindings, the default host for each group, aliases, and duplicate or conflicting names. Check all of the following:
- The expected
ServerNameappears under the listener and port you are actually using. - Every hostname you use is present as a
ServerNameorServerAlias. - The HTTP and HTTPS versions are both configured if you test both schemes.
- No other host claims the same name or silently becomes the default.
- The file and line reported by Apache are the ones you intended to enable.
Do not infer the active configuration from a directory listing alone. Apache parses included files, enabled-site links, and module configuration; apachectl -S reports the result of that parsing.
Rank #2
- Used Book in Good Condition
Prove which virtual host handled the request
Send an explicit Host header
Test the listener directly while supplying the exact hostname:
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →curl -H "Host: example.test" -i http://127.0.0.1/
Replace example.test with the host’s real name and use the listener’s address and port. For TLS, test the HTTPS listener with a hostname-aware request; a plain HTTP request to port 443 does not exercise the same virtual-host selection.
Inspect the response status, redirects, and body. Requesting a deliberately nonexistent path is useful because it should generate a predictable 404 in the selected host rather than accidentally serving an index page:
curl -H "Host: example.test" -i http://127.0.0.1/this-path-should-not-exist
Give each host identifiable logs
Configure distinct access and error logs for each virtual host, or include the virtual-host name in the access-log format. Repeat the known-404 request and confirm which log receives it. Then inspect that same host’s error log while requesting the PHP URL.
This separates three cases that look similar in a browser:
- No entry in the expected log means the request did not reach that host, listener, or server.
- An access entry with no PHP-related error suggests Apache handled the request without invoking a PHP backend.
- An error entry mentioning a proxy, socket, or upstream points to PHP-FPM connectivity rather than name matching.
Always perform this identification before changing a handler. Otherwise you can repeatedly edit an inactive host while the request continues to hit the default.
Choose the PHP execution model
PHP-FPM with mod_proxy_fcgi
For Apache 2.4 and current deployments, PHP-FPM behind mod_proxy_fcgi is the preferred integration documented by both Apache and PHP. PHP runs in a separate process manager instead of inside Apache workers. That provides independent PHP restarts, process management, process isolation, and compatibility with threaded event or worker MPMs.
PHP-FPM can listen on a TCP address and port or on a Unix-domain socket. The Apache handler must use the endpoint that the FPM pool actually listens on; a plausible-looking socket path is not enough.
mod_php
mod_php embeds PHP in Apache. It requires the PHP module to be loaded and a handler mapping for PHP files. Most non-ZTS PHP builds require Apache’s prefork MPM, so a mod_php recipe copied onto an event or worker MPM commonly fails or cannot load. Verify the module and MPM instead of mixing instructions from different integration models.
Do not combine recipes casually
A host should have one deliberate PHP path. Leaving an old mod_php mapping in place while adding a proxy handler can make diagnosis difficult and can route different extensions through unexpected handlers. Decide whether the host uses FPM or mod_php, remove contradictory mappings, and then validate the parsed configuration.
Rank #4
| Characteristic | PHP-FPM with mod_proxy_fcgi | mod_php |
|---|---|---|
| Process model | PHP runs as a separate FPM-managed process pool. | PHP is embedded in Apache worker processes. |
| MPM fit | Works with threaded event or worker MPMs. | Most non-ZTS builds require prefork. |
| Operational control | PHP can be restarted and managed independently of Apache. | PHP lifecycle follows Apache’s process lifecycle. |
| Typical Apache mapping | SetHandler using a TCP or Unix-socket FCGI proxy. |
SetHandler application/x-httpd-php after loading the PHP module. |
| Primary failure points | Wrong endpoint, unavailable service, socket permissions, or an overly broad match. | Module not loaded, incompatible MPM, or missing PHP handler. |
Configure PHP-FPM in the selected virtual host
Use a narrow, file-aware handler
A typical Apache 2.4 pattern is:
<FilesMatch "\.php$">
<If "-f %{REQUEST_FILENAME}">
SetHandler "proxy:fcgi://127.0.0.1:9000"
</If>
</FilesMatch>
The regular expression matches PHP filenames, while the -f condition requires the requested path to be a real file. Replace 127.0.0.1:9000 with the address and port used by the relevant FPM pool. A pool listening on another port will not answer this configuration.
Use a Unix socket when that is the pool endpoint
For a Unix socket, the form is:
<FilesMatch "\.php$">
<If "-f %{REQUEST_FILENAME}">
SetHandler "proxy:unix:/run/php/php-fpm.sock|fcgi://localhost/"
</If>
</FilesMatch>
Use the actual socket path on the machine. Socket ownership and permissions must allow Apache to connect. If the file does not exist, belongs to an inaccessible pool, or is recreated at a different path after a service restart, Apache will log a backend connection failure and the request can become a 502 or 503.
Keep the handler in the host that serves the application
Place the FilesMatch block inside the selected virtual host when PHP behavior must differ by site. A handler placed only in another host, or in a file that is not enabled, cannot affect this request. Conversely, a global handler may make one host appear to work while hiding the fact that the intended host has no explicit PHP configuration.
Free tools Windows power users keep installed
One-click scans. No signup required.
Why the existence check matters for front controllers
Applications often send non-file URLs to an index script through a fallback mechanism. A PHP handler that catches every URL ending in .php, including paths that do not exist, can intercept those requests before FallbackResource or application routing has a chance to run. The -f guard limits the FCGI handoff to real scripts and leaves nonexistent paths to the intended fallback behavior.
Configure mod_php when you deliberately use it
Confirm the module and MPM
First verify that Apache has loaded the PHP module and that the active MPM is compatible with the PHP build. A non-ZTS build paired with event or worker MPM is a common mismatch. The exact module-list command varies by distribution, so use the platform’s Apache module inspection command and check the loaded-module output rather than assuming the package installation succeeded.
Best Value
- Used Book in Good Condition
Map PHP files to the module
The Apache recipe for mod_php uses a handler such as:
<FilesMatch "\.php$">
SetHandler application/x-httpd-php
</FilesMatch>
This mapping belongs in the active virtual host when the behavior is host-specific. If the module is absent, the handler name has nothing capable of executing it; Apache may instead serve the file as text or download it.
Recommended Free Tools
Do not use an FPM proxy and mod_php as accidental fallbacks
Decide which handler should own .php requests. Remove stale directives from older configurations, then reload only after Apache accepts the complete configuration. Keeping both models in different include files makes the effective handler dependent on parse order and enabled-site state.
Validate, reload, and test safely
- Check syntax first. Run Apache’s configuration test command, commonly
apachectl configtest. Fix every syntax error before attempting a reload. - Recheck virtual-host parsing. Run
apachectl -Sagain and confirm the expected names, listener, default host, and source file are present. - Reload gracefully. Use the service-management command appropriate to your distribution for a graceful Apache reload. The exact unit name and command differ by operating system.
- Verify the PHP-FPM endpoint. Confirm that the FPM service is running and that its configured TCP port or Unix socket matches the handler exactly.
- Request a minimal script through the real hostname. Use an explicit
Hostheader when testing a local listener, then check the selected host’s access and error logs. - Remove diagnostic files. If you create a
phpinfo()script, delete it after testing because it exposes detailed configuration information.
A minimal test script can contain only a recognizable output string. That proves execution without publishing a complete environment report. If the script downloads, Apache never handed it to a PHP handler. If it returns a gateway error, the handler was selected but the FPM backend could not complete the request.
Symptom-to-cause troubleshooting
| Symptom | Likely cause | Verification and fix |
|---|---|---|
| Another site’s HTML appears | The hostname did not match, names are duplicated, or the request reached the default virtual host. | Run apachectl -S, send an explicit Host header, inspect per-host logs, and make names unique. |
| The PHP file downloads or source code is displayed | No PHP handler exists in the selected host, or the PHP module is not loaded. | Confirm the selected host, inspect loaded modules, then add the correct FPM SetHandler or mod_php mapping. |
| A PHP URL returns 502 or 503 | The FPM service, port, socket path, or socket permissions are wrong or unavailable. | Read the selected host’s error log, check the FPM service and socket, and make the handler endpoint match the pool configuration. |
| Only one virtual host executes PHP | The handler is global or exists only in another host. | Put the intended handler in the selected host, then confirm the mapping with apachectl -S, explicit-host testing, and per-host logs. |
| Front-controller URLs return unexpected 404 or 500 responses | The PHP handler catches nonexistent script paths before fallback routing can run. | Wrap the handler in the -f existence check so only real PHP files are sent to FPM. |
Security checks before you leave the fix in place
Do not proxy every path that happens to contain “.php”
A greedy proxy rule can turn an uploaded path such as /uploads/file.jpg/anything.php into an executable PHP request. Apache’s PHP-FPM guidance warns about this class of upload-to-code-execution risk. Restrict matching to genuine PHP files, validate path information when your application needs it, and avoid executing files from upload directories.
Keep uploads non-executable
Where possible, store user uploads outside the document root. If uploads must be web-accessible, use a separate location and ensure the PHP handler cannot process them. The existence check prevents nonexistent script names from being proxied, but it does not replace a deliberate upload-directory policy.
Limit diagnostic exposure
Per-host error logs are valuable during diagnosis, but they can contain filesystem paths, backend details, and request data. Keep access restricted, remove temporary test scripts, and avoid leaving verbose diagnostics enabled on a public host.
A compact decision path
- Wrong content: solve name matching first with
apachectl -S, an explicitHostheader, and identifiable logs. - Source or download: the selected host lacks a working PHP handler; choose FPM or mod_php and map
.phpfiles. - 502 or 503: the handler is being used, but the FPM endpoint or service is not reachable; verify the exact port or socket and its permissions.
- Routing failures: add the real-file guard so fallback routes are not mistaken for PHP scripts.
- New deployment: use PHP-FPM with
mod_proxy_fcgiunless a legacy constraint specifically requires mod_php.
The decisive test is always end-to-end: the intended hostname selects the intended virtual host, that host maps real PHP files to one execution model, and the chosen handler reaches a live PHP backend. Once those three links are proven in the logs and with an explicit-host request, the apparent “Apache will not run PHP” problem has a concrete cause rather than a mysterious one.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




