← Tutoriais

[PHP] Sistema Multi-Linguagem

Lida 47272 vezes

Offline

RuiGomes 
Membro
Mensagens 504 Gostos 0
Feedback +4

Troféus totais: 23
Trófeus: (Ver todos)
Super Combination Combination Topic Starter Poll Voter Level 4 Level 3 Level 2 Level 1 500 Posts 100 Posts

Sistema Multi-Linguagem em PHP

Introdução

Neste tutorial vou explicar como criar um Sistema Multi-Linguagem em PHP, como o que é utilizado no meu próprio website: www.ruigomes.eu.
O sistema consiste em ter vários ficheiros que apenas contêm o texto e, na página em que se quer ter várias linguagens, faz-se um include do ficheiro adequado.


Parte 1 - Ficheiros Necessários

Neste tutorial vou usar como exemplo um site com duas línguas: Português e Inglês.
Começamos por criar uma pasta onde vamos ter os ficheiros com os textos.
Vou utilizar como exemplo uma pasta de nome: "lang".
Dentro dessa pasta criamos dois ficheiros: 'en.php' e 'pt.php'
No ficheiro 'en.php' vamos escrever o seguinte:
Código: [Seleccione]
<?php
define
'TEXTO1''This is a test.' );
?>

E no ficheiro 'pt.php' vamos escrever o seguinte:
Código: [Seleccione]
<?php
define
'TEXTO1''Isto é um teste.' );
?>

Basicamente, temos de definir uma constante com o mesmo nome, mas em diferentes linguagens.
Para adicionar mais variáveis é apenas necessário acrescentar:
Código: [Seleccione]
define( 'NOME_DA_VARIAVEL', 'texto da variável' );É necessário ter a váriavel com o mesmo nome em ambos os ficheiros (pt.php e en.php), com o texto na linguagem devida (em 'pt.php' o texto deve estar em português, e em 'en.php' o texto deve estar em inglês.

Pode criar todas as linguagens que quiser, apenas criando outro ficheiro dentro da pasta "lang", com as constantes definidas na lingua que deseja adicionar
Se, por exemplo, quiser ter texto em Francês, pode criar o ficheiro 'fr.php' com o seguinte código:
Código: [Seleccione]
<?php
define
'TEXTO1''Ceci est un test' );
?>


Parte 2 - Carregar a linguagem

No ínicio do index.php (ou a página a traduzir) devemos incluir o seguinte código:
Código: [Seleccione]
<?php
if (!isset($_COOKIE["lang"])) {
include "lang/en.php"; }
 elseif (
$_COOKIE["lang"]=="en") {
include "lang/en.php"; }
 elseif (
$_COOKIE["lang"]=="pt") {
include "lang/pt.php"; }
?>

O que este código faz é:
  • Se não houver nenhum cookie definido, o sistema carrega o ficheiro 'en.php'
  • Se houver um cookie que definida que a linguagem a utilizar é o Inglês, o sistema carrega o ficheiro 'en.php'
  • Se houver um cookie que definida que a linguagem a utilizar é o Português, o sistema carrega o ficheiro 'pt.php'

