Internacionalização rápida com PHP

O PHP possui um recurso interessante no qual as variáveis podem assumir qualquer nome, ter espaços, acentuação e outros caracteres.

${'meu novo nome!'} = 10;

Entre as chaves podemos escrever qualquer coisa no índice, fugindo da regra de apenas letras, números e sobrelinhas.

Lembra de variáveis variáveis? Então…

Escrever qualquer coisa como nome de variável é o primeiro recurso que vamos usar na tradução. O outro é o magic __get de classes. Um método que é acionado sempre que você tentar acessar uma propriedade que não existe.

class SomeClass {
	function __get($name) {
		echo "Erro: A propriedade '$name' não existe.";
	}
}

Como vai funcionar

Considere $m sendo uma instância da classe que ainda vamos criar. Na view e onde mais precisar de tradução, use:

<p><?= $m->{'Hello world'} ?></p>

$json = ['message' => $m->{'Error, try again.'}];

O __get será acionado e nele a busca pela tradução será feita. Caso não exista, o próprio texto é retornado.

Qual idioma o usuário irá consumir?

O navegador envia para o servidor no cabeçalho de solicitação as preferências de idioma. Essa informação pode ser acessada em code>$_SERVER[‘HTTP_ACCEPT_LANGUAGE’].

Algo como:

pt-BR,pt;q=0.8,en-US;q=0.6,en;q=0.4

Você pode parar por aqui ou criar outras regras de persistência, como cookie, sessão e banco de dados. Você só precisa ter a chave do idioma.

Para cookie, crie e modifique o cookie em alguma área do site.

<?php

if (isset($_GET['changeLanguage'])) {
	setcookie('lang', $_GET['changeLanguage'], ...);
}

?>

A Classe

<?php

class m {
	// idioma atual
	public $lang;
	
	// idiomas disponíveis
	public $opts = ['pt', 'en', 'es'];
	
	function __construct() {
		// definição do idioma: do mais específico para o mais genérico
		// desconsidere sessão e cookie ou modifique para o seu ambiente
		if (isset($_SESSION['user']])) {
			$this->lang = $_SESSION['user']['lang'];
		}
		// cookie
		else if (isset($_COOKIE['lang'])) {
			$this->lang = $_COOKIE['lang'];
		}
		// navegador: uma expressão regular para encontrar os padrões
		// e para cada um verificar se o idioma está disponível
		else if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
			if (preg_match('#[a-z-]{2,}#i', $_SERVER['HTTP_ACCEPT_LANGUAGE'], $matches)) {
				foreach ($matches[0] as $lang) {
					if (in_array($lang, $this->opts)) {
						$this->lang = $lang;
						break;
					}
				}
			}
		}
		
		// última verificação e definição do idioma padrão
		if (!in_array($this->lang, $this->opts))
			$this->lang = $this->opts[0];
		
		// com o idioma definido, abra a sua fonte de texto/tradução
		$this->_ = json_decode(file_get_contents($this->lang . '.json'));
	}
	
	function __get($text) {
		return isset($this->_[$text]) ? $this->_[$text] : $text;
	}
}

?>

Para textos longos e áreas com muitas variações você pode usar if ($m->lang == 'pt-BR') {}.

Com certeza essa não é a melhor solução para lidar com múltiplos idiomas, mas quebra o galho com coisas simples e desenvolvimento rápido.

You may also like...