why a rewrite_rule works only when the folder exist? - php

The objective is to input an url like
https://www.mywebsite/expert/188/name-of-the-expert
and return it to the server in the form
expert.php?exp=188
Like if the user typed in https://www.mywebsite/expert.php?exp=188
WHAT DOES NOT WORK:
simple rules like RewriteRule ^expert-([0-9]*)$ expert.php?exp=$1 [L,NC,QSA]
WHAT WORK
I have the following rewrite_rule that works only when I physically create the folder expert/ in my tree, i.e. /www/expert/
# FRIENDLY URL FOR EXPERTS PROFILE
Rewriterule ^(.*)expert\/([0-9]*)(\/[a-z0-9\-\']*)?\/?$ expert.php?exp=$2 [L,NC,QSA]
Also, for this rule to work, I had to put the <base href="/"> in the page expert.php to avoid errors with all my linked resources:
Failed to load resource: the server responded with a status of 404 ()
The server is APACHE on a shared web hosting platform named OVH.
The full code of the issue:
<IfModule mod_rewrite.c>
RewriteEngine On
Options +FollowSymlinks
RewriteBase /
# FRIENDLY URL FOR EXPERTS PROFILE
Rewriterule ^(.*)expert\/([0-9]*)(\/[a-z0-9\-\']*)?\/?$ expert.php?exp=$2 [L,NC,QSA]
</IfModule>

Have it like this with MultiViews turned off:
Options +FollowSymlinks -MultiViews
RewriteEngine On
RewriteBase /
# FRIENDLY URL FOR EXPERTS PROFILE
Rewriterule ^/?expert/(\d+)/?$ expert.php?exp=$1 [L,NC,QSA]
Option MultiViews (see http://httpd.apache.org/docs/2.4/content-negotiation.html) is used by Apache's content negotiation module that runs before mod_rewrite and makes Apache server match extensions of files. So if /file is the URL then Apache will serve /file.html.

I changed from using rewrite rules to using Apaches FallbackResource after reading https://www.adayinthelifeof.nl/2012/01/21/apaches-fallbackresource-your-new-htaccess-command/. It's more of a 'if page not found, then run this page instead'
<Directory /var/www/>
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
FallbackResource /root.php
</Directory>
The only thing I have found is that if the URL is for page that does exist - then it serves that instead of your base new base page 'root.php' in my case.

Related

mod_rewrite redirects don’t work as expected

I have two problems actually:
First, I’m trying to redirect several short URLs to a single page with more actions, like this:
RewriteEngine On
RewriteRule ^/login?$ ^login.php?action=login&next=$1 [L]
RewriteRule ^/reset?$ ^login.php?action=reset&next=$1 [L]
This is being written in the .conf file inside <Directory>. The problem is that the first rule gets executed, while the second doesn’t and I can’t figure why.
I also tried writing them like this:
RewriteCond %{REQUEST_URI} /login$
RewriteRule ^login.php?action=login&next=$1 [L]
RewriteCond %{REQUEST_URI} /reset$
RewriteRule ^login.php?action=reset&next=$1 [L]
I should probably mention that login.php does not reside in the root directory, but in different subdirectories.
What am I doing wrong and how can I fix it?
The second issue I have is that if I put an .htaccess file inside the root directory, the rules in the .conf file don’t get executed anymore.
Inside the .conf file I have these rules:
<Directory>
Options Indexes FollowSymLinks ExecCGI Includes MultiViews
AllowOverride All
Order allow,deny
Allow from all
RewriteEngine On
</Directory>
Why is this and how can I fix it?
Just to extend on from my comments above. Place these rules in your site root .htaccess or in httpd.conf file:
Options -MultiViews
RewriteEngine On
RewriteRule ^/?login(?:/(.*))?$ subdir1/login.php?action=login&next=$1 [L,NC,QSA]
RewriteRule ^/?reset(?:/(.*))?$ subdir1/login.php?action=reset&next=$1 [L,NC,QSA]
Option MultiViews (see http://httpd.apache.org/docs/2.4/content-negotiation.html) is used by Apache's content negotiation module that runs before mod_rewrite and makes Apache server match extensions of files. So if /file is the URL then Apache will serve /file.html.

URL Rewriting and GET values

I know there are lots of answer about this, but I can't understand why it does not work for me.
I want every URL like :
http://mywebsite.com/campagne/blabla
to be redirected to
http://mywebsite.com/campagne.php?c=blabla
Here is my .htaccess file:
Options +FollowSymlinks
RewriteEngine On
RewriteBase /
RewriteRule campagne/(.+)$ campagne.php?c=$1 [QSA,L] [L]
The URL is redirected to campagne.php but $_GET['c'] is not sent.
Can you help me? I cannot find what is wrong? It works on my local server but not online.
This is due to enabling of MultiViews option in your Apache. Place this line on top of your .htaccess to turn it off:
Options -MultiViews
Option MultiViews is used by Apache's content negotiation module that runs before mod_rewrite and makes Apache server match extensions of files. So /file can be in URL but it will serve /file.php.

How to make an alias in .htaccess to change a local URL

I'm pretty sure this is a duplicate but I just don't know how to find the answer to this simple problem.
So I have a local page like this:
http://example.com/mypage.php
And all I want to do is to have anyone who tries to access http://example.com/subfolder/mypage.php to actually load the page at the above location.
I don't want a redirect. http://example.com/subfolder/mypage.php does not exist as an actual path on my server, but I want to make it available via rule in .htaccess
Try this:
RewriteEngine on
RewriteRule ^subfolder/(.*) /$1
This rule rewrites every request that starts with /subfolder/ to /. Or if you need only for a specific URL-path:
RewriteEngine on
RewriteRule ^subfolder/mypage.php /mypage.php
You can add it in .htaccess
RewriteEngine On
RewriteRule ^([^/]+)/(.*) /$2
or use directly in httpd.conf like
<Directory /var/www/>
Options Indexes FollowSymLinks ExecCGI
AllowOverride None
Order deny,allow
Allow from all
RewriteEngine On
RewriteRule ^([^/]+)/(.*) /$2
</Directory>
use $1 to get subfolder and $2 to get mypage.php :)

RewriteRule working on http but breaks on https

I have some RewriteRule in htaccess to have some pretty urls for my landing page. The url can look like www.site.com/new-document and my RewriteRule will make that www.site.com/index.php?page=new-document
This way I can leave the pretty url and use index.php to change the text depending on the page variable.
Everything works perfectly well on http but once I add https to the url I get a Not Found error as in the RewriteRule is not triggering.
Here is a copy of my htaccess code
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^new-document$ index.php?page=new-document
RewriteRule ^old-document$ index.php?page=old-document
</IfModule>
Grasshopper and anubhava pointed me in the right direction!
My problem was that the https virtual host did not have the AllowOverride All directive.
<Directory /var/www/>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all
</Directory>
Can you get to the HTTPS URL without the RewriteRule? It sounds like Apache may be using a different virtual host or not accepting HTTPS at all.

Apache mod_rewrite REST URL

Please help me with this one, which should be easy but I've never managed to properly learn Apache mod_rewrite's syntax...
I have a REST webservice implemented in PHP and I need to rewrite the following URL:
[1] http://www.myserver.com/service/ca;x={valx},y={valy},z={valz}
into
[2] http://www.myserver.com/service/ca.php?x={valx}&y={valy}&z={valz}
How to accomplish this?
I'm using Apache2 on Ubuntu, this is the configuration:
Alias "/service" "/opt/htdocs/service"
<Directory "/opt/htdocs/service">
AllowOverride All
Options -Indexes FollowSymLinks
</Directory>
and the content of my /opt/htdocs/service directory:
$>ls -1 /opt/htdocs/service
ca.php
Mod_rewrite is enabled:
$>a2enmod rewrite
Module rewrite already enabled
Thanks in advance!
Try putting this in your server/vhost config or the htaccess file in your document root:
RewriteEngine On
RewriteRule ^/?service/ca;(.*)$ /service/ca.php?$1 [L]
RewriteCond %{QUERY_STRING} ^(.*),(.*)$
RewriteRule ^/?serivce/ca\.php$ /service/ca.php?%1&%2 [L]

Categories