Para incluir outras linguagens, basta inserir o seguinte código, depois de [b" ]include "lang/pt.php"; } "[/b]:
Código: [Seleccione]
elseif ($_COOKIE["lang"]=="lingua") {
include "lang/lingua.php"; }
Se, por exemplo, desejasse incluir texto em Francês, o código completo ficaria assim:
Código: [Seleccione]
<?php
if (!isset($_COOKIE["lang"])) {
include "lang/en.php"; }
 elseif (
$_COOKIE["lang"]=="en") {
include "lang/en.php"; }
 elseif (
$_COOKIE["lang"]=="pt") {
include "lang/pt.php"; }
 elseif (
$_COOKIE["lang"]=="fr") {
        include 
"lang/fr.php"; }
?>


Parte 3 - Definir os Cookies

Agora é necessário ter uma maneira de definir a linguagem que queremos utilizar.
Para tal, vamos criar dois ficheiros: 'change_en.php' e 'change_pt.php' (sem as aspas, obviamente).
No ficheiro 'change_en.php' vamos escrever o seguinte código:
Código: [Seleccione]
<?php 
$expire
=time()+60*60*24*30;
setcookie("lang""en"$expire);
$back $_SERVER['HTTP_REFERER'];
header('Location: ' $back);
?>

No ficheiro 'change_pt.php' vamos escrever o seguinte código:
Código: [Seleccione]
<?php 
$expire
=time()+60*60*24*30;
setcookie("lang""pt"$expire);
$back $_SERVER['HTTP_REFERER'];
header('Location: ' $back);
?>

Para adicionar a sua própria língua, apenas precisa de mudar o "pt" ou o "en" para a língua em questão.
Se, por exemplo, desejasse incluir texto em Francês, teria de criar um novo ficheiro: 'change_fr.php', e nesse ficheiro escreveria:
Código: [Seleccione]
<?php 
$expire
=time()+60*60*24*30;
setcookie("lang""fr"$expire);
$back $_SERVER['HTTP_REFERER'];
header('Location: ' $back);
?>


Parte 4 - Finalizar

Agora resta aplicar o texto nas várias línguas onde quiser que ele apareça, e criar link's para os ficheiros que mudam a linguagem.

Para mostrar o texto dentro dos ficheiros de texto apenas precisa de escrever:
Código: [Seleccione]
<?php echo TEXTO1 ?>
Para criar os links para mudar de texto precisa de escrever o seguinte:
Código: [Seleccione]
<a href="change_en.php">Change language to English</a>
<br>
<a href="change_pt.php">Mudar a linguagem para Português</a>


Sistema de detecção de país automatizado

O tutorial incluí agora um sistema que detecta automaticamente o país do utilizador, carregando automaticamente o texto na linguagem adequada. Se o utilizador quiser, mesmo assim, visitar o site noutra linguagem, poderá continuar a fazê-lo, apenas clicando nos links para mudar a linguagem.

Para incluir esta automatização, é necessário criar um novo ficheiro chamado "detect_country.php", com o seguinte código:
Código: [Seleccione]
<?php
function locateIp($ip){
$d file_get_contents("http://www.ipinfodb.com/ip_query.php?ip=$ip&output=xml");
 
//Use backup server if cannot make a connection
if (!$d){
$backup file_get_contents("http://backup.ipinfodb.com/ip_query.php?ip=$ip&output=xml");
$answer = new SimpleXMLElement($backup);
if (!$backup) return false// Failed to open connection
}else{
$answer = new SimpleXMLElement($d);
}
 
$country_code $answer->CountryCode;
$country_name $answer->CountryName;
$region_name $answer->RegionName;
$city $answer->City;
$zippostalcode $answer->ZipPostalCode;
$latitude $answer->Latitude;
$longitude $answer->Longitude;
$timezone $answer->Timezone;
$gmtoffset $answer->Gmtoffset;
$dstoffset $answer->Dstoffset;
 
//Return the data as an array
return array('ip' => $ip'country_code' => $country_code'country_name' => $country_name'region_name' => $region_name'city' => $city'zippostalcode' => $zippostalcode'latitude' => $latitude'longitude' => $longitude'timezone' => $timezone'gmtoffset' => $gmtoffset'dstoffset' => $dstoffset);
}
?>

E modificar o código da "Parte 2 - Carregar a linguagem" para:
Código: [Seleccione]
<?php
include "detect_country.php";
if (!isset(
$_COOKIE["lang"])) {
$ip $_SERVER['REMOTE_ADDR'];
$ip_data locateIp($ip);
if ($ip_data['country_name']=="Portugal") {
include "lang/pt.php";
} else {
include "lang/en.php"; }
}
 elseif (
$_COOKIE["lang"]=="en") {
include "lang/en.php"; }
 elseif (
$_COOKIE["lang"]=="pt") {
include "lang/pt.php"; }
?>

Para utilizar isto com outra linguagem serão necessárias algumas alterações.
Vou exemplificar, utilizando o Francês:

Código: [Seleccione]
<?php
include "detect_country.php";
if (!isset(
$_COOKIE["lang"])) {
$ip $_SERVER['REMOTE_ADDR'];
$ip_data locateIp($ip);
if ($ip_data['country_name']=="Portugal") {
include "lang/pt.php"; } 
elseif ($ip_data['country_name']=="France") {
include "lang/fr.php"; }
else {
include "lang/en.php"; }
}
 elseif (
$_COOKIE["lang"]=="en") {
include "lang/en.php"; }
 elseif (
$_COOKIE["lang"]=="pt") {
include "lang/pt.php"; }
?>

A sugestão de um sistema automatizado foi feita pelo user cenourinha, e a detecção do país é feita pelo http://ipinfodb.com/.


Conclusão

Espero que este tutorial tenha sido útil.
Em caso de dúvida, é preferível que responda ao tópico em vez de enviar PM, pois a dúvida de uma pessoa pode ser a dúvida de outra.


Cumprimentos,

Rui Gomes
Offline

cenourinha 
Elite
Mensagens 4094 Gostos 21
Troféus totais: 34
Trófeus: (Ver todos)
Mobile User Apple User Level 6 Super Combination Combination Topic Starter 10 Poll Votes Poll Voter Level 5 Level 4

Agora brincas um bocadinho com esta API e tens um sistema de detecção de país automático... :D
http://ipinfodb.com/index.php
Offline

RuiGomes 
Membro
Mensagens 504 Gostos 0
Feedback +4

Troféus totais: 23
Trófeus: (Ver todos)
Super Combination Combination Topic Starter Poll Voter Level 4 Level 3 Level 2 Level 1 500 Posts 100 Posts

Obrigado pela sugestão, tenho de ver se vejo isso.
Se conseguir depois faço um update ao tutorial.
Offline

cenourinha 
Elite
Mensagens 4094 Gostos 21
Troféus totais: 34
Trófeus: (Ver todos)
Mobile User Apple User Level 6 Super Combination Combination Topic Starter 10 Poll Votes Poll Voter Level 5 Level 4

Basicamente:

Código: [Seleccione]
<?php
function locateIp($ip){
$d file_get_contents("http://www.ipinfodb.com/ip_query.php?ip=$ip&output=xml");
 
//Use backup server if cannot make a connection
if (!$d){
$backup file_get_contents("http://backup.ipinfodb.com/ip_query.php?ip=$ip&output=xml");
$answer = new SimpleXMLElement($backup);
if (!$backup) return false// Failed to open connection
}else{
$answer = new SimpleXMLElement($d);
}
 
$country_code $answer->CountryCode;
$country_name $answer->CountryName;
$region_name $answer->RegionName;
$city $answer->City;
$zippostalcode $answer->ZipPostalCode;
$latitude $answer->Latitude;
$longitude $answer->Longitude;
$timezone $answer->Timezone;
$gmtoffset $answer->Gmtoffset;
$dstoffset $answer->Dstoffset;
 
//Return the data as an array
return array('ip' => $ip'country_code' => $country_code'country_name' => $country_name'region_name' => $region_name'city' => $city'zippostalcode' => $zippostalcode'latitude' => $latitude'longitude' => $longitude'timezone' => $timezone'gmtoffset' => $gmtoffset'dstoffset' => $dstoffset);
}
 
//Usage example
$ip $_SERVER['REMOTE_ADDR'];
$ip_data locateIp($ip);
$pais $ip_data['country_code'];
$expire=time()+60*60*24*30;
setcookie("lang"$pais$expire);
$back $_SERVER['HTTP_REFERER'];
header('Location: ' $back);
?>

Penso que funcione, mas não testei... só fiz copy and paste do exemplo e alterei.
Offline

RuiGomes 
Membro
Mensagens 504 Gostos 0
Feedback +4

Troféus totais: 23
Trófeus: (Ver todos)
Super Combination Combination Topic Starter Poll Voter Level 4 Level 3 Level 2 Level 1 500 Posts 100 Posts

Já fiz o sistema automático.
Obrigado pela sugestão.

Com o método que postaste ia fazer include de ficheiros inexistentes no caso de o utilizador ser de um país que não Portugal ou Inglaterra, mas obrigado na mesma.

Cumps.
Offline

cenourinha 
Elite
Mensagens 4094 Gostos 21
Troféus totais: 34
Trófeus: (Ver todos)
Mobile User Apple User Level 6 Super Combination Combination Topic Starter 10 Poll Votes Poll Voter Level 5 Level 4

Já fiz o sistema automático.
Obrigado pela sugestão.

Com o método que postaste ia fazer include de ficheiros inexistentes no caso de o utilizador ser de um país que não Portugal ou Inglaterra, mas obrigado na mesma.

Cumps.

Exacto, assim como colocas-te já faz a verificação. :)
Offline

