.htaccess URL rewrite ignored - php

.htaccess newbie here.
I have a URL like this:
example.com/lesson-plans/earth-sciences/show_lesson_plan.php?title=Some_Title&id=6
that I need to be rewritten like this:
example.com/lesson-plans/earth-sciences/some-title-6
I am using the following .htaccess URL rewrite:
RewriteEngine On
RewriteRule ^lesson-plans/earth-sciences/([^/]*)/([^/]*)$ /lesson-plans/earth-sciences/show_lesson_plan.php?title=$1&id=$2&cat=3 [L]
However, when I hover over/click on links of the original format (example.com/lesson-plans/earth-sciences/show_lesson_plan.php?title=Some_Title&id=6), they are not being rewritten. I've tried a few different rewrite rules, but nothing works.
How can I make this rewrite work? As far as I know, .htaccess is working on my server and rewrites are permitted.

You were close
RewriteEngine on
RewriteCond %{QUERY_STRING} title=([^&]+)&id=([^&]+)
RewriteRule ^lesson-plans/earth-sciences/show_lesson_plan.php$ /lesson-plans/earth-sciences/%1-%2 [QSA,L,R]

Randomly while lying in bed last night.
You have the rewrite rule back to front. you have to add the rule for the rewritten url to turn it back into an ugly one
see: http://martinmelin.se/rewrite-rule-tester/
RewriteEngine On
RewriteRule ^lesson-plans/earth-sciences/(.*)-(.+)$ /lesson-plans/earth-sciences/show_lesson_plan.php?title=$1&id=$2&cat=3 [L]
so
lesson-plans/earth-sciences/some-title-6
becomes
/lesson-plans/earth-sciences/show_lesson_plan.php?title=some-title&id=6&cat=3

