I have a number of pages in my site, as one would expect.
For example:
index.php
submit.php
view.php?id=blah
I want these rewritten like
index/
submit/
view/blah
Whats the best way of doing this?
The ways of handling it through .htaccess Rewrite can generate a bit of a headache. It seems like a basic answer, but unless you're up on your regular expressions, you're going to be lost.
There's a few ways of handling it, however. I'm assuming that you only have index.php, submit.php, and view.php with an id associated.
RewriteEngine On
RewriteRule ^(index|submit|view)/(\d+)$ /$1.php?id=$2
RewriteRule ^(index|submit|view)/(\d+)$ /$1.php
Here's how it works: You tell .htaccess to turn on the Rewrite Engine. Step 2, you give the site the parameter that tells it how it's done. The parameter in this case reads: At the beginning of the url, after the domain name, check for index, submit, or view. If those exists, it'll look for the id. If both those exists, it will return the value into PHP as /(index, submit, or view)?id=$id.
The second one is in case the ID isn't viable.
This is a simple way of handling it. A more complex way of handling it would be...
RewriteEngine On
RewriteRule ^([a-z]+)/?(\d+)?$ /$1.php?id=$2
This will load whatever is written in regular alphabetical characters of upper and lower case letters only, use that as the filename, then detects if id is even necessary--it will load without.
You should be sure to include some safeguards on your $_GET lines to return errors if the names are erroneous or doesn't return anything of worth.
You should play around with it, research Regular Expressions over a pot of coffee and something alcoholic (I believe that regexp is the #1 cause of alcoholism in modern programmers, but I could be wrong ;-P ...) til you find a scheme that fits comfortably into your system.
As a side-note, you can have as many RewriteRules as you need, but they always get processed from the top one first. I realize this sounds like common sense, but it's important to know when debugging.
Related
I have a website which has dynamic URLs and they're not currently prettified. I have re-worked the site and included pretty URLs, but the real dynamic folder structure/filename has also changed.
To better explain, the current dynamic URLs look like
http://example.com/liveguide/year.php?year=2017
The new dynamic url for the same page is
http://example.com/shows/show-list.php?year=2017
I use the following:
RewriteRule ^shows/(199[5-9]|200[0-9]|20[0-1][0-7])/?$ /shows/show-list.php?year=$1 [L]
To enable the use of pretty URLS like
http://example.com/shows/2017
So what I'm trying to do is if anyone followed a link of the original dynamic URL, they'll end up on the new clean URL. So far I've just got
RewriteRule ^liveguide/year.php /shows/show-list.php [R=301,L]
Which redirects to the correct page, but you're left with the ugly URL in the address bar. How could I do it so that the new, pretty URL is in the address bar?
Ie someone visits
http://example.com/liveguide/year.php?year=2017
They end up on, and see in their address bar
http://example.com/shows/2017
You just need to match the query string, which is in a separate variable, and used in a RewriteCond, which capture to %1, %2 etc. Like this:
RewriteCond %{QUERY_STRING} ^year=(\d{4})$
RewriteRule ^liveguide/year\.php$ /shows/%1? [R=301,L]
While we are here, do you really need to only match just those exact years? Would it matter if /shows/1234 also got rewritten? Probably not, you can just return a 404 from your PHP, so a simpler rule would be ok, like the above just saying any four numbers. It will also work for future years without changing it.
RewriteRule ^shows/(\d{4})/?$ /shows/show-list.php?year=$1 [L]
The goal is usually not to match exactly what you want, and only that, but rather to ensure nothing else (other parts of the site) will be matched that shouldn't be. Simpler rules are easier to maintain and review later. Your script must already be able to handle bad data anyway, so just let it handle the detailed checking without duplicating it unnecessarily.
Hope this helps.
i'm trying to understand some rules or rewrite engine but i can't figure how to do it.
i have this link:
w**.example.com/index.php?city=new+york
and i wish to rewrite to this new:
w**.example.com/good-parties-in-new-york
the value of city can change to any other city.
but the point here is I only what to rewrite if all the key is:
index.php?city=
because the
index.php?zone=
is used for other things, etc...
any suggestion? thanks.
I'm a little confused on what exactly you want to achieve. URL rewriting is normally done to make URLs look nicer, not the other way around.
You would typically want to have a nice URL like this (which you'd communicate to your users):
w**.example.com/good-parties-in-new-york
act as an "alias" for a not-so-nice looking URL like this (= the actual page being served, unbeknownst to the users):
w**.example.com/index.php?city=new+york
With Rewrite, you can backreference regular expressions. In this case, you could convert parts of the "nice" URL into RegEx's which you would then backreference with variables in the query string of the page working in the background.
E.g.:
RewriteEngine On
RewriteBase /
RewriteRule ^good-parties-in-([a-z]+)-([a-z]+)$ index.php?city=$1+$2 [NC,L]
The first RegEx (([a-z]+)) is referenced as $1, the second as $2 (and so on).
Note that this example will only work for city names consisting of two words, like New York, San Francisco etc. You'll have to figure out of how many words city names can consist of and rewrite your code accordingly. (You might also have to set different flags.)
Plus, you should make sure that your php script checks against existing city names and throws an appropriate error/gives out a warning if users enter fantasy names like good-parties-in-magical-rainbow-city or similar.
If this isn't what you're looking for, maybe you could clarify your question?
I'm kind of noob in the world of web so my apologies... I tried many things found on SO and elsewhere, but I didn't manage to do what I want. And the Apache documentation is... well too much complete.
Basically what I want to do is redirect my domain to a subfolder. I found easy solutions for this (many different actually).
http://www.foo.com/
http://foo.com/
should redirect to /bar and appear as http://foo.com/
Using the following I got the expected result :
RewriteEngine on
Options +FollowSymLinks
RewriteCond %{HTTP_HOST} ^www\.foo.com$
RewriteRule ^/?$ "http\:\/\/foo.com" [R=301,L]
RewriteRule ^((?!bar/).*)$ bar/$1 [NC,L]
But I also want the subfolder as well as filenames not to appear when explicitly entered, i.e :
http://www.foo.com/index.html
http://foo.com/index.html
http://wwww.foo.com/bar
http://foo.com/bar
http://wwww.foo.com/bar/index.html
http://foo.com/bar/index.html
Should all appear as
http://foo.com/
Is this possible ?
Obviously using .htaccess, since I'm on a virtual host.
Thanks
As Felipe says, it's not really possible, because you lose information when you do that R=301 redirect: a hard redirect like this starts a whole new request, with no memory of the previous request.
Of course, there are ways to do similar things. The easiest is to put the original request in the query string (here's a good rundown on how mod_rewrite works with query strings). Sure, the query string does show up in the URL, but most modern browsers hide the query string in the address bar, so if your goal is aesthethics, then this method would be workable.
If you really don't want to show any of the original query in the URL, you might use cookies by employing the CO flag (here are some very good examples about cookie manipulation). At any rate, the information about the original request must somehow be passed in the hard redirect.
But anyhow, and most importantly, why would you want to do something like this? It's bound to confuse humans and robots alike. Great many pages behaved like this back when frames were fashionable, and it was pretty terrible (no bookmarking, no easy linking to content, Google results with the snippet "your browser cannot handle frames", no reloading, erratic back button, oh boy, those were the days).
Speaking of which, if your content is html, you may just use a plain old iframe to achieve the effect (but I'd sincerely advise against it).
Is this qood example of redirection of page to another domain page:
RewriteCond %{HTTP_HOST} ^dejan.com.au$ [OR]
RewriteCond %{HTTP_HOST} ^www.dejan.com.au$
RewriteRule ^seo_news_blog_spam\.html$ "http\:\/\/dejanseo\.com\.au\/blog\-spam\/" [R=301,L]
or good old works too:
301 redirect seo_news_blog_spam.html http://dejanseo.com.au/blog/spam/
and whats the difference?
Presumably, the rules are functionally equivalent (well, assuming that http://dejanseo.com.au/blog/spam/ was supposed to be http://dejanseo.com.au/blog-spam/ like the first one redirects to, and the only host pointing at that location is dejanseo.com.au with or without the www).
The first example uses directives from mod_rewrite, whereas the second one uses some from mod_alias. I imagine that the preferred option is the second one for this particular case, if not only because it's a bit simpler (there's also marginal additional overhead involved in creating the regular expressions being used by mod_rewrite, but that's very minor):
Redirect 301 seo_news_blog_spam.html http://dejanseo.com.au/blog-spam/
However, I suspect the reason that you have the first one is that it was created using CPanel (based on the unnecessary escapes in the replacement that appeared before in another user's question where it was indicated CPanel was the culprit). They've gone with the mod_rewrite option because it provides conditional flexibility that the Redirect directive does not, and I assume this flexibility is reflected somewhat in whatever interface is used to create these rules.
You'll note that there is a condition on whether or not to redirect based upon your host name in the first example, identified by the RewriteCond. This allows for you to perform more powerful redirects that are based on more than just the request path. Note that mod_rewrite also allows for internal redirects invisible to the user, which mod_alias is not intended for, but that's not the capacity it's being used in here.
As a final aside, the host names in your RewriteCond statements should technically have their dots escaped, since the . character has special meaning in regular expressions. You could also combine them, change them to direct string comparisons, or remove them altogether (since I imagine they don't do anything useful here).
Unbeliavable, the problem was that the synthax wasn't correct, so instead of:
redirect 301 seo_news_blog_spam.html http://dejanseo.com.au/blog/spam/
it should look like this:
Redirect 301 seo_news_blog_spam.html http://dejanseo.com.au/blog/spam/
One, first big letter was the source of all troubles, what a waste of time :D
it works now as it supposed to!
Thanks to everyone who participated, issue solved.
I want to a rewrite rule such that if a user goes to the URL example.org/stuff/junk.jpg the rule will process and end up at re-writer.php but if the user goes to example.org/stuff/hackingisawesome/junk.jpg the rule will not be triggered and they will get a standard 404 (or a page, if one should exist).
I can't tell, based on the environmental variables, if this is possible without some fairly fancy regex.
So does anyone know of either:
a) a way this is already built into the mod_rewrite syntax, or
b) a good, reliable way of handling this with regular expressions?
Links to documentation or tutorials welcome. I'm just feeling clueless on where to go next.
Oh, and I can imagine the ways I could simply have the script that the rule redirects to simply deliver the 404, but I'd rather only use the rule when the conditions exist.
Try this:
RewriteRule ^stuff/[^/]+$ re-writer.php
This will rewrite all requests to /stuff/… with only one additional path segment to re-writer.php.