.htaccess ReWrites cancelling each other out ... Any Ideas? - php

I have a couple of rules in my .htaccess file in order to make the URLs a bit cleaner, however, they seem to be cancelling each other out.
The first rule is just to remove the .php from page names,
example : mysite.com/join rather than mysite.com/join.php
RewriteEngine On
Rewrite Condition : %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
The second rule is to make it easier for Users to share their profiles on my site,
example : mysite.com/user1 rather than the actual URL mysite.com/profile.php?user=user1
RewriteRule ^([_A-Z0-9a-z-+]+)$ profile.php?user=$1 [S=1]
I've been playing round with them, and they essentially cancel each other out - Any ideas on how I can get them both working?
Thanks

The problem you have is that both conditions are almost identical i.e. anything that ^([_A-Z0-9a-z-+]+)$ matches will also be matched by ^([^.]+)$, so someone accessing mysite.com/user1 will get redirected to mysite.com/user1.php since that is the first rule that is encountered, and it has the L flag to prevent processing more rules. To prevent this happening you need to make the rules different, e.g. perhaps require user pages to be mysite.com/users/user1? Then you could write the rules as
RewriteRule ^([^./]+)$ $1.php [NC,L]
RewriteRule ^users/([_A-Z0-9a-z-+]+)$ profile.php?user=$1 [S=1]
Note that you need to add / to the characters not to be matched in the first rule, otherwise it will still match mysite.com/users/user1.
Edit
A couple of other alternatives:
If you were willing to have actions (e.g. join) use URLs such as mysite.com/action/join then you could keep users at the top level e.g.
RewriteRule ^action/([^.]+)$ $1.php [NC,L]
RewriteRule ^([_A-Z0-9a-z-+]+)$ profile.php?user=$1 [S=1]
Or if you know the names of all your actions you could put them in an alternation (this would require that you couldn't have a user called e.g. join):
RewriteRule ^(join|login|logout|delete)$ $1.php [NC,L]
RewriteRule ^([_A-Z0-9a-z-+]+)$ profile.php?user=$1 [S=1]

Related

Using .htaccess to clean GET URL

Before anyone comments, I know there are a lot of posts created on this topic, but none of them seem to solve my problem, that is why I have started this thread.
So, I have a page in my website called project.php which is used in GET query like so: project.php?id=12 I want to have a .htaccess file that converts the given URL into localhost/MyWeb/project/id/12/. I've literally followed every single post regarding that topic but none of them seem to work.
Also, along with that, I want all my .php and .html files to be shown just with their names, i.e localhost/MyWeb/index.php/ becomes localhost/MyWeb/index/ and localhost/MyWeb/sub1/sub2.php becomes localhost/MyWeb/sub1/sub2/.
EDIT:
The reason why I did not add my work in first place was because I didn't think it would be any helpful. But here it is:
RewriteEngine On
RewriteRule ^([0-9]+)$ project.php?id=$1
RewriteRule ^([0-9]+)/$ project.php?page=$1
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
RewriteRule ^([^\.]+)$ $1.html [NC,L]
Firstly, you are operating out of a sub-directory (MyWeb), which means you need to set a RewriteBase. Also, you need to ensure that your .htaccess file is placed inside that sub-directory, and not in the localhost document root.
So, below RewriteEngine on, insert the folloeing line:
RewriteBase /MyWeb/
Next, you stated that you want to convert project.php?id={id} to project/id/{id}, but your code omits the /id/ segment. I also noticed that you have two rules, and that the second one contradicts your question, so I am only going to show you the change you need to make for the first rule, until such time as you clarify what the second rule is for.
To make the project URI work, change the very first rule to:
RewriteRule ^project/id/([0-9]+)/?$ project.php?id=$1 [QSA,L]
This will match the URI you want, with an optional trailing slash. I've also added the QSA flag which appends any extra query string parameters to the rewitten URI, as well as the L flag which stops processing if the rule is matched.
Next, to omit the .php or .html from your URIs, change the last three lines to the following:
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^([^\.]+)$ $1.php [L]
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^([^\.]+)$ $1.html [L]
When you make a request to localhost/MyWeb/index, Apache will check to see if localhost/MyWeb/index.php or localhost/MyWeb/index.html exist, and will then serve whichever one it finds first.
If you have both the PHP and HTML files, then the PHP one will be served, and not the HTML one. If you prefer to serve HTML files, then swap the two blocks around.
Unfortunately, I don't know of a good way to force a trailing slash for these, specifically because of the condition that checks for their existence. In other words, it won't work if you request sub2/, with the trailins slash because it would need to check if sub2/.php exists, which it does not.
Update: For added benefit, place these two blocks just below the new RewriteBase you set earlier to redirect the old URIs to the new ones whilst allowing the rewrites to the new URIs to still work:
RewriteCond %{THE_REQUEST} \/project\.php\?id=([0-9]+) [NC]
RewriteRule ^ project/id/%1/ [R=302,L,QSD]
RewriteCond %{THE_REQUEST} \/MyWeb/(.+)\.(php|html)
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ %1 [R=302,L]
For reference, here's the complete file: http://hastebin.com/gacapesoqe.rb

mod rewrite -new.php to /new

I want to rewrite any page url which contains -new.php to the /new
For example:
example.com/page-new.php
to
example.com/page/new
I am able to remove the ending .php with following rule, but I can't figure out how to match the -new.
RewriteRule ^([^\.]+)$ $1.php [NC,L]
Your rule actually adds .php to the end.
RewriteRule ^(.*)-new\.php$ $1/new [NC,L]
removes -new.php and changes it to /new
EDIT:
After a while of thinking, if you want users to get redirected, use above and add "R=301" to the brackets as third parameter.
OR, if you actually have links in /page/new schema and files in -new.php schema, then you actually wants to remowe /new and add -new.php. If so, then you asked wrong question. Here you go:
EDIT 2:
You also want to redirect /page to page.php. Now you can do this in two ways:
RewriteRule ^(.*)/new$ $1-new.php [NC,L]
RewriteRule ^(.*)$ $1.php [NC,L]
OR
RewriteRule ^(.*)/new$ $1-new [NC]
RewriteRule ^(.*)$ $1.php [NC,L]
First one are two separate rules, first for /new URLs and then for any other.
Second code is like "first change /new to -new, and then apply next rule"
If you want rule to apply only to urls without dots or anything, then replace (.*) with any other rule like for example ([^\.]*)

How to redirect two url to the same file with .htaccess?

Here's my problem, I have a bilingual website nd I don't know how to manage the urls.
I would like
mydomain.tld/contact-us and mydomain.tld/nous-contacter to show contact-us.php
mydomain.tld/pricing and mydomain.tld/prix to show pricing.php
mydomain.tld/pricing/item1 and mydomain.tld/prix/item1 to show pricing.php?what=item1 (for this one I'm not sure how to handle that, any hint is appreciate).
I can do the case one and two with ease with:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/\.]+)/?$ $1.php [R] # R for debug, make sure it shows the right page
But I don't want to have 10 entries for 5 pages, and this is not a secure way.
It would be great if (maybe) I can do something like: (contact-us|nous-contacter) as a condition. Still not sure if this is possible and if it is, if its the easiest and most secure way to do it.
How can I do this?
RewriteBase /
RewriteRule ^(contact-us|nous-contacter)$ contact-us.php [R]
RewriteRule ^(pricing|prix)$ pricing.php [R]
RewriteRule ^(pricing|prix)/(.*)$ pricing.php?what=$2 [R]