I ended up using the following code and am posting it as an answer in the event someone else finds this useful:
RewriteEngine on
RewriteRule ^([^/.]+)/([^/.]+)$
show_lesson_plan.php?title=$1&id=$2
This will take a url (like this: http://example.com/lesson-plans/earth-sciences/a-cloud-in-a-bottle-i/8923) and run it through this: http://example.com/lesson-plans/show_lesson_plan.php?title=$1&id=$2
Note that I changed the original URL slightly, opting to break the id out of the title string.

Related

SEO friendly URL not working using .htaccess

I'm trying to implement a SEO friendly URL using .htaccess by using the RewriteRule below
RewriteRule ^n/article/([a-zA-Z0-9]+)/$ article.php?title=$1
The actaul URL looks like this
http://localhost/n/article.php?title=this-is-the-first-news-article
but I want it to look like this :
http://localohst/n/article/this-is-the-first-news-article
When I applied the RewiteRule above it does not change to the desired URL
This should do it. You are missing the n. Not sure why you need the word title though.
RewriteRule ^n/article/title/([a-zA-Z0-9]+)/$ article.php?title=$1
You have to capture the query string first. You can't do that with a RewriteRule because they ignore the query string. Here we're using [R] to redirect. If this is working for you and there is the potential that the old URLs are being stored somewhere as links, then you may want to specify [R=301]. Be sure to remove all old-style links from your site though (that contain the previous link format we're rewriting), that way you're not penalized for not updating your links.
RewriteEngine on
RewriteBase /
RewriteCond %{QUERY_STRING} title=([^&]+)
RewriteRule ^n/article.php n/article/%1? [R,L]
If your site needs the formatting to function from the original, you might also need this after the first rule. This rule quietly redirects the URL back to the original without showing it to the end user:
RewriteRule ^n/article/(.*) n/article.php?title=$1 [L]
it will be RewriteRule ^n/article/title/([a-zA-Z0-9]+)/$ article.php?title=$1

How to Convert Query String to Segment URI?

I'm trying to convert a query string;
http://atwd/books/course?course_id=CC100&format=XML&submit=Submit
Into a segment URI;
http://atwd/books/course/CC100/XML
I'm working in CodeIgniter.
I was looking at a stackoverflow answer that said to check CodeIgniter's URL segment guide, but I don't think there's any information on how to convert a query string into a segment URI. There is, however a way to convert a segment URI into a query string, which is bringing up a load of results from Google too.
Following another stackoverflow answer, I tried this in my .htaccess file but nothing seemed to work
RewriteCond %{QUERY_STRING} ^course_id\=([^&]+)\&format\=([^&]+)$
RewriteRule ^$ /course/%1/format/%2 [R,L]
In my entire .htaccess file I have this;
<IfModule mod_rewrite.c>
RewriteEngine on
#Source: http://codeigniter.com/user_guide/general/urls.html
#Removal of index.php
RewriteCond $1 !^(index\.php|images|robots\.txt)
RewriteRule ^(.*)$ /index.php?route/$1 [L]
#Source: https://stackoverflow.com/questions/3420204/htaccess-get-url-to-uri-segments
#Format Course function requests
RewriteBase /
RewriteCond %{QUERY_STRING} ^course_id\=([^&]+)\&format\=([^&]+)$
RewriteRule ^$ /course/%1/format/%2 [R,L]
</IfModule>
This is in my root directory of Codeigniter screenshot
My code in the .htaccess file isn't working, I refresh the page and nothing happens. The code to hide the index.php is working though. Does anyone know why?
The notion of "converting URLs" from one thing to another is completely ambiguous, see the top part of this answer for an explanation of what happens to URLs when redirecting or rewriting: https://stackoverflow.com/a/11711948/851273
There's 2 things that happen, and I'm going to take a wild stab and guess that you want the 2nd thing, since you're complaining that refreshing the page doesn't do anything.
When you type http://atwd/books/course?course_id=CC100&format=XML&submit=Submit into your browser, this is the request URI that gets sent through mod_rewrite: /books/course. In your rule, you are matching against a blank URI: RewriteRule ^$ /course/%1/format/%2 [R,L]. That's the first reason your rule doesn't work. The second reason why it doesn't work is because above that, everything except images and index.php and robots.txt is being routed through index.php. So even if you were matching against the right URI, it gets routed before your rule even gets to do anything.
You need to correct the pattern in your rule to match the URI that you expect to redirect, and you need to place this rule before the routing rule that you have. So everything should look roughly like this:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteBase /
RewriteCond %{QUERY_STRING} ^course_id\=([^&]+)\&format\=([^&]+)$
RewriteRule ^/?books/course$ /course/%1/format/%2 [R,L]
#Source: http://codeigniter.com/user_guide/general/urls.html
#Removal of index.php
RewriteCond $1 !^(index\.php|images|robots\.txt)
RewriteRule ^(.*)$ /index.php?route/$1 [L]
</IfModule>
You'll need to tweak the paths to make sure they match what you are actually looking for.
To both redirect the browser and internally rewrite back to your original URL, you need to do something different.
First, you need to make sure all of your links look like this: /course/CC100/format/XML. Change your CMS or static HTML so all the links show up that way.
Then, you need to change the rules around (all before your codeigniter routing rule) to be something liek this:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteBase /
# redirect browser to a URI without the query string
RewriteCond %{THE_REQUEST} ^(GET|HEAD)\ /books/course/?\?course_id=([^&]+)&format=([^&]+)
RewriteRule ^/?books/course$ /course/%2/format/%3? [R,L]
# internally rewrite query string-less request back to one with query strings
RewriteRule ^/?course/([^/]+)/format/([^/]+)$ /books/course?course_id=$1&format=$2&submit=Submit [L]
#Source: http://codeigniter.com/user_guide/general/urls.html
#Removal of index.php
RewriteCond $1 !^(index\.php|images|robots\.txt)
RewriteRule ^(.*)$ /index.php?route/$1 [L]
</IfModule>
I'm not going to address the misunderstanding already addressed pretty well in the other answer and comments, and I can't speak for CodeIgniter specifically, but having given their URL routing docs a quick skim, it seems pretty similar to most web frameworks:
You probably just want to direct all traffic (that doesn't match physical files) to the frontend web controller (index.php) and handle the URL management in CodeIgniter's routing, not a htaccess file.
To do that, your htaccess could be as simple as:
<IfModule mod_rewrite.c>
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* index.php [QSA,L]
</IfModule>
This, as I said, will redirect any traffic that doesn't match an physical file such as robots.txt or an image to your index.php.
Then, using the routing as described in the docs (http://ellislab.com/codeigniter/user-guide/general/routing.html) you can take in parameters and pass them to your controllers as you see fit, there is no need to 'convert' or 'map' anything, your URL's don't need to resolve to /?yada=yada internally, based on your routing rules CodeIgniter can work it out.
You'll need wildcard routes such as this from the docs:
$route['product/:id'] = "catalog/product_lookup";
A rough example of what yours might end up looking like would be something like:
$route['course/:id/format/:format'] = "course/something_or_other_action";
If I'm understanding you correctly, you might be over-thinking it. I have something similar in my own code.
I have a controller named Source. In that controller, I have the following method:
public function edit($source_id, $year)
{
# Code relevant to this method here
}
This produces: http://localhost/source/edit/12/2013, where 12 refers to $source_id and 2013 refers to $year. Each parameter that you add is automatically translated into its own URI segment. It required no .htaccess trickery or custom routes either.

URL Rewrites not working

On my website I am trying to rewrite a long URL to a SEO friendly one.
I've got the following code, but it doesnt seem to affect anything! However if I type dgadgdfsg into my htaccess, it throws an internal server error. So I am presuming it is something with Rewrite Rule.
RewriteEngine On
RewriteRule ^([^/]*)/([^/]*)/([^/]*)$ /missing-people/user-profile.php?userID=$1&firstName=$2&lastName=$3 [L]
I have confirmed that mod_rewrite is on.
This is the current URL
http://mysite.com/missing-people/user-profile.php?userID=1&firstName=Liam&lastName=Gallagher
and this is what I want it too appear like
http://mysite.com/1/Liam/Gallagher
Change your RewriteRule to this (slightly modified from your version)
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/?$ missing-people/user-profile.php?userID=$1&firstName=$2&lastName=$3 [QSA,L]
If that doesn't work try putting a R flag for testing purpose (which will make your browser change the original URI to: /missing-people/user-profile.php?userID=1&firstName=Liam&lastName=Gallagher
Presuming your userID is comprised only of digits and firstName and lastName are only alphanumeric.
RewriteEngine On
RewriteRule /(\d+)/(\w+)/(\w+)/ /missing-people/user-profile.php?userID=$1&firstName=$2&lastName=$3 [L]
A more strict version that does the same thing except it sets boundaries for the beginning and the end of the evaluated regex.
RewriteEngine On
RewriteRule /^(\d+)\/(\w+)\/(\w+)$/ /missing-people/user-profile.php?userID=$1&firstName=$2&lastName=$3 [L]

mod_rewrite freakishly appends 21 slashes to URL

I have what I thought was a simple mod_rewrite rule.
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^store/([a-z0-9_\-]+)/?([a-z0-9_\-]+)?(.*)?$ store/$2?store_name=$1$3 [L]
However, when I go to a URL like:
http://www.mydomain.com/store/e95_airport/
It turns into:
http://www.mydomain.com/store/e95_airport/////////////////////
I'm expecting the URL to load:
index.php?store_name=e95_airport
It works fine when I call a URL like:
store/e95_airport/some-page-other-than-index.php
I've disabled all other mod_rewrite rules just in case there was a conflict somewhere else in my .htaccess file. Is there anyone here who can diagnose what's wrong with my rewrite rule? Any help is greatly appreciated!
The problem is that the site is getting itself into a loop because you're redirecting it to essentially the same address.
Okay, so you are changing it with the rewrite, but the URL it rewrites it to still matches the expression.
The way mod_rewrite works is that once it's rewritten the URL, it then effectively requeries itself with the new URL. So if your new URL still matches the expression, it will get into a loop.
Why it stops at 21 slashes? This is because Apache will detect when it's in a loop, and stop if it requeries itself twenty times.
As #Spudley said, you are into a loop.
Looking to your rewrite rule, and looking the result you want, I would say that the rewrite rule is wrong also. It should be something like this:
RewriteRule ^store/([a-z0-9_\-]+)/?([a-z0-9_\-]+)?(.*)?$ index.php?store_name=$1 [L]

Diggbar modrewrite- How do they pass URLs through modrewrite?

With the new Diggbar, you can put http://digg.com in front of any URL that you are currently at and it will create a Digg short URL. I am only assuming they do this by modrewrite (though I am not sure since I am new at this all).
How is this done? It seems to me when I try this with a website I am working on, it bombs out.
I want to be able to do the following:
http://example.com/http://stackoverflow.com/question/ask
and have a modrewrite that will allow this to go to
http://example.com/index.php?url=http://stackoverflow.com/question/ask
But when I use this modrewrite:
RewriteEngine on
RewriteRule ^([A-Za-z0-9]+)$ /message.php?id=$1 [L]
it doesn't work. What am I doing wrong?
You have to take the value from the request line because Apache removes empty path segments. The initially requested URI path /http://foobar/ becomes /http:/foobar/. But the request line (THE_REQUEST) stays untouched:
RewriteCond %{THE_REQUEST} ^GET\ /(https?://[^\s]+)
RewriteRule ^https?:/ index.php?url=%1 [L]
You're only looking for letters and numbers in that regular expression, so it won't pick up the colon and slashes. You're also using index.php in the example and message.php in the htaccess ;)
You'll probably want something like this:
RewriteEngine on
RewriteRule ^http://(.+)$ /index.php?url=$1 [L]
This makes sure you only catch URLs here, and you can still have regular pages! (Think about what would have happened if you went to example.com/index.php, you'd end up in an infinite loop.)

Categories