Conflicting mod_rewrite rules - php

This is the full set of rewrite code in my htaccess file, but I'm only having problems with a conflict in the last 3 rules. The final rule writes the URL I want, but returns travel.php instead of travel2.php
RewriteEngine On
Options +FollowSymLinks
RewriteCond %{http_host} ^www.example.com [NC]
RewriteRule ^(.*)$ https://example.com/$1 [R=301,L]
RewriteRule ^(.+[^/])/$ http://%{HTTP_HOST}/$1 [R=301,L]
RewriteRule ^journal/([^/]*)$ /journal2.php?url=$1 [L]
RewriteRule ^travel/([a-zA-Z0-9-]+)/([a-zA-Z0-9-]+)$ travel.php?country=$1&url_string=$2
RewriteRule ^travel/([a-zA-Z0-9-]*)$ /travel2.php?cat=$1
RewriteRule ^travel/([a-zA-Z0-9-]+)/([a-zA-Z0-9-]+)$ travel2.php?cat=$1&subcat=$2
This is what I'm after from those last 3:
/travel/country/title-url-string (currently works & displays correct content)
/travel/category (currently works & displays correct content)
/travel/category/subcat (currently displays URL as I want it, but returns travel.php content instead of travel2.php)
I originally had an ID number in the travel.php rule, and removing that has resulted in the conflict. I'm aware two of the rules have the same pattern, so how can I best go about getting the results I want? Thanks for any help. :)

From last 3 rewrite rules:
1 & 3 check the same pattern where first one always take effect.
Further, as your category and country values cannot be distinguished each other here, I would suggest to append a unique identifier to the url as below:
RewriteRule ^travel/country-([a-zA-Z0-9-]+)/([a-zA-Z0-9-]+)$ travel.php?country=$1&url_string=$2
RewriteRule ^travel/category-([a-zA-Z0-9-]+)/([a-zA-Z0-9-]+)$ travel2.php?cat=$1&subcat=$2
So your matching urls would be:
/travel/country-countryname/title-url-string
/travel/category-categoryname/subcat

Related

.HTACCESS adding to slugs

