A legacy application is passed through Slim framework by passing all legacy PHP file requests to index.php in a .htaccess file. Further, a Symfony application is set up in a folder with an Alias set up.
VHost configuration with PHP-FPM
<VirtualHost *:80>
ServerName example.com
DocumentRoot /path/to/app/slim
Alias /system /path/to/app/symfony
<IfModule mpm_itk_module>
AssignUserId web_user web_user
</IfModule>
<LocationMatch "^(.*\.php)$">
ProxyPass fcgi://127.0.0.1:9001/path/to/app/slim
</LocationMatch>
</VirtualHost>
Files for testing:
/path/to/slim/index.php
<?php echo "slim";
/path/to/slim/.htaccess
RewriteEngine On
RewriteBase /
RewriteRule ^hello$ /hello.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
/path/to/slim/hello.php:
<?php echo "hello";
/path/to/symfony/app.php
<?php echo "symfony";
/path/to/symfony/.htaccess:
DirectoryIndex app.php
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_URI}::$1 ^(/.+)/(.*)::\2$
RewriteRule ^(.*) - [E=BASE:%1]
RewriteCond %{HTTP:Authorization} .
RewriteRule ^ - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^app\.php(?:/(.*)|$) %{ENV:BASE}/$1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
RewriteRule ^ %{ENV:BASE}/app.php [L]
</IfModule>
Test Uri Expected Output Actual Output
/hello.php hello hello
----------------------------------------------------------------------
/test slim slim
----------------------------------------------------------------------
/test.php slim 404 error
[proxy_fcgi:error] [pid 18527] [client x.x.x.x:45357] AH01071: Got error 'Primary script unknown\n'
----------------------------------------------------------------------
/system/hello symfony symfony
/system/app.php/hello symfony symfony
I have tried this both on Ubuntu 16 and CentOs 7 with the same results. Using Apache 2.4, AllowOverride All and mod_rewrite enabled. PHP7-fpm
What else have I tried:
1)
ProxyPass fcgi://127.0.0.1:9001/path/to/app/slim/index.php
for /test.php shows "slim", however the request is then misinterpreted in slim framework as "/".
According to Apache documentation .htaccess
should be processed first.
What is the best way to resolve this?
(Note: Bounty says I don't want to standardise Apache configuration. This is a typo.
I DO WANT TO standardise Apache configuration)
Best Answer
Your problem is the use of
<LocationMatch>
for proxying to php-fpm, which is applied to all URLs before checking whether a corresponding file exists. (ProxyPassMatch
would do the same thing more elegantly, by the way.) To quote the documentation on<Location>
:However, you obviously do want to check if the PHP file exists before passing it to php-fpm. This can be accomplished by using
<FilesMatch>
andSetHandler
instead:(I myself am using unix sockets here, as in the documentation I linked to above, so I'm not 100% confident this is the right syntax for the URL.)
This way, only files will be redirected to php-fpm, and your mod_rewrite rules have a chance of being applied even to URIs ending in .php when the corresponding files don't exist.
Note also that using
FallbackResource
has no influence on this, because again the<LocationMatch>
has priority and proxies even inexistent URIs to php-fpm. It only redirects those URIs that would otherwise use Apache's builtin 404 handler, but that doesn't kick in as you already noted.