RewriteRule conflict with folders

In my page I have a login folder. When I enter into domain.com/login/ it takes me correctly to the folder. When I write domain.com/login it also opens the page but the url changes into domain.com/login/?cname=login
My other main link is like domain.com/company and works correctly. However if i write domain.com/company/ it sais object not found.
How can I fix these?
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/$
RewriteCond %{REQUEST_URI} !^/domain.com/index.(php|html?)
# domain.com/login
RewriteRule ^/login?$ /domain.com/login/index.php
# domain.com/abc
RewriteRule ^([a-z0-9]+)?$ /domain.com/profile/company-profile.php?cname=$1 [NC,L]
It sound like you want to have domain.com/login/ or domain.com/login take you to the login folder.
The rule below will ensure that all of your folders end with a trailing slash and thus make domain.com/login work.
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ http://domain.com/$1/ [L,R=301]
The next rule below will allow domain.com/company/ to work. In combination with the rule above, it will also ensure that domain.com/company continues to work.
RewriteRule ^company/$ profile/company-profile.php?cname=company [NC,L]
You should delete your other rules as they are incorrect.
Edit
Based on your last response modify the last rule to be
RewriteCond %{REQUEST_URI} !=/login/ [NC]
RewriteRule ^([a-z0-9]+)/$ profile/company-profile.php?cname=$1 [NC,L]
i.e. for all URI's except login do the rewrite company rule.
Make sure that you understand that any # of RewriteCond's only apply to the very next RewriteRule. I don't understand why you're matching against REQUEST_URI with a RewriteCond, rather than just matching it as part of the RewriteRule.
I also don't understand exactly what you're trying to accomplish with the ^/login?$ RewriteRule. I'm guessing the '?' needs to be escaped - otherwise, you're literally asking it to match against "/login" or "/logi".
Due to complications from the above concerns, I'm guessing your "domain.com/login" request is being handled by the 2nd RewriteRule which contains the "cname=", though I'm confused why you then don't see the "company-profile.php" as well (assuming maybe just an oversight in your question)?
After considering the above and trying to simplify this a little, I'm guessing everything should fall into place. If not, please comment back, and we'll see what we can do.