So, I'm currently building a REST API in PHP.
I managed to get slugs working for the most part.
If I request /api/admin/v1/users/1, it will return the user I need.
However, I also need to be able to add to it, e.g. /api/admin/v1/users/1/keys.
The HTACCESS file managing the slug is in the folder itself (/users/).
RewriteEngine On
RewriteRule ^(.*)$ user.php?slug=$1 [L]
I tried adding another line, but I think I messed up (I'm not that advanced with HTACCESS)
RewriteRule ^(.*)/keys$ keys.php?slug=$1 [L]
This didn't do anything, it still returns the user object.
RewriteRule ^(.*)$ user.php?slug=$1 [L]
RewriteRule ^(.*)/keys$ keys.php?slug=$1 [L]
The first rule matches everything, so the second rule is never processed. But since the first rule matches everything it will also rewrite itself (to user.php?slug=user.php) on the second pass by the rewrite engine.
You can resolve these issues by making the regex more restrictive. From your example URL it looks like the slug is numeric - in which case you can restrict the regex to match digits (0-9) only.
For example:
RewriteRule ^(\d*)$ user.php?slug=$1 [L]
RewriteRule ^(\d+)/keys$ keys.php?slug=$1 [L]
Note that the first rule also matches an empty URL-path, ie. no slug at all (as does your original rule). The second rule does not permit an empty slug (it would never match anyway).
The second rule don't work because the L flag stay for: last - stop processing rules
So you need to edit to:
RewriteEngine On
RewriteRule ^(.*)$ user.php?slug=$1 [QSA, L]
RewriteRule ^(.*)/keys$ keys.php?slug=$1 [QSA, L]

$_GET & .htaccess | PHP ignorer values

I got this problem, where I try to make an Image Archive. Most of it works, but I have now come to prettifying URLs. I have worked with this before, but somehow, it don't work now. If I add more then one Rewrite URL to the same file (index), it ignores the values added with it.
What I got:
Header add "disablevcache" "true"
RewriteEngine On
RewriteBase /folder/
RewriteCond %{HTTPS} !on
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
RewriteRule ^archive/([^/]+)?$ archive/index.php?cat=$1 [E=ORIG_URI:/$1]
RewriteRule ^archive/([^/]+)/([^/]+)?$ archive/index.php?cat=$1&sub=$2 [E=ORIG_URI:/$1]
RewriteRule ^archive/([^/]+)/([^/]+)/([^/]+)?$ archive/index.php?cat=$1&sub=$2&id=$3 [E=ORIG_URI:/$1]
RewriteRule ^archive/([^/]+)/([^/]+)/([^/]+)?/([^/]+)$ archive/index.php?cat=$1&sub=$2&id=$3 [E=ORIG_URI:/$1]
The following should allow me to access these URLs:
domain.com/archive/category
domain.com/archive/category/subcategory/
domain.com/archive/category/subcategory/id
domain.com/archive/category/subcategory/id/item
domain.com/archive will be made default, since I use an index.php file, in a folder. And item will just be for SEO and has nothing to do with PHP. (The last rewriteRule)
This works. I can access the same page, from all the different URLs. (archive/index.php). But when I try to use PHP to get the value from the provided URLs, it won't work. I can't even check and see if there are values.
No matter what I do, it just echo out Category & Sub Category on every URL. Also if I go to the default URL, domain.com/archive.
if($_GET['cat']){
echo 'Category';
if($_GET['sub']){
echo 'Sub Category';
}
}
Anyone who can see what I am doing wrong or got a suggestion to why it ignore my values? Or maybe know another way to do this, so I end up with the same result?
Apache rewrites in a loop. You need to stop it for archive/index.php since that always matches the first RewriteRule:
RewriteRule ^archive/index\.php$ - [L]
RewriteRule ^archive/([^/]+)?$ archive/index.php?cat=$1 [E=ORIG_URI:/$1]
RewriteRule ^archive/([^/]+)/([^/]+)?$ archive/index.php?cat=$1&sub=$2 [E=ORIG_URI:/$1]
RewriteRule ^archive/([^/]+)/([^/]+)/([^/]+)?$ archive/index.php?cat=$1&sub=$2&id=$3 [E=ORIG_URI:/$1]
RewriteRule ^archive/([^/]+)/([^/]+)/([^/]+)?/([^/]+)$ archive/index.php?cat=$1&sub=$2&id=$3 [E=ORIG_URI:/$1]
You can also remove [E=ORIG_URI:/$1] if you don't use it.

.htaccess page rewrite with spelling errors

I am building a content management system to allow a companies staff members to be listed via category. Essentially, this is what I'm trying to accomplish:
There is a page called inside.php that contains 404, 500, etc. errors. We have a page called physicians.php that passes variables and displays specific information based on the variable so physicians.php?id=1 would display a specific category of staff members. Currently, when you go to http://website.com/physicians or http://website.com/physicians/ it redirects to http://website.com/physicians.php just fine, but the problem is that happens even if you type some variation of the word physicians. Example being that physiciansasfhouiae would still link to physicians.php where we want it to link to inside.php because it is technically a non-existing page.
Here is the rewrite code that I have now:
RewriteEngine on
#enables you to access PHP files with HTML extension
AddType application/x-httpd-php5 .html .htm
RewriteCond ${REQUEST_URI} ^.+$
RewriteRule ^detail/(css|js|img)/(.*)?$ /$1/$2 [L,QSA,R=301] [OR]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -l
RewriteRule ^ - [L]
RewriteCond %{REQUEST_URI} physicians
RewriteRule .* physicians.php
RewriteRule ^physicians/((([a-zA-Z0-9_-]+)/?)*)$ physicians.php?id=$1 [NC,L]
RewriteRule ^((([a-zA-Z0-9_-]+)/?)*)$ inside.php?page=$1
You should start by deleting these 2 lines:
RewriteCond %{REQUEST_URI} physicians
RewriteRule .* physicians.php
Not only are these 2 lines not necessary due to the RewriteRule that's already below them, but they're causing the main problem you're noticing. Those 2 lines match any URL with the substring "physicians" in it, which is not quite what you want. So you need to make your matching pattern more specific; thankfully, the next RewriteRule line is already doing that:
RewriteRule ^physicians/((([a-zA-Z0-9_-]+)/?)*)$ physicians.php?id=$1 [NC,L]
That line is really all you need to accomplish what you want. It tells Apache to only match the word "physicians" if it's the first word of the URL and ends in a slash (i.e. the whole, exact word "physicians"), which won't match misspellings like "physiciansasfhouiae".
But as a suggestion, I would tweak it slightly to make the optional trailing slash still match, and remove the slashes from the ID parameter:
RewriteRule ^physicians(/((([a-zA-Z0-9_-]+)/?)*))?$ physicians.php?id=$4 [NC,L]
So this will send all these variations to physicians.php:
/physicians
/physicians/
/physicians/abc123
/physicians/abc123/
And the ID parameter will equal abc123 (if it's provided). All other requests will go to inside.php, even if the URL contains a variation of "physicians".

Redirect Urls With Parameters Using Htaccess

I did a "site:" command in google to view the indexed urls and found a lot of urls with parameters all pointing to the same page.
Its a static site, but about 5 years ago it was a Wordpress site, which may be how those links were created and indexed by Google. The 3 main links I found are as follows. They all look like these 3 but with different id's.
http://example.com/index.php?option=com_banners&task=click&bid=41
http://example.com/?option=com_content&view=article&id=86&Itemid=201
http://example.com/phlebotomy-jobs?&pid=6774238282444518&q=Phlebotomy&pg=7
My question is how do I redirect these links, with all of the different parameter ids, to their corresponding pages. The first two go to the homepage and the 3rd one goes to a /phlebotomy-jobs page.
So, what I'm looking for is, for example, this url: http://example.com/phlebotomy-jobs?&pid=6774238282444518&q=Phlebotomy&pg=7 to redirect to http://example.com/phlebotomy-jobs
Basically removing everything from the ? on.
Well, not sure if it's the "best" way, but this, for example, works:
RewriteCond %{QUERY_STRING} option=
RewriteRule (.*) /$1? [R=301,L]
RewriteEngine On
RewriteRule ^index.php?$ /path/page.php [R=301,L,QSA]
RewriteRule ^$ /path/page.php [R=301,L,QSA]
RewriteRule ^phlebotomy-jobs?$ /path/page.php [R=301,L,QSA]
The QSA RewriteRule Flag appends the query string.
https://httpd.apache.org/docs/2.4/rewrite/flags.html
Edit:
Since you're not concerned with retaining the query strings:
RewriteEngine On
RewriteCond %{REQUEST_URI} (^/index.php$|^/$|^/phlebotomy-jobs$)
RewriteCond %{QUERY_STRING} .
RewriteRule (.*) /$1? [R=301,L]
Note: This method prevents passing any query strings to either of those two pages.

adding a parameter to a url that has a mod_rewrite value

I have a rewirte rule that rewrites my portfolio urls from
portfolio.php?cat=cat-name&project=project-slug
to
/portfolio/cat/slug/
That all works fine and dandy, I'm wondering if It's possible to add a parameter to the end of the rewritten slug. For example
/portfolio/cat/slug&preview=true
I'm trying to make it so I can preview hidden projects by appending the preview=true to the end. It works if I go to
portfolio.php?cat=cat-name&project=project-name&preview=true
I'm just hoping I don't have to create a rule that has /true I've tied various ways to get the value or preview but thought someone here may have a simple solution
Edit Adding .htaccess
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^.*$
#portfolio
RewriteRule ^portfolio/?$ portfolio.php [L,NC]
RewriteRule ^portfolio/([a-z0-9_-]+)/([a-z0-9_-]+)/?$ portfolio.php?cat=$1&project=$2 [L,NC]
RewriteRule ^portfolio/([a-z0-9_-]+)/?$ portfolio.php?cat=$1 [L,NC]
RewriteRule ^portfolio/([a-z0-9_-]+)/page=([0-9]+)/? portfolio.php?cat=$1&page=$2&
Add QSA as an option to the back of the RewriteRule (in the [] brackets). E.g.
RewriteRule ^portfolio/([a-z0-9_-]+)/([a-z0-9_-]+)/?$ portfolio.php?cat=$1&project=$2 [L,NC,QSA]
Please look at http://www.workingwith.me.uk/articles/scripting/mod_rewrite for such an example.
You may also include a hidden field with that appropriate value.

Categories