htacess how to convert two query strings to one url - php

Options +FollowSymlinks
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^news/([^/]+) /casino2/newsdetail.php?newsid=$1 [NC]
Currenty using the above code to conver http://localhost/casino2/newsdetail.php?newsid=3 to
http://localhost/casino2/news/3 now what problem is i am trying to make one url out of two query strings like if url is localhost/casino2/newsdetail.php?newsid=3 & pagename=article the url should be localhost/casino2/news/article is it possible to do so ?

To start with, those rules appear to do the opposite of what you say you want - i.e. they're rewriting "/localhost/casino2/news/4711" to "/casino2/newsdetail.php?newsid=4711".
Provided this is what you really mean, what you need to do is to save two items into two variables, instead of just one into one variable, like this:
RewriteRule ^news/([^/]+)/([^/]+) /casino2/newsdetail.php?newsid=$1&pagename=$2 [NC]
If the newsid is always 1, so that you don't need to pass it to the php, you simply create it in your replacement, like this
RewriteRule ^news/([^/]+) /casino2/newsdetail.php?newsid=1&pagename=$1 [NC]
This would create the following rewrites:
/news/article -> /casino2/newsdetail.php?newsid=1&pagename=article
/news/somethingelse -> /casino2/newsdetail.php?newsid=1&pagename=article
But if you want to be able to select different newsids, you need to pass it in somewhere - either as part of the URL or as a querystring.
Just to be clear, the way the rules are applied is
RewriteRule "What the URL looks like in the browser" "What my web server expects"
If you have problems, I highly suggest you turn on a lot of debug logging, it'll be a great help. The relevant config lines are
RewriteLog /path/to/logfile
RewriteLogLevel 3

Related

Having trouble with .htaccess and clean URLs, need redirect on entering the "dirty" URL

I know there's a million similar questions on stuff like this, but clearly there's much I don't understand because I haven't been able to derive answers or a solution to my (as I understand it) fairly simple question.
Basically, I'm trying to get an old site back up, but want a more professional look to it this time round, which includes cleaning up the URLs. A typical page is as follows (hosted locally at the moment, but will be assigned a domain in next few days):
192.168.0.200/album-reviews.php?albid=22
Using the following code, I have been able to achieve the above example page loading via manually typing 192.168.0.200/album-reviews/22 into the browser:
RewriteRule ^album-reviews/([0-9a-zA-Z]+) album-reviews.php?albid=$1 [NC,L]
However, what I want as well is for when the link is clicked on my site, it directs the user to /album-reviews/22 instead of album-reviews.php?albid=22. The only way to get the clean URL at the moment is to manually type it into the bar, links from my site do not get the clean URL, the code I have been playing around with (and have been unable to get working) based on sources I've found is this:
RewriteCond %{THE_REQUEST} /album-reviews/?(?:\.php)?\?albid=([0-9a-zA-Z]+)
RewriteRule ^ /album-reviews/%1? [L,R]
So if anyone could shed some light on how I get all this working as desired, I'd be grateful, I hope my question has been articulated appropriately.
On a side note, If i wanted to include the post title in the URL too like this:
192.168.0.200/album-reviews.php?albid=22&ptitle=my first post
how would alter any code to make it like this:
192.168.0.200/album-reviews/22/my first post
Thank you.
You can use:
Options -MultiViews
RewriteEngine on
RewriteCond %{THE_REQUEST} /album-reviews/?(?:\.php)?\?albid=([^\s&]+)&ptitle=([^\s&]+)
RewriteRule ^ album-reviews/%1/%2? [L,R=301]
RewriteCond %{THE_REQUEST} /album-reviews/?(?:\.php)?\?albid=([^\s&]+)
RewriteRule ^ album-reviews/%1? [L,R=301]
RewriteRule ^album-reviews/([^/]+)/?$ album-reviews.php?albid=$1 [NC,L]
RewriteRule ^album-reviews/([^/]+)/([^/]+)/?$ album-reviews.php?albid=$1&ptitle=$2 [NC,L]
If you want to show the contents of http://yoursite.com/album-reviews.php?albid=22 at the url http://yoursite.com/album-reviews/22, you need these codes:
Your htaccess needs this lines:
RewriteEngine On
Options -Indexes
RewriteRule ^album-reviews/(.*)$ album-reviews.php?pretty=$1 [L,QSA]
And your PHP these:
$pretty = $_GET['pretty'];
$parameters = explode('/',$pretty);
$albid = $parameters[0];
Your user won't be redirected, your website will show directly the page at the pretty url.
Now, what happened? That you instructed htaccess to send everything after album-reviews as a GET parameter called "pretty". Then in your PHP you cut it for every / that appeared in it, and that way you formed the array $parameters. So you can even get more parameters, for every /, they are all in the array $parameters:
$second_parameter = $parameters[1];
$third_parameter = $parameters[2];
$fourth_parameter = $parameters[3];

mod_rewrite on apache - language parameter

