Apache mod rewrite rule is not working - php

I already checked and the MOD REWRITE is up and running on the server.
Request url is:
http ://www.mydomain.com/user/123456
.htaccess rule:
RewriteRule ^/user/(.*)$ /user.php?user=$1 [L,QSA]
So in theory it should redirect internally to the php script user.phpwith the variable u=123456 but nothing is happening? How can I debug that?
Not Found
The requested URL /user/65464654 was not found on this server.

You need to get rid of the leading slash in your pattern. The leading slash is removed from the URI when used to match against rules in an htaccess file. So you want:
Options -Multiviews
RewriteEngine on
RewriteRule ^user/(.*)$ /user.php?user=$1 [L,QSA]
The -Multiviews option may not be needed, it's to ensure mod_negotiation doen't take over and automatically map the request to user.php before your rewrite rule can get applied.

if .htaccess is in /user then RewriteRule ^\d+$ user.php?user=$0 [L,QSA]
from #Deadooshka works.

Related

RewriteRule in htaccess fails, but it could be my host

I read that Self Sabotage is Not asking for help so here I am.
So, I have a site...it's working great using WAMP. It's working great on my current host. But I need to switch to a new host and now it's failing. I figured it's a .htaccess issue but now I'm not sure. On my current host I have no .htaccess file and it works great. On my localhost server using WAMP I had the same thing as on my new host but I just disabled the .htaccess file, renaming it to BAD.htaccess, and the site still works great. This is why I think it's a server-side problem and I need some help. On my WAMP server in vhosts I disabled +FollowSymLinks for that "domain". On my current host I had no easy way to do that so it's just whatever they gave me, but it works.
I am currently with Ionos and have switched to GreenGeeks, who use cPanel. So far I haven't found a vhosts file to edit to remove +FollowSymLinks, if that is even the problem.
Maybe it can be accomplished with .htaccess and if so here is what I need to do. First my current .htaccess:
Options +FollowSymLinks
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^poems$ poems.php [R]
#RewriteRule ^poems/$ poems.php
RewriteRule ^collections$ collections/ [R]
RewriteRule ^collections/$ collections.php
RewriteRule ^poem$ poem/ [R]
RewriteRule ^poem/$ poem.php
RewriteRule ^poem/([0-9]+)/([a-zA-Z])$ poem.php?num=$1&poem=$2 [NC,L]
RewriteRule ^collection$ collection/ [R]
RewriteRule ^collection/$ collection.php
# RewriteRule ^poem/([0=9]+)$ indpoem.php?num=$1 [NC,L]
With the first two setups I can go to example.com/poems and it will redirect or rewrite to example.com/poems.php but still look like example.com/poems. Same with collections. On the new host those rewrite rules do rewrite it but the URL or URI shows example.com/poems.php, which I don't want per current SEO standards. Still, I could live with that.
However, when I get to the next level... example.com/poem/#/poem-name it fails on my new host. I do have a file called poem.php which it should rewrite to. In that file I use the following to get the # and name...
$URL = explode("/",$_SERVER['REQUEST_URI']);
So I don't have to do a _GET.
As you can see I tried to do a RewriteRule to change it from the first to example.com/poem?111&name, but that just seems silly because on WAMP I don't have to do anything. I could try rewriting it to the same URL again, but I have a feeling that won't work. And if it does it will probably be poem.php/#/name/
Any thoughts on a server config I'm missing when using cPanel. I even tried doing
Options -FollowSymLinks
in my .htaccess file with no success.
Any help would be appreciated. My WAMP and the new host have all the most recent versions of Apache and PHP.
There are a few issues here...
For the site to work without the .htaccess file at all (on your WAMP dev server and current host) then MultiViews (part of mod_negotiation) must have been enabled. It is MultiViews that "rewrites" /foo to /foo.php.
If MultiViews is enabled then your current .htaccess file is essentially overridden since the MultiViews content-negotiation occurs before your mod_rewrite directives are processed so your RewriteRule patterns fail to match.
MultiViews is disabled by default on Apache, it needs to be "explicitly" enabled. Unfortunately, some shared hosts do enable this in the server config (which causes more problems than it fixes - if you are not expecting it.)
On the new host those rewrite rules do rewrite it but the URL or URI shows example.com/poems.php.
RewriteRule ^poems$ poems.php [R]
Because MultiViews is disabled and your directives externally "redirect" /poems to /poems.php. There is no "rewrite" here. The R (redirect) flag triggers an external redirect.
RewriteRule ^poem$ poem/ [R]
RewriteRule ^poem/$ poem.php
However, for /poem you are redirecting to /poem/ (appending the trailing slash) but you have omitted the L flag so processing continues and the request is further rewritten to /poem.php. But because you have already triggered a Redirect, the request is "redirected" (not rewritten) to /poem.php, again exposing the .php.
Redirects should nearly always include the L flag. In fact, all your rules should include the L flag for optimisation and to prevent accidental conflicts.
Why are you redirecting to append the trailing slash (as if this is the preferred canonical URL)? You make no mention of this in your question text and only one of your examples includes a trailing slash on the URL as far as I can see? So, what is the preferred/canonical URL? What URL are you linking to? Incidentally, MultiViews will not append a trailing slash - so either this redirect is not required, or your site is not actually "working great" on WAMP / current host without the .htaccess file. (?) (Personally, I would not use a trailing slash.)
RewriteRule ^poem/([0-9]+)/([a-zA-Z])$ poem.php?num=$1&poem=$2 [NC,L]
:
$URL = explode("/",$_SERVER['REQUEST_URI']);
Your PHP script parses the requested URL-path (ie. $_SERVER['REQUEST_URI']), it is not referencing the query string. However, the above RewriteRule directive is rewriting to a query string - which would seem to be entirely superfluous ("silly" - as you suggest). Because you are not using the query string in your PHP script, the request still "works" when using MultiViews.
According to your PHP script, you simply need to rewrite the request to poem.php, without a query string. (Which is what MultiViews does. Although, strictly speaking, MultiViews rewrites /poem/123/name to /poem.php/123/name - passing the additional URL-path as path-info to poem.php.)
This regex only matches a single letter in the 3rd (name) path segment so it will fail to match a requested URL of the form /poem/123/name, so the request is not rewritten to poem.php and the request fails (with a 404 I suspect).
This regex also does not match a trailing slash. (So, is the trailing slash really canonical?)
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
These conditions are entirely superfluous where you have put them. RewriteCond directives only apply to the first RewriteRule directive that follows.
Options -FollowSymLinks
You need FollowSymLinks for mod_rewrite to work. Don't try to disable this. FollowSymLinks is actually the default Apache setting, so you only need to explicitly enable it (ie. +FollowSymLinks) in .htaccess if it has been disabled in the server config.
Solution
Personally, I would not use a trailing slash on the canonical URLs. (This is in line with most of your examples and the regex used in your rule.)
So, bringing the above points together:
Options +FollowSymLinks -MultiViews
RewriteEngine on
# Canonical redirect to remove trailing slash (from non-directories)
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*)/$ /$1 [R,L]
# Internal rewrites to ".php"
RewriteRule ^poems$ poems.php [L]
RewriteRule ^collections$ collections.php [L]
RewriteRule ^poem(/\d+/[\w-]+)?$ poem.php [L]
RewriteRule ^collection$ collection.php [L]
On the other hand, if the canonical URL should include a trailing slash then change it accordingly:
Options +FollowSymLinks -MultiViews
RewriteEngine on
# Canonical redirect to append trailing slash to "all" URLs
RewriteRule !/$ ${REQUEST_URI}/ [R,L]
# Internal rewrites to ".php"
RewriteRule ^poems/$ poems.php [L]
RewriteRule ^collections/$ collections.php [L]
RewriteRule ^poem/(\d+/[\w-]+/)?$ poem.php [L]
RewriteRule ^collection/$ collection.php [L]
If you have many such URLs/pages then you can make this entirely "generic" without having to explicitly name each URL/file. ie. "poems", "collections", etc.
Alternatively, you simply enable MultiViews and let mod_negotiation rewrite the URLs. However, you will not be able to canonicalise the trailing slash or validate the request before rewriting and MultiViews applies to everything, not just your .php files, so potentially creates duplicate content. If you need to do any specific rewriting, such are rewriting the query string then MultiViews is likely to conflict.
Options +MultiViews

