.htaccess, Rewriting language code to PHP vars - php

I tried to find some examples here but none of them work for me.. I'm a newbie working with R.E.
I need some help on .htacess > RewriteRule. How could I achieve this?
www.mysite.pt/folder/?a=home&id=22 -> www.mysite.pt/folder/index.php?lang=pt&a=home&id=22
www.mysite.pt/folder/en/?a=home&id=22 -> www.mysite.pt/folder/index.php?lang=en&a=home&id=22
Notes:
both with and without "www"
the ?a=home&id=22 is only an example, I would like to append the
whole query-string.
The 'folder' is needed until I release the website cause I have to
test it on my client server (e.g. www.mysite.pt/site_v2/).
Thanks in advance for your help,
Pedro

I can mainly help you out with regex. I did a few htaccess interventions in the past but don't know the details.
www.mysite.pt/folder/?a=home&id=22 => www.mysite.pt/folder/index.php?lang=pt&a=home&id=22
regex
(www\.)?mysite\.pt/folder/\?(.*)
replace with
www.mysite.pt/folder/index.php?lang=pt&$1
www.mysite.pt/folder/en/?a=home&id=22 => www.mysite.pt/folder/index.php?lang=en&a=home&id=22
regex
(www\.)?mysite\.pt/folder/en/\?(.*)
replace with
www.mysite.pt/folder/index.php?lang=en&$1
I recall that the order you specify the rewrite rules is important and AFAIK first one wins.
Why? It could be that multiple regexes match
This is not the case with these 2 regexes but something to be aware of

Do you want to support only EN and PT?
I also expect that you have a lot of image, CSS, files, etc. Will you want EN and PL versions of those as well? Anyway, let's focus on the scripts for now. Here you want to pick up URIs for /somefolder/en/ and then /somefolder/. If you are using the DOCroot .htaccess then you'll need this:
RewriteEngine On
RewriteBase /
RewriteRule ^(.*?)/en/$ $1/en/index.php?lang=en [L,NS,QSA]
RewriteRule ^(.*?)/$ $1/pl/index.php?lang=pt [L,NS,QSA]
Lookup the L,NS,QSA flags in the mod_rewrite documentation. You'll need the NS flag to stop subqueries biting you. The QSA flag merges the lang parameter with the rest of the query list.
If you want a fixed folder then replace the (.*?) and $1 by the fixed folder name. Also remember that your HTML references will need to work as well. e.g. if a page includes an image src="images/mygif.gif" then this will either resolve to <same directory as HTML file>/images/mygif.gif from the browser perspective, e.g. /folder/en/images/mygif.gif so you'll need to figure out where to map these and add the corresponding rules.

Related

Detecting language and keeping current url schema

