Ao desenvolver uma grande aplicação ou um framework Web, é preciso ter consciência de que precisará trabalhar com camadas e que fará várias conversões entre estas camadas para manter o sistema portável. Vamos observar a imagem abaixo:
Apesar de ser possível utilizar a mesma notação para representar números reais no formulário, na aplicação e no BD, pode ser que o usuário esteja em uma localidade que usa uma notação diferente da americana (usada no PHP), e pode ser que o BD não utilize a mesma notação que a aplicação para todos tipos de dados. Portanto, é importante realizar a transformação de dados entre as camadas do sistema.
Partindo do usuário, devemos considerar que ele está em uma localidade. É interessante que este usuário utilize a notação usada pela sua localidade para representar números, datas, etc. Para isso, é importante conhecer algumas funções:
- setlocale - define a notação de uma localidade, que será usada para exibir valores numéricos, monetários, etc.
- localeconv - devolve um array com informações sobre a localidade definida com setlocale.
- number_format - permite formatar um número com símbolos personalizados.
- money_format - formata um valor monetário de acordo com a localidade definida com setlocale.
- strftime e gmstrftime - formatam datas (alguns valores são afetados pela localidade definida em setlocale).
- strcoll - compara duas strings de acordo com a localidade definida em setlocale.
Exemplo:
// Definindo localidade do Brasil no Linux setlocale(LC_ALL, 'pt_BR.UTF-8'); // Obtendo informacoes sobre a localidade $conv = localeconv(); // Exibindo um numero de acordo com a localidade echo number_format(1234.567, 3, $conv['decimal_point'], $conv['thousands_sep']); // Montando uma expressao regular para checar se foi passado um numero real $sinal = preg_quote($conv['positive_sign'].$conv['negative_sign']); $milhar = preg_quote($conv['thousands_sep']); $decimal = preg_quote($conv['decimal_point']); $exp = "/^([{$sinal}]?)(\d{1,3}([{$milhar}]\d{3})*)([{$decimal}]\d+)?$/"; $valor = '1.234,56'; if (preg_match($exp, $valor)) { // Valor valido }
Para converter o valor real passado na notação da localidade, é preciso adaptar a expressão regular para recuperar as componentes do número individualmente (separar o sinal, porção inteira e porção decimal), depois formatá-los com a notação do PHP, depois realizar o casting para float.
Desta maneira, o seu objeto na camada da aplicação fica com os valores padronizados no formato do PHP, mas quando precisa ser mostrado para o usuário, você pode convertê-los novamente para a notação que ele está adaptado.
Seguindo a mesma lógica, é importante que a ligação entre a aplicação e o Banco de Dados também seja feita a conversão de valores. Primeiro, para a aplicação passar um valor para o banco (através da montagem da SQL de INSERT ou UPDATE) e, depois, para converter um valor recebido do BD e jogá-lo no objeto da aplicação (recuperar um resultado de um SELECT e convertê-lo para notação PHP). Isso porque os dados recuperados de um SELECT costumam ser trazidos na forma de string ou NULL, em alguns casos. Porém, alguns destes campos representam números e é importante convertê-los para o padrão do PHP para que possíveis contas sejam realizadas sem problemas.
A conversão entre aplicação e BD costuma ser mais simples, pois os SGBDs normalmente usam a notação americana com algumas pequenas diferenças. Para realizar tais conversões, é preciso conhecer a sintaxe do BD. Por exemplo, no MySQL, valores booleanos são implementados na forma de um inteiro (TINYINT), que pode assumir valor 1 e 0 (representando true e false respectivamente). Já no PostgreSQL, existe o campo BOOL que pode assumir TRUE e FALSE, porém, em uma consulta, são devolvidos os valores "t" e "f". Ambas, se forem convertidas com casting para bool do PHP assumiriam o valor "true", caracterizando um erro de implementação. O correto é verificar se o valor vale "t" ou "f", conforme exemplo:
// Recuperando um registro do BD $registro = $pdo->fetchObject(); // Criando um objeto da aplicacao (ORM) $usuario = new usuario(); // Testando o tipo de um atributo switch ($tipo_atributo) { case 'bool': $usuario->comprovou = ($registro->comprovou == 't'); break; ...
Ou seja, cada driver de conexão com o BD deve implementar seu método de conversão da aplicação para o banco e do banco para aplicação. Isso tudo depende de um ORM com tipos bem definidos, para que os tipos usados no PHP possam ser convertidos e recuperados num BD relacional.
0 comentários
Postar um comentário
Nota: fique a vontade para expressar o que achou deste artigo ou do blog.
Dica: para acompanhar as respostas, acesse com uma conta do Google e marque a opção "Notifique-me".
Atenção: o blogger não permite inclusão de tags nos comentários, por isso, use algum site externo para postar seu código com dúvidas e deixe o link aqui. Exemplo: pastebin.com