I have searched for a solution of this problem all over the Internet, read various threads and articles about it but did come to a full solution for my - i think quite generic problem in mod_rewrite. Here is the issue:
I have developed a small webapp that lets users make calculations (splitting costs after holidays "who pays to whom"). Now I have come to the point where I want to make it (especially the static pages) language dependent. What seemed like no big deal by passing a get parameter ?lang= seems to be a problem for search engines according to my research - so apache mod_rewrite to the rescue to have beautiful URLs like
example.com/en/index => example.com/index.php?lang=en.
example.com/en/about => example.com/about.php?lang=en.
Moreover, users should be able to share their calculations with their friends - for this they are issued an ID after caluclation therefore a rule like
example.com/c/9842398dfalkjdsf98sfdasf => example.com/c.php?id=9842398dfalkjdsf98sfdasf
is used to call their previous calculations (language handling is done here directly in the script automatically, also this links are not needed to be indexed in any search engine).
To achieve this I have come up with these rules:
RewriteEngine on
RewriteRule ^c/([^/]+) c.php?id=$1 [L,QSA]
RewriteRule ^c/([^/]+)/ c.php?id=$1 [L,QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/([^/]+)/$ $2.php?lang=$1 [L,QSA]
RewriteRule ^([^/]+)/([^/]+)$ $2.php?lang=$1 [L,QSA]
So far these rules work - however:
Here are my questions:
1) Is this approach a good approach for language dependent sites - meaning will google index the "static" sites like "about" etc. correctly?
2) Come somebody come up with a Rewrite Rule to also have requests like
example.com/about => example.com/about.php?lang=en.
(notice the missing language parameter in the first url)
to send them to the standard language
OR should I then first get their accpted langauge and then redirect them to example.com/LANG/about
3) How should I design the language detection - especially on the homepage? Right now it works according to the rules above - howver I have seen solutions on the Internet passing everything first to a index.php which then call the disred page like
index.php?lang=en&page=about
When google "visits" it will usually not provide an HTTP_ACCEPT_LANGUAGE so will it even ever see the other language versions like example.com/it/about ?
4) Turns out that using RewriteRules kill your relative CSS, JS, picture links in your code (suprise!), however I found a page on the internet saying that this also could be handled with a RewriteRule instead of using absoulute paths in the html? (here). Unfortunately I where not able to implement it.
In a nutshell:
I am a little confused, hope somebody can help how to set up a simple SEO conform, language dependent site and that this will help others to see a best practice solution as a whole.
Thanks in advance!
Try this , thank you
RewriteEngine On
# This is to prevent the rules from looping, they only work as on-shot
RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule ^ - [L]
# If the url is blank, go to 'web/en/'
RewriteRule ^/?$ /web/?lang=en [L,QSA]
# If the url starts with en,es,pt-br, remove it and add ?lang=$1 ,has /web
RewriteRule ^/?(en|es|pt-br)/web(/?.*)$ /web$2/?lang=$1 [L,QSA,R]
# If the url starts with en,es,pt-br, remove it and add ?lang=$1 ,has no /web
RewriteRule ^/?(en|es|pt-br)/?$ /web/?lang=$1 [L,QSA,R]
# If the url starts with en,es,pt-br, remove it and add ?lang=$1 ,everything else
RewriteRule ^/?(en|es|pt-br)/(.+?)/?$ /$2/?lang=$1 [L,QSA,R]

Rewrite url with multiple get variables

I have a url that looks like this
http://mysite.com/item/?food=1&drink=1&bar=1&name=Bomba
I want to make it more friendly and maybe more secure and to look something like
http://mysite.com/item/Bomba
The problem is that sometime drink or bar will not be part of the url, so I don't know how to make it to work with .htaccess. Also I don't know how to make rules for multiple get variables and if I can use conditionals in a rewrite rule (if drink==true or something similar).
And also I don't want to use post because I want to be able to share the link.
So far I made something like this
mysite.com/item/1/Bomba.menu
and the rule
Options +FollowSymlinks
RewriteEngine on
RewriteRule ^item/(.+)/(.+).menu item/?food=$1&drink=$1&bar=$1&name=Bomba [nc]
But it only works if the url stays the same.
Thanks
So at last I made this short link http://mysite.com/item/1/D1/W1/Bomba that is taking me here http://mysite.com/item/?food=1&drink=1&wine=1&name=Bomba
And added this rules to the .htaccess file.
Options +FollowSymlinks
RewriteEngine on
RewriteRule ^item/(.+)/(D.)/(W.)/(B.+)/(.+) item/?food=$1&drink=$1&wine=$1&bar=$1&name=$5 [nc]
RewriteRule ^item/(.+)/(D.+)/(W.+)/(.+) item/?food=$1&drink=$1&wine=$1&name=$4 [nc]
RewriteRule ^item/(.+)/(D.+)/(B.+)/(.+) item/?food=$1&drink=$1&bar=$1&name=$4 [nc]
RewriteRule ^item/(.+)/(W.+)/(B.+)/(.+) item/?food=$1&wine=$1&bar=$1&name=$4 [nc]
I hope that it will help somebody.
:)
[EDITED Answer]
You would need to have them set as key/value pairs as you have no way to tell if is a Drink or a Bar ID.
The other way I can think of, which won't look quite as elegant is to prefix the ids, so if it was a Drink ID then make the dynamic URL:
http://mysite.com/item/D1/B4
Then if it is prefixed with 'D' then it is a drink, 'B' for bar etc