.htaccess Multiple Rewrite Rules with Extensions

So, I'm not very good with Apache config or .htaccess rewrite rules.... And I'm trying to do some modifications to how my localhost server works...
What I'm trying to do is return a 404 error on any request with the extension '.php'. If the uri does not have an extension, then route the request to 'ini.php'. If the uri contains an extension that isn't of '.php', then it should just follow normal procedures in fetching the file.
What I have now:
Rewrite Engine on
DirectorySlash off
RewriteCond $1 (.php)
RewriteRule ^(.*)$ - [L,NC,R=404]
RewriteCond $1 !^(.+)
RewriteRule ^(.*)$ ini.php [L,NC]
My logic is that if it's not a .php, and it doesn't have an extension, then route it to ini.php. Otherwise it should route normally.
Right now it looks like the .php rule is working in returning 404 errors.. However, if a request for a path without an extension is received, it tries to route to ini.php and hits a 404 page. Is it maybe processing like the second rule and then hitting the first rule?
Anyways, can someone help me sort it out and give me some guidance on it? I tried google and a bunch of different solutions, but I couldn't find something that worked for this situation...
UPDATE:
I changed the code to the following and added ini.php to the DirectoryIndex settings in httpd:
RewriteEngine on
RewriteCond %{REQUEST_URI} (\.[php^\\/]+)$
RewriteRule ^(.*)$ - [L,NC,R=404]
RewriteCond %{REQUEST_URI} !(\.[^\\/]+)$
RewriteRule ^.+$ / [L,NC]
Can you check if it looks alright?
I've turned on DirectorySlash again. Thanks.
This will do it:
RewrieEngine on
# 404 any URL ending .php (ignoring any query string)
RewriteRule ^(.+)\.php$ - [R=404,L,NC]
# Rewrite any URL that does not contain a dot (.), and therefore has no extension, to ini.php
RewriteRule ^([^.]*)$ ini.php [END]
I am assuming it will go in a .htaccess file from what you said. It would need changing to go in the main config.
Don't turn DirectorySlash off. It's a security risk to do so (see the link) and it only applies to existing directories anyway so is not causing any problems for you. There is no space in RewriteEngine.