RuiGomes 
Membro
Mensagens 504 Gostos 0
Feedback +4

Troféus totais: 23
Trófeus: (Ver todos)
Super Combination Combination Topic Starter Poll Voter Level 4 Level 3 Level 2 Level 1 500 Posts 100 Posts

É mais um if ou menos um if :-P

Btw, agora reparei que há uma secção só de Tutoriais. Não será melhor mover este tópico para lá?

Cumps.
Offline

anjo2 
Membro
Mensagens 3020 Gostos 0
Troféus totais: 31
Trófeus: (Ver todos)
Super Combination Combination Topic Starter 10 Poll Votes Poll Voter Poll Starter Level 5 Level 4 Level 3 Level 2

E usarem coisas nacionais  :superlol:

Código: [Seleccione]
$country = stream_get_contents(fopen("http://www.ipdomain.info/cc[".$_SERVER['REMOTE_ADDR']."]", "r"));
if(file_exists("lang/${country}.php")) require_once("lang/${country}.php");
else require_once("lang/uk.php"); // Lingua por definição
+- isto, mais pequeno e fácil, digo eu
Offline

bfms 
Equipa
Mensagens 1769 Gostos 40
Feedback +1

Troféus totais: 35
Trófeus: (Ver todos)
Search Level 6 Apple User Super Combination Combination Topic Starter 50 Poll Votes 10 Poll Votes Poll Voter Poll Starter

Muito bom tutorial! Vai dar-me jeito!
;)
Offline