Use SO's URL format for $_GET

StackOverflow has a very neat, clean URL format. It looks the same as a directory structure, but there can't be a directory for each question on here! My question is this:
How can I get http://www.site.com/sections/tutorials/tutorial1, for example, to stay like that in the address bar, but convert it to a $_GET request for PHP to mess around with?
I could use a .htaccess file, but I don't want the URL being rewritten - I'd like it to remain clean and friendly. Is my only option here to use PHP's string splitting functions to get some pretend $_GET data?
Thanks,
James
What about this, using .htaccess to split the URL up, the URL won't change but instead point to index.php with various $_GET variables, this could could be increased to cover more URL sections.
# turn rewriting on
RewriteEngine on
# get variables in this order, [object], [object,action], [object,action,selection]
RewriteRule ^([^/\.]+)/?$ /index.php?object=$1 [L,NC,QSA]
RewriteRule ^([^/\.]+)/([^/\.]+)/?$ /index.php?object=$1&action=$2 [L,NC,QSA]
RewriteRule ^([^/\.]+)/([^/\.]+)/([^/\.]+)/?$ /index.php?object=$1&action=$2&selection=$3 [L,NC,QSA]
A PHP Rest framework could do this for you, so I refer you to this question. Most of the frameworks won't load the data from $_GET, but will offer a similar and equally convenient way to read it.
It's actually a RESTful way of building your URI's. Not only SO applies this pattern. I recommend to not re-invent the wheel by taking a look at this question.
In addition you could switch over to a RESTful framework such as CakePHP or CodeIgniter, which are configured by default to use the RESTful pattern.
$_GET does not contain the path compontents from the URL, only the parameters that eventually follow the ?. You could use
$parts = explode('/', pathinfo($_SERVER['REQUEST_URI'], PATHINFO_DIRNAME));
var_dump($parts);
However it seems you should have a read on URL rewriting e.g. with mod_rewrite. "I don't want the URL being rewritten - I'd like it to remain clean and friendly" ... The rewriting happens on the server. The user never sees the "ugly" result.
If you don't want to use mod rewrite the best solution would be using regular expressions agains the $_SERVER['REQUEST_URI'] variable.
i.e:
preg_match('|/(.*)/(.*)|', $_SERVER['REQUEST_URI'], $match);
$_GET['param1'] = $match[1];
$_GET['param2'] = $match[2];
If you want to setup a capture all php script. IE if the script request doesn't exist use a default script, use mod-rewrite to redirect everything to one script i.e. the zend framework (and most of the PHP MVC framework) use this:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ index.php [NC,L]
I think that could be a bit cumbersome.

Easy mod_rewrite - So I'll never have to think about it again

Not sure how you'll take this question but...
Whenever I try to make my URLs look pretty I always end up messing around for too long and it's simply not worth the trouble. But the end effect is good if it were a simple task.
So what I want to do is create a method which in the end would achive something like...
index.php?do=user&username=MyUsername //This becomes...
/user/MyUsername //...that
index.php?do=page&pagename=customPage //And this becomes...
/page/customPage //...that
index.php?do=lots&where=happens&this=here //This also becomes...
/lots/happens/here //...that
index.php?do=this&and=that&that=this&and=some&more=too //And yes...
/this/that/this/some/more //This becomes this
So then I just make a nice .htacess file that I'll never have to look at again. Everything will be better in the world because we have pretty URLs and my head didn't hurt in the making.
You can use a different approach of throwing the url in a single parameter, and parse it in your application.
So the apache rewrite rule would look like:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
which will convert your urls as follows:
/user/MyUsername => index.php?q=/user/MyUsername
/page/customPage => index.php?q=/page/customPage
...
In your app, you then have a $_GET['q'] variable, which you can split by '/', and have your arguments in order. In PHP it would be something like:
$args = explode('/', $_GET['q']);
$args will be an array with 'user', 'MyUserName', etc.
This way you will not have to touch your .htaccess again, just your app logic.
For /user/MyUsername ==> index.php?do=user&username=MyUsername and /page/customPage ==>
index.php?do=page&pagename=customPage, you can use:
RewriteRule ^([A-Za-z0-9-]+)/([A-Za-z0-9-]+)$ index.php?do=$1&$1name=$2 [L]
But I don't think you can write a catch-all rule for /lots/happens/here and /this/that/this/some/more because you need to tell mod_rewrite how to translate the two urls.
Remember, mod_rewrite has to translate /lots/happens/here into index.php?do=lots&where=happens&this=here and not the other way around.
The best approach would be to delegate your application to generate the “pretty URLs” as well as parse and interpret them and to use mod_rewrite only to rewrite the requests to your application with a rule like this one:
RewriteRule %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
This rule will rewrite all requests that can not be mapped directly to an existing file to the index.php. The originally requested URL (more exact: the URL path plus query) is then available at $_SERVER['REQUEST_URI'].

Categories