URL rewrite rule is not working in php

i am using godaddy hosting and addon domain. i want to make my long url to short url.
for example my url is follwing:
www.example.com/events/landing_event.php?url=text-first
and i want following url:
www.example.com/events/text-first
for this i am using following rewrite url in .htaccess file
RewriteRule ^([a-zA-Z0-9-/]+)$ events/landing_event.php?url=$1 [L]
RewriteRule ^([a-zA-Z0-9-/]+)/$ events/landing_event.php?url=$1 [L]
but this rewrite rule is not working.
so please help how can i make short url.
Use this source after you make sure RewriteEngine Enabled and On
RewriteEngine On
RewriteRule ^events/([^/]*)$ /events/landing_event.php?url=$1 [L]
The original URL:
http://www.example.com/events/landing_event.php?url=text-first
The rewritten URL:
http://www.example.com/events/text-first
Updated with 500 Internal Server Error
Your code is guaranteed to generate 500 internal server error because it is causing infinite looping. Reason is that your matching URI pattern is: ^events/([^/]*)$
Which matches your URLs before and after rewrites. And once it reaches max allowed internal rewrite limit Apache throws 500 internal server error and bails out.
Change your code to this
Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^events/([^/]*)$ /events/landing_event.php?url=$1 [L,QSA,NC]
Try this code :
RewriteEngine On
RewriteRule ^([^/]*)\.html$ /events/landing_event.php?url=$1 [L]
Add this in your .htaccess file
You can see there are many ways to achieve that goal.
Also
RewriteEngine On
RewriteRule ^events/([^/]*)\.html$ /events/landing_event.php?url=$1 [L]
would do the job. So basicly, how does the full scope of your project urls look like?
Like do you always want to print the parameters? If yes, also the name sometimes or also the value?
The newer versions of apache requires you to change AllowOverride on /etc/apache2/apache2.conf
from
AllowOverride None
to
AllowOverride All

htaccess redirect from asp to php with parameters

I have to redirect all my asp page to new website developed in PHP.
I had my asp page as,
abc.asp?id=82
Which need to be redirected to
siteurl/index.php/abc
Can any one help me with this in HTAccess?
I have tried with,
Redirect 301 /abc.asp?id=82 siteurl/index.php/abc
rewriterule ^/abc.asp?id=82$ siteurl/index.php/abc[R=301,L]
But this is not working and giving me a 404 error.
You can't match against the query string in either a Redirect or RewriteRule. It's not very clear what the scope you're trying to accomplish here. Is the id=82 important? Does abc mean "anything that's just letters"? Is siteurl a directory or a domain name? If it's strictly what you've attempted, then this is strictly how it'll work:
RewriteEngine On
RewriteCond %{QUERY_STRING} ^id=82($|&)
RewriteRule ^/?abc.asp$ siteurl/index.php/abc? [L,R=301]
You're making 2 main mistakes:
Rewrite rule matches only URI part and doesn't match query string
Rewrite rule in .htaccess doesn't match leading slash.
Enable mod_rewrite and .htaccess through httpd.conf and then put this code in your .htaccess under DOCUMENT_ROOT directory:
Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /
RewriteCond %{QUERY_STRING} ^id=82(&|$) [NC]
RewriteRule ^(abc)\.asp$ http://domain.com/index.php/$1 [R=302,L,NC]
Once you verify it to be working replace 302 (Temporary Redirect) with 301 (Permanent Redirect)
Just use
RewriteRule ^abc.asp$ siteurl/index.php/abc [R=301,QSA,L]
That should do the job.. Using the QSA flag will forward any GET paramater too, if that's what you meant with the title.

Mod_rewrite rule not passing PHP variables

I am trying to rewrite the URL (using mod_rewrite) as requested by the user:
http://example.com/question/1/
To load this URL from the server:
http://www.example.com/question.php?qid=1
I am currently using the rewrite rule:
RewriteEngine On
RewriteRule ^question/([^/\.]+)/?$ question.php?qid=$1 [L]
But this does not work. I have tried other things in the .htaccess (such as redirects) and this work, so I know that the .htaccess is being processed.
Thank you.
According to your example, your rewrite rule should be something like:
RewriteRule ^question/(\d+)/?$ /question.php?qid=$1 [L]

Categories