Get web browser preferred language with PHP $_SERVER variables HTTP_ACCEPT_LANGUAGE

HTTP Language headers.
In php the way to get the language information sent by browser is with server reserved variables.

1
2
3
<?php
echo $_SERVER['HTTP_ACCEPT_LANGUAGE']);
?>

Which output (in my browsers):

  • ca,en-us;q=0.7,en;q=0.3 in Mozilla Firefox 13.0.1
  • es-ES in Internet Explorer 9 64b
  • ca-ES,ca;q=0.8 in Google Chrome 20.0

The “q-value” (when it’s shown in a value range between 0-1) indicates the percent that the browser prefer this language. If it’s not provided, we asume is 1 (maximum).

How to get the preferred language?
Here’s a simple function I’ve coded to get the preferred language according q-value in ISO 639-1 format:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
function GetLanguageCodeISO6391()
{
	$hi_code = "";
	$hi_quof = 0;
	$langs = explode(",",$_SERVER['HTTP_ACCEPT_LANGUAGE']);
	foreach($langs as $lang)
	{
		list($codelang,$quoficient) = explode(";",$lang);
		if($quoficient == NULL) $quoficient = 1;
		if($quoficient > $hi_quof)
		{
			$hi_code = substr($codelang,0,2);
			$hi_quof = $quoficient;
		}
	}
	return $hi_code;
}
 
echo "Your browser preferred language is: ".GetLanguageCodeISO6391();
?>

To check what will output in your browser, go to this demo.

 

Read More

Redirect a domain to another file domain keeping web browser URL (htaccess)

Situation:
You have a site (eg. www.mysite.com) and a page of this site dedicated to photography (eg. www.mysite.com/photography.html) . For some reason you buy another domain (eg. www.photosite.com) and want to render your photography.html page below this new domain.

Solution:
Use a htaccess file running Apache server to solve that. How?

Options +FollowSymlinks
RewriteEngine on
RewriteRule ^$ photography.html [L]
RewriteRule ^(.*)$ http://www.photosite.com/$1 [P]

And upload it to you new domain renaming the name to .htaccess .

Explanation:

  1. First rule will redirect www.photosite.com to www.photosite.com/photography.html
  2. Second one will “render” every www.mysite.com/any-site-page.html under domain www.photosite.com, and keeping this url domain even navigating between different pages (that’s why there’s a [P], standing for Proxy).

Hope you you find it useful.

Read More

Warning: Cannot modify header information – headers already sent

Sometimes programming with PHP and trying to redirect pages with header(“location:”.$site); , it’s possible to get the following warning:
Warning: Cannot modify header information – headers already sent
This may occur for one of those reasons:

  • Start the file with (or including a file which starts with):
    1
    2
    3
    
    <?php
     
    // the code starts here, above there's a whitespace
  • Having previously in the script (or including a file which have it) whitespaces :
    1
    2
    3
    4
    5
    6
    7
    
    <?php
    // some example code...
    ?>
     
    <?php
    // more example code lines...
    ?>
  • Print or echo of a variable or text before sending headers.
  • HTML code before sending headers.
  • A mix of the above reasons…

Sometimes, depending on PHP version, everything seems to be okay but when you run the script, it doesn’t work. Let’s see an example:

Warning: Cannot modify header information – headers already sent by (output started at /full/route/to/file/which/previously/has/sent/headers/included.php:xx) in /full/route/which/has/sending/header/script.php on line xx

In script.php there is eg. header(“location:script2.php); and apparently headers has sent before in included.php.

In included.php:

1
2
3
4
5
6
7
8
9
10
11
12
<?php
// code
if ($lang== "es")
{
	include("spanish.inc.php");
}
elseif ($lang== "en")
{
	include("english.inc.php");
}
// more code
?>

Imagine your error is on include(“spanish.inc.php”) and obviously the included file is ok (eg. empty). Then why there’s an error? Some php versions or apache/iis configurations, make an include (or require, require_once, …) works as an output buffer. To avoid that, just wrap the “conflictive” code with:

ob_start();
// code which have include or require, etc.
ob_clean();

So, finally In included.php:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
// code
ob_start();
if ($lang== "es")
{
	include("spanish.inc.php");
}
elseif ($lang== "en")
{
	include("english.inc.php");
}
ob_clean();
// more code
?>

 

More information about those php functions here and here.

Read More