RuiGomes 
Membro
Mensagens 504 Gostos 0
Feedback +4

Troféus totais: 23
Trófeus: (Ver todos)
Super Combination Combination Topic Starter Poll Voter Level 4 Level 3 Level 2 Level 1 500 Posts 100 Posts

E usarem coisas nacionais  :superlol:

Código: [Seleccione]
$country = stream_get_contents(fopen("http://www.ipdomain.info/cc[".$_SERVER['REMOTE_ADDR']."]", "r"));
if(file_exists("lang/${country}.php")) require_once("lang/${country}.php");
else require_once("lang/uk.php"); // Lingua por definição
+- isto, mais pequeno e fácil, digo eu

Assim é uma boa solução, mas se o utilizador preferir ver o site noutra linguagem, não tem como escolher.

Cumps.
Offline

Emanuel Santos 
Elite
Mensagens 848 Gostos 2
Feedback +25

Troféus totais: 25
Trófeus: (Ver todos)
Windows User Super Combination Combination Topic Starter 10 Poll Votes Poll Voter Level 4 Level 3 Level 2 Level 1

Podes melhorar.. em vez de cookies usavas sessions e fazias apenas

Citar
require_once 'lang/' . $_SESSION['lang'] . '.php';

E também usava arrays em vez de constantes.
Offline

Cacofb 
Elite
Mensagens 1035 Gostos 3
Troféus totais: 34
Trófeus: (Ver todos)
Level 6 Tenth year Anniversary Linux User Mobile User Apple User Super Combination Combination Topic Starter 10 Poll Votes Poll Voter

Muito bom tutorial !!

Há uns meses tinha-me dado um jeitaço.. andei precisamente à procura disto!!
Offline

elcsat 
Membro
Mensagens 53 Gostos 0
Troféus totais: 19
Trófeus: (Ver todos)
Super Combination Combination Topic Starter Level 4 Level 3 Level 2 Level 1 50 Posts 10 Posts First Post

nao tirando valor ao tutorial...ha outras soluçoes para criar um site multilingua.

a quem prefira utilizar um array com o respectivo conteudo, na minha opniao nao é a melhor soluçao.

quando se trata de textos extensos se calhar em vez de um array ou um define é melhor usar um include ou um require.


em relaçao a detectar o pais quem quiser pode instalar uma extensao do php a partir do perl que faz isso.


o tutorial ta exelente, parabens

 :+trafego:
Offline

narg 
Membro
Mensagens 265 Gostos 0
Feedback +2

Troféus totais: 27
Trófeus: (Ver todos)
Super Combination Combination Topic Starter Poll Voter Level 5 Level 4 Level 3 Level 2 Level 1 100 Posts

Só um aparte, apresentar sites diferentes em linguas diferentes, no mesmo url não é uma boa opção SEO, ou seja o link por exemplo www.pagina.com/exemplo.php se tivesse o cookie ou session numa lingua diferente, não seria indexado nas 2 ou 3 ou 4 linguas, perdendo assim SEO.

A melhor situação seria usar url_rewrite e criar links do tipo www.pagina.com/pt/exemplo.php

Código: [Seleccione]
Options +FollowSymlinks
RewriteEngine on
RewriteBase /

RewriteRule ^en/$ /index.php?lg=en [NC]
RewriteRule ^pt/$ /index.php?lg=pt [NC]
RewriteRule ^es/$ /index.php?lg=es [NC]
RewriteRule ^fr/$ /index.php?lg=fr [NC]

RewriteRule ^en/(.*)$ /$1?lg=en [NC]
RewriteRule ^es/(.*)$ /$1?lg=es [NC]
RewriteRule ^fr/(.*)$ /$1?lg=fr [NC]
RewriteRule ^pt/(.*)$ /$1?lg=pt [NC]

Assim sendo passaria-se a usar o $_GET['lg']

é claro que ao abrir o site em www.pagina.com deveria-mos redireccionar para a língua predefinida
Offline

Emanuel Santos 
Elite
Mensagens 848 Gostos 2
Feedback +25

Troféus totais: 25
Trófeus: (Ver todos)
Windows User Super Combination Combination Topic Starter 10 Poll Votes Poll Voter Level 4 Level 3 Level 2 Level 1

nao tirando valor ao tutorial...ha outras soluçoes para criar um site multilingua.

a quem prefira utilizar um array com o respectivo conteudo, na minha opniao nao é a melhor soluçao.

quando se trata de textos extensos se calhar em vez de um array ou um define é melhor usar um include ou um require.


em relaçao a detectar o pais quem quiser pode instalar uma extensao do php a partir do perl que faz isso.


o tutorial ta exelente, parabens

 :+trafego:


Não percebeste.. é um array que está num ficheiro .php que podes incluir. Esse array pode até ser criado dinamicamente, vindo da BD por ex.