Mod rewrite user URL

I'm lost here. I'm using this script to give users the opportunity to enter their username lijke this:domain/username
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/?$ userpage.php?user=$1 [NC,L]
</IfModule>
This works fine. However, every user has pages I must link to: Video, Music, Images etc...
So I need something like:
domain/username/video
In php code it must be something like:
user.php?user=test&page=video
And one other question: What is the preferable way to link in this situation?
userpage.php?user=test&page=video
or
/test/video
And finally: Is it possible to deny the possibility to enter the url:
domain/userpage.php?user=test&page=video? Instead just always show: domain/test/video
Thanks in advance
I'm not 100% sure what you're asking? Do you need to change the rewrite rule to match the URL site.com/moonwalker/videos? You could try this:
RewriteRule ^([^/]+)/(images|videos|music)/?$ userpage.php?user=$1&page=$2 [NC,L]
Update
Just a quick note on the domain/member/videos URL structure. That could end up causing you problems in the future. For instance what if you decide to have a single page that shows all member videos? You'd probably want to URL to look something like site.com/members/videos. That's a problem, because the rewrite rule will also match that, but "members" isn't a member username.
I would probably structure my member page URLs like site.com/user/moonwalker/videos so it doesn't clash with future rewrite rules. You would change the above rewrite rule to this:
RewriteRule ^user/([^/]+)/(images|videos|music)/?$ userpage.php?user=$1&page=$2 [NC,L]
Then later on you can add a rewrite rule like:
RewriteRule ^members/(images|videos|music)/?$ allusers.php?page=$1 [NC,L]
To show all member videos.
Yes, it is possible by looking at the request line:
RewriteCond %{THE_REQUEST} ^[A-Z]+\ /userpage\.php[?\ ]
RewriteRule ^userpage\.php$ - [F]
This is necessary as the URL path could already be rewritten by another rule and thus using just RewriteRule would match those already rewritten requests too.

Categories