I'm trying to get the .php extension to not be required when you view a php file. My current config is the following:
<VirtualHost *:80>
DocumentRoot /var/www/server
ServerName localhost
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
RewriteRule ^([^/\.]+)/?$ $1.php [L,QSA]
</VirtualHost>
However, it doesn't work as I'm getting 404's when I try access a files like login.php as login, for instance. My server setup is kind of strange, in the /var/www/server is a symbolic link to another folder Dev/server/. Also, since it's localhost, I'm accessing it via localhost/project/login.php.
You are correct that regex rule looks like it would fail if the URI contained periods in the path. Which is bad since RFC does not say they are not valid.
You could try this:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ([^\\.]+)$ $1.php [NC,L]
That would result in: http://test.com/test/test.test/test.php for a request like http://test.com/test/test.test/test
I would test it more though. You might want to take a look at an .htaccess tester like this: http://htaccess.madewithlove.be/
The REQUEST_FILENAME can be swapped out for REQUEST_URI if needed in testing.
Related
I have simple php application with navigation based on domain/foo/bar nested urls.
For instance, I have main page index.php with about nav link which should navigate to domain/en/about, where en and about must be transfered to url param like index.php?url=....
But when I click to about I got to domain/en/aboutand
404 not found instead.
I have configured apache2 virtual domain config as:
<VirtualHost *:80>
ServerAdmin webmaster#localhost
<Directory /var/www/html/domain>
Options -Indexes +FollowSymLinks -MultiViews
AllowOverride All
Require all granted
</Directory>
DocumentRoot /var/www/domain/
ServerName domain.local
ServerAlias www.domain.local
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
And .htaccess file as:
order deny,allow
RewriteEngine On
RewriteBase /
RewriteRule .* index.php?url=$0 [QSA,L]
mod_rewrite for apache2 is already enabled.
Have no clue what I have missed.
Any help is appreciated!
Thank you in advance!
<Directory /var/www/html/domain>
:
DocumentRoot /var/www/domain/
Your <Directory> section and DocumentRoot directive refer to different locations, so regardless of where you've put the .htaccess file, it's not going to work as intended.
However...
RewriteRule .* index.php?url=$0 [QSA,L]
This rule is not strictly correct, since it ends up rewriting itself on a second pass by the rewrite engine. If it wasn't for the QSA flag, the original url param value (that contains the originally requested URL-path) would be lost. The above ends up rewriting a request for /en/about to index.php?url=index.php&url=en/about. Fortunately, your PHP script still reads $_GET['url'] as en/about. But you can examine the full (erroneous) query string in $_SERVER['QUERY_STRING'].
(And, if you were to simply prefix the substitution string with a slash, ie. a URL-path, you'll get an endless rewrite-loop (500 Internal Server Error). But this could also result from adding additional rules later.)
You should prevent requests to index.php itself being rewritten, which you can do by adding an additional rule. For example:
RewriteRule ^index\.php$ - [L]
RewriteRule .* index.php?url=$0 [QSA,L]
However, this will still rewrite your static assets (assuming you are linking to internal images, CSS and JS files?). So, you would normally need to prevent this with an additional condition that prevents the rule from being processed if the request already maps to a static file.
For example:
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* index.php?url=$0 [QSA,L]
The CondPattern -f checks if the TestString maps to a file. The ! prefix negates this. So the condition is only successful when the request does not map to a file.
You need parenthesis around what you want to capture. Back-references indices start with '1':
RewriteRule (.*) index.php?url=$1 [L,QSA]
I am using Apache 2 on Xubuntu to run multiple local instances of TYPO3. Since they use different TYPO3 and therefore PHP versions, I'm using fastcgi to pass requests to the one with TYPO3 version 9.5.x to the corresponding php7.2-fpm.
However, none of the pages other than "Home", the TYPO3 backend and the phpinfo are loading. I just get a raw 404 message which looks like it's coming from apache rather than from TYPO3 itself.
The only way I can get the pages to load is when I call them using the pageID and a parameter to suppress the redirect to the "more beautiful" URL. This, and the raw error page, make me believe that the problem lies within my Apache config rather than my TYPO3 setup. It seems like every call to a specific file (/index.php, /typo3/index.php, and /info.php) works, but the routing doesn't work because the apache tries to resolve it directly to a file/directory.
This is my apache config for the problematic vhost:
<VirtualHost *:80>
ServerName test.test
DocumentRoot /var/www/foo/bar/httpdocs
# <FilesMatch \.php$>
# SetHandler "proxy:unix:/var/run/php/php7.2-fpm.sock|fcgi://localhost"
# </FilesMatch>
ProxyPassMatch ^/(.*\.php(/.*)?)$ unix:/run/php/php7.2-fpm.sock|fcgi://localhost/var/www/foo/bar/httpdocs
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
The commented part was the first try, when I noticed the problems I found the "ProxyPassMatch"-Part online and tried it out, but I have the same issues.
This is the crucial part of the rewriting in the default .htaccess (that is shipped with TYPO3):
<IfModule mod_rewrite.c>
RewriteEngine On
# ...
# If the file/symlink/directory does not exist => Redirect to index.php.
# For httpd.conf, you need to prefix each '%{REQUEST_FILENAME}' with '%{DOCUMENT_ROOT}'.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^.*$ %{ENV:CWD}index.php [QSA,L]
</IfModule>
Important is that all URLs that are not file requests are passed on to index.php
First, check the obvious:
Is mod_write enabled (e.g. a2enmod rewrite)?
Is the .htaccess executed? As mentioned, in the comments, AllowOverride must be set.
For example, within the VirtualHost section, put this:
<Directory /var/www/foo/bar/httpdocs>
# When this directive is set to All, then any directive which has the .htaccess Context is allowed in .htaccess files.
AllowOverride All
</Directory>
If that does not solve the problem, you can try narrowing down the problem step by step:
For example create a file /abc.txt with text "hello" in your web root. Then, add this before the TYPO3 rewrite blocks.
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule /?xyz /abc.txt [L]
</IfModule>
Test the URLs /abc.txt, /xyz. They should both show "hello".
This way you can check if the rewrites work in general (without involving TYPO3). Once the test is successfull, remove again.
see also Troubleshooting in the Installation Guide, which also mentions the mod_rewrite.
Disclaimer: I don't know about the ProxyPassMatch but it seems to be generally working from what you described.
I have an internal domain like
live.domain.com
which I defined in sites-available like so
ServerName live.domain.com
ServerAdmin webmaster#localhost
DocumentRoot /data/www/html/mydomainnamenodots
<Directory /data/www/html/mydomainnamenodots>
Require all granted
</Directory>
and the accordingly same for SSL conf.
I do have a folder /api which is in there like
/data/www/html/mydomainnamenodots/api
What I want is to catch all calls to
live.domain.com/api/*
and redirect them to something like
live.domain.com/api/index.php?url=*
So a real example would be
live.domain.com/api/statistics/getFTE/123/456
and I'd like that to be
live.domain.com/api/index.php?url=/statistics/getFTE/123/456
That would result in a $_REQUEST in index.php like so
array(1) {["url"]=>string(33) "/statistics/getFTE/123/456"}
mod_rewrite is enabled and loaded. Simple tests with file to file redirects work.
My rewrite rule which does not work as it does not redirect is
<Directory "/data/www/html/mydomainnamenodots/api">
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^.*?mydomainnamenodots\/api(.*)$ /mydomainnamenodots/api/index.php?url=$1 [QSA,L]
</Directory>
Any ideas why that does not work?
Am I missing the RewriteBase or something?
Thanks in advance
Alex
As the subdomain already points to a subfolder, it has to be the the according subfolder below that one in the directory definition. In addition I changed the regexp as well.
Here is what worked for me:
<Directory />
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^.*\/api(\/.*)$ /api/index.php?url=\/$1 [QSA,L]
</Directory>
I'm trying to run a php project using apache configurations in LAMP but its not working*, whereas when I run it as php -S locahost:4000 its working really great.
Here is the link to the project if you need some info about the files or working of it Project
Here is my apache configuration -
<VirtualHost localhost:4000>
ServerAdmin root#localhost
ServerName localhost
ServerAlias localhost
DocumentRoot /var/www/html/dir
<Directory "/var/www/html/dir">
AllowOverride None
Options None
Require all granted
</Directory>
*not working means - when running it through apache i can only access the index page and when going to some other page of the project like localhost:4000/about It shows The requested URL /department was not found on this server. ie. Error 404.
I think that you expect "index.php" to receive all requests.
Now, Apache is trying to find "about" directory and "department" directory.
In order for Apache to run index.php on any URL, we need to use the Rewrite rule.
Although I have not verified it in detail, I guess it will work with the following rules.
RewriteEngine on
RewriteRule ^/(.*)$ /index.php
It now working after enabling a2enmod rewrite from apache and updating the contents of .htaccess file as follows
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?path=$1 [NC,L,QSA]
I started a php project based on http://www.php-mvc.net/ and i searched on Google how to set up my WAMP Server to enable URL rewriting.
I'm running the latest version of WAMP.
1) Enable mod_rewrite module on httpd.conf
2) On httpd-vhosts.conf i added a virtual host
<VirtualHost *:80>
ServerName phpmvc.test
ServerAlias *.phpmvc.test
VirtualDocumentRoot "C:\wamp\www\phpmvc"
ErrorLog "logs\errors.log"
<directory "C:\wamp\www\phpmvc">
Options Indexes FollowSymLinks
AllowOverride all
Order Deny,Allow
Deny from all
Allow from all
</directory>
3) On my hosts file i added the host 127.0.0.1 phpmvc.test
4) On .htacces file i have this lines
RewriteEngine on
RewriteRule ^(.*)\/$ index.php?url=$1 [QSA,L]
I restarted Apache after setting up the files and when i went to phpmvc.test it worked fine but when i tried phpmvc.test/test it shows an error that says that the requested URL is not found on this server.
EDIT: I tried with RewriteRule ^(.*)$ index.php?url=$1 [QSA,L] but it shows the same error
EDIT2: I tried with EDIT: I tried with Rahil Wazir suggestion but it stills not working.
I have this controller file IndexController.class.php and it works if i access with this URL: phpmvc.test?url=index but if i try phpmvc.test/index it says that index is not found on the server.
<?php
class IndexController {
public static function index() {
echo "Index controller";
}
}
Printing $_GET and $_SERVER on root i get an empty Array() and the server array. If i go to phpmvc.test/index?url=index i get the value on $_GET["url"] and on $_SERVER [QUERY_STRING] => url=index.
This is because Apache thinks /test is a file or directory which you are trying to accessing which probably don't exist.
You need to apply those two famous condition which is used by most Front controller pattern frameworks:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
Which tells Apache Rewrite Module unless the file or directory from the requested uri is exist then apply the rewrite rule, otherwise render the contents of the file or directory.
Debug by checking what you are getting in $_GET and $_SERVER variables.
print_r($_GET);
print_r($_SERVER);
Compare the differences in the values for ['url'] index.
Also, it may depend on your sub-folder depth as seen on the URL before /index.