I want to serve all requests for non-existing files via .php
.htaccess configuration:
ErrorDocument 404 /index.php
DirectoryIndex index.php
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [L]
This does seem to mostly work but some specific file extensions (.txt,.jpg, some more?) get handled by apache instead of getting passed through php.
http://localhost:8000/home -> shows homepage
http://localhost:8000/file.zip (does not exist) -> shows custom styled 404 page served by PHP
http://localhost:8000/exists.txt (existing file) -> serves existing file
http://localhost:8000/doesnotexist.txt (does not exist) -> shows default apache 404 page (same as when no PHP is installed)
Is there some default apache handler for specific file extensions?
How can I set ALL requests to get passed through index.php?
I copied your experiment with Docker and the php 7.4-apache image. When opening the url http://localhost:8000/doesnotexist.txt I'm transfered to the index.php file as I would expect to be. The bottom three rewrite rules will rewrite everything to index.php.
First off: You have not posted a docker-compose.yml or Dockerfile, so to be sure: you have to enable the rewriting for Apache by either a command in the dockerfile or a custom Dockerfile like this:
# Dockerfile
FROM php:7.4-apache
RUN a2enmod rewrite
If you would not have enabled the rewrite, an error 500 should appear, because there are no if-conditions around the rewrite rule.
If you did enable the rewriting, the behaviour is still strange, because even if the line ErrorDocument 404 /index.php is not there the bottom rewrite should make that the index.php is served anyway. In other words: The bottom three lines in the .htaccess would make sure that no 404 is served, because everything is rewritten to the index.php.
When you say 'the default apache 404 page' are you talking about the 'Not found' page?
Not Found (H1 tag)
The requested URL was not found on this server.
Apache/2.4.52 (Debian) Server at localhost Port 8000
Try to remove and rebuild the container, so that no weird caching issue can give problems.
And what about your index.php. Is there anything in there that could trigger something strange? Could you post it here?
Try this in your .htaccess file (without the ErrorDocument part):
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ index.php?file=$0 [QSA,L]
Make sure you output 404 if the code does'nt find the file.
Is there some default apache handler for specific file extensions?
No, there is not such a handler by default.
How can I set ALL requests to get passed through index.php?
ErrorDocument 404 /index.php is valid.DirectoryIndex index.php is validRewriteEngine on is validRewriteCond %{REQUEST_FILENAME} !-f is validRewriteCond %{REQUEST_FILENAME} !-d is validRewriteRule ^ index.php [L] is also valid!Keep in mind that you are not rewriting it to the root /index.php, instead you are rewriting without the slash, and it rewrites to the index.php in the current directory. So if index.php doesn't exist in the current directory, chances it can get into an infinite loop.
Try:
ErrorDocument /index.php
DirectoryIndex index.php
RewriteEngine On
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [L] # use '/index.php' if needed to redirect to root index.php
This will redirect that everything exists to index.php, and avoid conflicts with ErrorDocument.
But, I think this actually what you mean to do:
ErrorDocument /index.php
DirectoryIndex index.php
# remove those rewrite rules