Currently I just have one language in my site,
And I implemented the friendly urls vía the .htaccess, like:
RewriteRule ^post/(.+)/(.+) post.php?id=$2&friendly=1
So:
domain.com is the homepage and domain.com/the-title/5 is the page for the post with ID 5.
Now I would like to make that as the default language urls, and for example, next language would be:
domain.com/es is the homepage and domain.com/es/the-title/6 is the page for the post with ID 6 in spanish. (but previous rule should work, too)
Question is,
How should I adapt my (or additional) rewrite rules to check for the 2 first chars of the url (first split) and add it as a param, like: &lan=es and if it's not found then don't add this parameter?
Lets say:
^post/(.+)/(.+) post.php?id=$2&friendly=1 (english)
^es/post/(.+)/(.+) post.php?id=$2&friendly=1&lan=es (spanish)
But if posible,
To just work with more languages (and add, if needed, the extra parameter),
To just work wit other rules, like:
^es/photo/(.+)/(.+) photo.php?id=$2&friendly=1&lan=es (spanish)
Any suggestions?
Something like this might work. I haven't tested it but you can use RewriteCond to check for a specific structure of the uri and if it matches, use the following rule. If it doesn't then continue on to the original rule.
#Does the uri match 2 characters followed by /post/?
RewriteCond %{REQUEST_URI} ^../post/
#then use this rule and stop processing rules
RewriteRule ^(..)/post/(.+)/(.+) post.php?id=$3&friendly=1&lan=$1 [L]
#Else use this rule
RewriteRule ^post/(.+)/(.+) post.php?id=$2&friendly=1&lan=en
Edit: I added a default language to the end of the second rule. This way there is always a $_GET['lan'] parameter. You could leave it off and set a default in php. Your choice, no difference.
I can only answer you with advice cause we need more context...
Use default pages to do a temporary redirect (302) to the default langauge or the user language.
Use always the same scheme to get the language from the same pattern (http://mydomain.com/en/mypage.php)
Use complete language codes if you will have a large public or for much content, like en_US, fr_FR, fr_CA ...
Prefer negative search in your regex to avoid to capture the following characters, like "before/([^/]+)/after", in some cases, this is mandatory.
If you don't have the language information, the user is not coming from a valid url, redirect him to a page with language informations (default or user language).
If user is using direct php link, redirect him to the official link, to avoid duplicate content. You can use $_SERVER['REQUEST_URI'] to check it.
Use a framework to manage it or at least a base to control the routes.
With these advices, you could use only the following rewrite rule for all your website:
RewriteRule ^([^\/]+)/([^\.]+)\.([\.]+)$ index.php?lang=$1&route=$2&format=$3 [L,QSA]
Here I capture the language (es, en, en_US, fr...), the route (post/5, gotabeer, cats/postit/thumb/2) and the format (html, json, jpeg...).
(I didn't try the rewrite rule but it should work)
Here is what I would suggest:
RewriteRule ^/?((en|es)/)?post/(.+)/(.+)$ post.php?id=$4&friendly=1&lan=$2
Where /? allows optional forward slash at begining of string. This makes rule able to be moved interchangeably between htaccess directory contact and httpd.conf server context
((en|es)/)? Allows for optional specification of one of two accepted language codes.
Note that I did not suggest a wildcard for the language part, as I assume you are only working with a known subset of languages, so using something other than a known language code (or missing the entire thing) should fall through to handling be other rules (or perhaps result in 404).
If this is not the case you can change the first portion of the regex from (en|es) to (.{2}) if you expect exactly two characters, or perhaps (.{2}(-.{2})) if you expect to also handle language codes like es-ES.
This should work for you:
RewriteEngine On
RewriteRule ^([a-z]{2})/post/([^/]+)/([0-9]+)/?$ post.php?id=$3&friendly=1&lan=$1 [L,QSA]
RewriteRule ^post/([^/]+)/([0-9]+)/?$ post.php?id=$2&friendly=1&lan=en [L,QSA]

How to load a specific page for any given pathname URL

Let's say I have a web-page called www.mysite.com
How can I make it so whenever a page is loaded like www.mysite.com/58640 (or any random number) it redirects to www.mysite.com/myPHPpage.php?id=58640.
I'm very new to website development so I don't even really know if I asked this question right or what languages to tag in it...
If it helps I use a UNIX server for my web hosting with NetWorkSolutions
Add this to your .htaccess file in the main directory of your website.
RewriteEngine on
RewriteBase /
RewriteRule ^([0-9]+)$ myPHPpage.php?id=$1 [L]
Brief explanation: it says to match:
^ from start of query/page
[0-9] match numbers
+ any matches of 1 or more
$ end of page requested
The parentheses part say to look for that bit and store it. I can then refer to these replacement variables in the new url. If I had more than one parentheses group then I would use $2, $3 and so on.
If you experience issues with the .htaccess file please refer to this as permissions can cause problems.
If you needed to capture something else such as alphanumeric characters you'd probably want to explore regex a bit. You can do things such as:
RewriteRule ^(.+)$ myPHPpage.php?id=$1 [NC, L]
which match anything or get more specific with things like [a-zA-Z0-9], etc..
Edit: and #Jonathon has a point. In your php file wherever you handle the $_GET['id'] be sure to sanitize it if used in anything resembling an sql query or mail. Since you are using only numbers that makes it easy:
$id = (int)$_GET['id']; // cast as integer - any weird strings will give 0
Keep in mind that if you are not going to just use numbers then you will have to look for some sanitizing function (which abound on google - search for 'php sanitize') to ensure you don't fall to an sql injection attack.

Rewrite syntax in .htaccess

I just know how htaccess works but I am always confused with the writing syntax and I appreciate if anyone could help me solving the below htaccess issue.
I have couple pages linking to redirect to something like
http://mydomain.com.au/product-details.php/142/categoryAbstract
but due to the mistakes of previous developer the images are not loading unless that url is
http://mydomain.com.au/product-details.html/142/categoryAbstract
He converted all php pages to html (I really don't know what's this intention in doing that) but
now the url should work even if it as http://mydomain.com.au/product-details.php/142/categoryAbstract
He used the below htaccess for this but its not working. If I manually change the url from .php to .html everything working fine.
RewriteRule ^product-details.html/(.*)/(.*)$ product-details.php?productid=$1&category=$2
I need a working line of code so that even the url http://mydomain.com.au/product-details.php/142/categoryAbstract should work.
You will just need an OR group (a|b) to account for both possibilities:
RewriteRule ^product-details\.(html|php)/(.*)/(.*)$ product-details.php?productid=$1&category=$2
#---------------------------^^^^^^^^^^^
That can be improved a little though. The (.*) are greedy matches. You are better served to use ([^/]+) as the first grouping to match everything up to the next /. I have also escaped the dot as \. so it is matched as a literal instead of any character.
RewriteRule ^product-details\.(html|php)/([^/]+)/(.*)$ product-details.php?productid=$1&category=$2
The .php extension is commonly modified either through rewriting or actual file renaming and server configuration to parse .html as .php in order to hide some server-side information from end users. To prevent them from knowing what technologies the site runs on the back end. It less common to actually rename files to .html than to use URL rewriting to hide the .php, however.
RewriteRule ^product-details.html/(.*)/(.*)$ product-details.php?productid=$1&category=$2
What this rule does is take everything after product-details.html/ and before the last / and a second bit gets taken after the last / until the end of the line. then it takes those bits and puts them where the $1 and $2 are.
to change it so it accepts .html and .php you can change it with
RewriteRule ^product-details(.html|.php)/(.*)/(.*)$ product-details.php?productid=$2&category=$3
Because it looks like the first bit you are grabbing are numbers and (.*) is a greedy selector it may be better to replace it with ([0-9]*) which will only select numbers. that way if you ever have /s in your catagory you'll be fine. giving you:
RewriteRule ^product-details(.html|.php)/([0-9]*)/(.*)$ product-details.php?productid=$2&category=$3

Rewrite URL in PHP

I would like to rewrite the following URL
www.mysite.com/mypage.php?userid=ca49b6ff-9e90-446e-8a92-38804f3405e7&roleid=037a0e55-d10e-4302-951e-a7864f5e563e
to
www.mysite.com/mypage/userid/ca49b6ff-9e90-446e-8a92-38804f3405e7/roleid/037a0e55-d10e-4302-951e-a7864f5e563e
The problem here is that the php file can be anything. Do i have to specify rules for each page on the .htaccess file?
how can i do this using the rewrite engine in php?
To get the rewrite rule to work, you have to add this to your apache configs (in the virtualhost block):
RewriteEngine On
RewriteRule ^([^/]*)/userid/([^/]*)/roleid/(.*)$ /$1.php?userid=$2&roleid=$3 [L,NS]
RewriteRule basically accepts two arguments. The first one is a regex describing what it should match. Here it is looking for the user requesting a url like /<mypage>/<pid>/roleid/<rid>. The second argument is where it should actually go on your server to do the request (in this case, it is your php file that is doing the request). It refers back to the groups in the regex using $1, $2, and $3.
RewriteEngine on
RewriteBase /
RewriteRule ^mypage\/userid\/(([a-z0-9]).+)\/roleid\/(([a-z0-9]).+)$ www.mysite.com/mypage.php?userid=$1&roleid=$2
No you don't need a separate rule for every php file, you can make the filename variable in your regex something like this:
RewriteRule ^(a-z0-9)/userid/([a-z0-9].+)/roleid/([a-z0-9].+)$ $1.php?userid=$2&roleid=$3
If you want to rewrite the latter URL that is entered in the browser TO the first format, you would want to use a .htaccess file.
However, if you want to produce the pretty URLs in PHP (e.g. for use in link tags), then you have two options.
First, you could simply build the URL directly (instead of converting) which in my opinion is preferred.
Second, you could rewrite the first (ugly) URL to the pretty latter URL. You would then need to use preg_replace() in PHP. See http://php.net/manual/en/function.preg-replace.php for more info. Basically, you would want to use something like
$rewrittenurl = preg_replace("#mysite\.com\/mypage.php?userid=(([a-z0-9\-]).+)\&roleid=(([a-z0-9\-]).+)$", "mysite.com/userid/$1/roleid/$2", $firsturl);
Good luck!

Create a page without placing .php at the end?

I was looking for ways to mimic something I've seen, however I'm really not even sure where to start or how to search for it.
Lets say my page was:
foo.com/ and my index page could take an argument of: index.php?id=5
What I'm wanting to do is create the following:
foo.com/5/ rather than placing index.php?id=5 just use the webstring to pass in the parameters, to hide not only the fact its a PHP page, but to clean up the url a bit more.
Is this possible?
Cheers
You'll want to look into URL rewriting. With the commonly used Apache webserver, this is accomplished with mod_rewrite.
or /?5/123/
and in php parse the query string if rewrite is not available
Something like this should suit:
RewriteRule ^pages/([A-Za-z_-]*)(/?)$ /index.php?page=$1
Broken down, we're looking for a URL that starts with pages, has any combination of letters, underscores and hyphens, and an optional trailing forward slash, and passing that to /index.php to handle.
Yes Mod_rewrite is best option, you can create .htaccess file. if you do not want the write a custom function which will handle the your url.

Categories