PHP Jedi

Que o PHP esteja com você!

  • Home
  • Sobre

Posts Tagged ‘tutorial’

Codificação de Caracteres – ISO-8859-1 versus UTF8

Tuesday, October 5th, 2010

  1. Introdução
  2. A Tabela ASCII
  3. Unicode
  4. Por que usar UTF-8?
  5. Como usar UTF-8 codificações de caracteres no dia-a-dia?
    1. Como usar UTF-8 nos arquivos (php, html, css, js, etc.)
    2. Como usar UTF-8 no banco de dados
    3. Como usar UTF-8 na conexão com o banco de dados
    4. Como usar UTF-8 no cabeçalho HTTP
    5. Como usar UTF-8 no XML (Incluindo XHTML)
    6. Como usar UTF-8 no HTML
    7. Como usar UTF-8 em requisições Ajax
    8. Como usar UTF-8 na hora de converter de uma codificação para outra:
    9. Como usar UTF-8 nas funções de string:
  6. Conclusão
  7. Fontes e referências

Introdução^

Segundo a Wikipédia, “Uma codificação de caracteres é um padrão de relacionamento entre um conjunto de caracteres”.

No nosso mundo existem milhares de caracteres em centenas de idiomas e variações e ainda outros milhares de símbolos que podem ser utilizados em fontes de computador para serem exibidas, salvas e transportadas. As tabelas de caracteres surgiram para transformar os nossos caracteres em bits que podem ser armazenados. A primeira tabela surgiu nos EUA e é chamada Tabela ASCII.

A Tabela ASCII^

Em computadores temos bits que geram bytes. Porém para um byte (ou mais) gerar um caracter, é necessário ter uma tabela de equivalência. Em 1963 a American Standards Association (Associação de Padrões Americanos) criou uma tabela de caracteres chamada ASCII, que é utilizada até os dias de hoje. A ASCII utilizava inicialmente um conjunto de 7 bits (27 = 128 caracteres). Para a língua inglesa os caracteres da tabela ASCII são suficientes para exibir todas as palavras, simbolos e textos possíveis. Porém para outros idiomas, como por exemplo latinos – que contém acentos, são necessários diferentes caracteres, a tabela ASCII não tem serventia completa. Para isso criou-se uma versão estendida da ASCII, utilizando 8 bits (um byte), possibilitando assim 256 caracteres. Então a ISO (Internation Standarts Organization – Organização de Padrões Internacionais) criou várias codificações (norma 8859) que são formas diferentes da tabela ASCII estendida (8 bits) para suprir as necessidades de vários países e idiomas de exibir seus símbolos. Ao todo existem 16 variações da codificação ISO-8859. A mais utilizada é a ISO-8859-1, chamada também de Latin-1, que é direcionada para a maioria dos idiomas europeus ocidentais. A ISO-8859-1 também a é mais utilizada no Brasil.

Para entender a diferença entre um arquivo texto em uma codificação e outra vamos exemplificar: A sequência de bits “11100100″ que representa o número hexadecimal “0xE4″ e o decimal “228″ corresponde ao caractere “ä” da tabela ISO-8859-1 (Latina) e ao caractere “ф” da ISO-8859-5 (Grega). Se um arquivo em uma codificação for aberto utilizando uma outra, os caracteres concorrentes do 128 ao 255 poderão ser interpretados de forma diferente, porém o caracter 0 ao 127 nas tabelas ISO serão interpretados de forma igual, pois correspondem à tabela ASCII de 7 bits.

Unicode^

As codificações diferentes serviram ao propósito de saciar as necessidades dos diferentes países e idioma, porém existem limitações nesse modelo. Essas limitações com a internet se tornam a cada dia mais evidentes. Por exemplo: Se eu tenho uma página em HTML usando a codificação ISO-8859-1 e preciso exibir caracteres japoneses e latinos ao mesmo tempo? Não consigo (a não ser com entidades, o que é desaconselhavel!). Para resolver tal problema e outros, o Unicode foi criado.

A idéia original foi do Joe Becker da Xerox e do Lee Collins e Mark Davis da Apple em 1989. Porém somente em 1991 foi criado o Unicode consortium – Consórcio Unicode – e publicada a primeira versão de um sistema de codificação de caracteres que englobassem todas as palavras de todos os idiomas do mundo inteiro.

Para economizar bytes, somente os caracteres diferentes da tabela ASCII utilizam mais de um byte. Esse sistema de bytes-múltiplos foi adotado pelo padrão UTF que tem como a variação mais conhecida a UTF-8.

Um arquivo codificado em UTF-8 pode exibir todos os caracteres mapeados e propostos pela Unicode, sendo assim resolvendo o problema inicial de exibir caracteres de diferentes idiomas ao mesmo tempo, no mesmo arquivo. A codificação UTF-8 é que tem a maior tendência de utilização hoje em dia. Todos os consórcios, institutos e associações de padrões importantes recomendam o suporte (e a utilização) do UTF-8 para transporte, exibição e armazenamento de caracteres.

Por que usar UTF-8?^

Na vida real, temos que usar UTF-8 nas codificações de arquivos e banco obrigatoriamente nas seguintes situações

  1. O sistema/site terá (agora ou no futuro) suporte à múltiplos idiomas;
  2. O sistema/site exibirá conteúdo de outros idiomas, como por exemplo o símbolo de euro (€);
  3. O usuário do sistema/site poderá ser um estrangeiro que possa inserir dados em outras codificações, como por exemplo um turco escrevendo o seu nome em um fórum brasileiro.

Para os outros casos não necessariamente precisamos utilizar UTF-8 para codificações, porém é recomendado, devido aos seguintes pontos:

  1. Nunca saberemos o futuro do sistema/site, podendo haver múltiplos idiomas ou usuários de outros idiomas no futuro;
  2. Evitar problemas de compatibilidade entre meios diferentes;
  3. É a codificação mais utilizada, é a tendência de utilização e é a recomendação dos grandes nomes da internet;

Como usar UTF-8 codificações de caracteres no dia-a-dia?^

Como usar UTF-8 nos arquivos (php, html, css, js, etc.)^

Todo editor de texto moderno (inclusive o bloco de notas), possui opções para escolher a codificação de caracteres. Consulte a documentação do seu editor para saber como fazer.

É necessário também não gerar os bytes identificadores BOM (Begin Order Mark), que em sistemas nix (Unix, Linux, etc.) o PHP interpreta como texto e envia para a saída, provocando problemas com a utilização de cabeçalhos.

Como usar UTF-8 no banco de dados^

Os SGBDs (Sistema Gerenciador de Banco de Dados) mais usados suportam as codificações UTF-8 e ISO-8859-1. Incluindo o MySQL, PostgreSQL, sqlite, MS SQL Server, Oracle. No MySQL por exemplo é possível definir a codificação a nível de banco de dados, esquema, tabela e até campo. Para saber como escolher a codificação, consulte a documentação do front-end utilizado para criar tabelas, etc.

Como usar UTF-8 na conexão com o banco de dados^

O banco de dados pode estar em uma codificação (ou em várias), porém a entrada e saída das queries serão feitas em uma só codificação que é a de conexão. Selecionar a codificação da conexão é diferente em cada classe/funções de conexão ao banco. Seguem alguns exemplos:

  1. // mysql
  2. mysql_set_charset('utf8');
  3. // mysqli
  4. $conexao->set_charset("utf8");

Ou ainda através de queries (mysql), que servem para classes de abstração que não tem métodos/funções para selecionar a codificação:

  1. set character_set_results = 'utf8';
  2. set character_set_client = 'utf8';
  3. set character_set_connection = 'utf8';
  4. set character_set_database = 'utf8';
  5. set character_set_server = 'utf8'

Como usar UTF-8 no cabeçalho HTTP^

A maneira mais fácil e compatível para dizer ao navegador qual codificação você está usando é definir o charset no cabeçalho Content-Type.

No PHP, é feito da seguinte maneira:

  1. header('Content-type: text/html; charset=utf-8');

Lembrando que todo cabeçalho deve ser enviado antes de qualquer outra informação.

Como usar UTF-8 no XML (Incluindo XHTML)^

Todo XML deve ter um pseudo-elemento

Como usar UTF-8 no HTML^

O MIME Content-type do HTML tem prioridade menor que o do cabeçalho, porém existem situações que não é possível enviar cabeçalhos. Para tal, utilize o atributo content da tag meta. Para evitar problemas o ideal é setar o content-type no header e no html.

Como usar UTF-8 em requisições Ajax^

Ao enviar dados em uma requisição Ajax, é necessário dizer em qual codificação encontram-se os dados. Caso a página esteja configurada em UTF-8, as propriedades DOM .value de objetos javascript como inputs e textareas estarão em UTF-8.

  1. ajax.open('POST', caminho, !sincrona);
  2. ajax.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
  3. ajax.send(dados);

Como usar UTF-8 na hora de converter de uma codificação para outra:^

Existem funções no PHP para converter de/para iso-8859-1 e UTF-8, sendo as intrínsecas utf8_encode e utf8_decode. Porém devemos restringir o uso delas a situações bem específicas como:

  1. Para utilização de funções/class que não suportem a UTF-8;
  2. Para comunicação com outros sistemas/webservices que utilizam codificação diferente da utilizada pelo sistema/site;
  3. Para gravar em arquivos que precisam estar em codificações diferentes.

Como usar UTF-8 nas funções de string:^

Até o PHP5 o suporte à UTF-8 não é completo nas funções de string. Por exemplo a strtoupper não aceita caracteres UTF-8. Para as funções de string no PHP5 é necessário converter para ISO-8859-1 antes de usa-la e de converter novamente para UTF-8 após o uso. Como demonstrado no exemplo a seguir:

  1. $nome = 'Esse blog é bem legal!';
  2. $nome_up = utf8_encode(strtoupper(utf8_decode($nome)));
  3. echo $nome_up;

Conclusão^

Se o conceito de codificação de caracteres for entendido, e com o auxílio das ferramentas (e funções) corretas, os problemas de exibição de acentos não ocorrerão e se ocorrerem, será fácil consertá-los. Já a escolha da codificação depende do projeto e do programador.

Lembrando sempre que o correto é utilizar sempre a mesma codificação em todos os lugares, independentemente de qual ela seja.

Fontes e referências^

  • http://pt.wikipedia.org/wiki/Codifica%C3%A7%C3%A3o_de_caracteres
  • http://www.ietf.org/rfc/rfc3629.txt
  • http://en.wikipedia.org/wiki/ASCII
  • http://en.wikipedia.org/wiki/ISO/IEC_8859-1
  • http://www.w3.org/TR/unicode-xml/
  • http://en.wikipedia.org/wiki/Unicode
  • http://revolucao.etc.br/archives/usando-entities-e-referencias-numericas-de-caracteres-ncr/
  • http://www.w3.org/International/O-charset.en.php
  • http://en.wikipedia.org/wiki/UTF-8
  • http://googleblog.blogspot.com/2008/05/moving-to-unicode-51.html

Tags: básico, tutorial
Posted in Uncategorized | 2 Comments »

Sistemas Corporativos em CakePHP – Separação de Módulos

Monday, September 20th, 2010

  1. Sistemas Corporativos – A Jornada
  2. Organização e Separação de Módulos
  3. Organização de Arquivos
  4. Organização de Tabelas
  5. Alterações no Código
    1. No app_model do módulo
    2. No Model
    3. Nos Controller
    4. Nos Links
  6. Conclusão

Sistemas Corporativos – A Jornada^

Inicio neste post uma jornada de vários artigos que acompanhará minha empreitada de desenvolver Sistemas Corporativos em CakePHP, como ERPs, CRMs, etc.

Todos sabem que o CakePHP é um ótimo framework para sistemas web, bem como seu inspirador, o Rais, porém poucos usam-o para Sistemas Corporativos. Per si o CakePHP não é completamente funcional neste caso, porém felizmente ele suporta uma gama enorme de especializações como helpers, behaviors e plugins que servirão como base para implementação dos recursos necessários.

Segue abaixo algumas das funcionalidades que acho necessárias pare o uso Corporativo.

  • Organização e Separação de Módulos <- Tema deste artigo
  • Aplicação de regras de negócio avançadas nos models
  • Plataforma de portlets (widgets, gadgets)
  • Edição de tabelas filhas “inline” (helper + javascript)
  • Filtros avançados e grid dinâmico no índice, com agrupamento, sumarização, etc.
  • Histórico transacional com suporte a “dezfazer” última ação no banco de dados
  • Exportação simples do resultado do índice para CSV e PDF
  • “Rascunho” e “Lixeira” de registros
  • Helper de Suggest
  • Helper de Gráficos

Organização e Separação de Módulos^

Como Sistemas Corporativos tendem a ter mais de 100 módulos, é imprescindível que haja uma organização de arquivos de tabelas. Acredito que seja uma opinião consensual entre os desenvolvedores desse tipo de sistema.

Organização de Arquivos^

Na imagem acima, podemos perceber que existe uma pasta nova, alheia a estrutura padrão do CakePHP, chamada “modules”. Em sua essência esta pasta é idêntica a “plugins”, comportando uma estrutura nova de “controllers”, “models” e “views” bem como seu próprio “app_model” e “app_controller”. Para esta pasta funcionar, é necessário adicionar as seguinte linhas no arquivo “bootstrap.php”:

  1. App::build(array(
  2.     'plugins' => array(
  3.         APP . 'plugins' . DS,
  4.         APP . 'modules' . DS
  5.     )
  6. ));

Nota-se uma divisão semântica entre os módulos que gera uma organização modo a agrupar os que são desenvolvidos em conjunto. Adotei um padrão que, para os conceitos básicos do sistema como: países, cidades, etc. utilizando do módulo básico chamado “base” para tal.

Alguns módulos são pré-requisitos de outros, acredito que seja necessário verificar os pré-requisitos porteriorimente.

Organização de Tabelas^

Na imagem acima, podemos perceber que está sendo utilizado um prefixo nas tabelas. Este prefixo é exatamente igual ao nome do módulo no qual ela será utilizada.

Na imagem acima, a estrutura da tabela “financeiro_transacoes”, observamos que as FKs (foreign keys – chaves estrangeiras) para o próprio módulo, não utilizam novamente o prefixo do módulo, como por exemplo “transacao_tipo_id”. Já as FKs que referenciam outro módulo tem em seu nome o prefixo do módulo em questão, como a “pessoa_estabelecimento_id”, que refere-se a tabela “estabelecimento_id” do módulo “pessoa”.

Alterações no Código^

No app_model do módulo^

  1. class FinanceiroAppModel extends AppModel {
  2.     var $tablePrefix = 'financeiro_';
  3. }

Para utilizar a tabela “financeiro_transacoes” como simplesmente “financeiro” dentro do módulo, é necessário dizer para o CakePHP que aquela tabela tem aquele prefixo, como exemplificado no código acima.

É absolutamente necessário que todos os models deste módulo extendam o “FinanceiroAppModel” e não o “AppModel” para o correto funcionamento do prefixo.

No Model^

  1. class Transacao extends FinanceiroAppModel {
  2.     var $name = 'Transacao';
  3.     var $displayField = 'descricao';
  4.     var $belongsTo = array(
  5.         'TransacaoTipo' => array(
  6.             'className' => 'Financeiro.TransacaoTipo',
  7.             'foreignKey' => 'transacao_tipo_id'
  8.         ),
  9.         'TransacaoSituacao' => array(
  10.             'className' => 'Financeiro.TransacaoSituacao',
  11.             'foreignKey' => 'transacao_situacao_id'
  12.         ),
  13.         'TransacaoIrma' => array(
  14.             'className' => 'Financeiro.Transacao',
  15.             'foreignKey' => 'transacao_irma_id'
  16.         ),
  17.         'Cliente' => array(
  18.             'className' => 'Pessoa.Cliente',
  19.             'foreignKey' => 'pessoa_cliente_id'
  20.         ),
  21.         'Fornecedor' => array(
  22.             'className' => 'Pessoa.Fornecedor',
  23.             'foreignKey' => 'pessoa_fornecedor_id'
  24.         )
  25.     );
  26.     var $hasMany = array(
  27.         'TransacaoBaixa' => array(
  28.             'className' => 'Financeiro.TransacaoBaixa',
  29.             'foreignKey' => 'transacao_id',
  30.             'dependent' => false
  31.         ),
  32.         'TransacaoCentro' => array(
  33.             'className' => 'Financeiro.TransacaoCentro',
  34.             'foreignKey' => 'transacao_id',
  35.             'dependent' => false
  36.         )
  37.     );
  38. }

No código acima, nas FKs, escrevemos o prefixo da tabela na referência utilizando a sintaxe: “Modulo.Model”, como visto no exemplo.

Nos Controller^

  1. class TransacoesController extends AppController {
  2.     function index() {
  3.         $transacaoTipos = $this->Transacao->TransacaoTipo->find('list');
  4.         $transacaoSituacoes = $this->Transacao->TransacaoSituacao->find('list');
  5.         $filterOptions = $this->AdvancedFilter->filterOptions;
  6.         $transacoes = $this->paginate(null, $this->AdvancedFilter->filter);
  7.         $this->Transacao->recursive = 0;
  8.         $this->set(compact('transacoes', 'filterOptions', 'transacaoTipos', 'transacaoSituacoes'));
  9.     }

No controller, acessamos o model “Transacao” diretamente, sem utilizar o prefixo “Financeiro”.

Nos Links^

  1.     echo $this->Html->link('Transações', array('plugin' => 'financeiro', 'controller' => 'transacoes', 'action' => 'index'));

Para criar um link para um módulo, utilizamos o índice “plugin” no método “link” do helper “Html”, conforme o código acima. Ele gerará a seguinte URL:

  1.     /financeiro/transacoes/index

Conclusão^

O CakePHP é um framework extremamente versátil que possibilita organizar o código de diversas maneiras, como pudemos ver no exemplo deste artigo.

Este é o primeiro artigo da série “Sistemas Corporativos”, até a próxima.

Tags: sistemas corporativos, tutorial
Posted in Uncategorized | No Comments »

PHAR – O JAR do PHP

Friday, July 30th, 2010

  1. O que é o Phar
  2. Exemplos de uso
  3. Instalação
  4. Tutorial
    1. Habilite a escrita no php.ini
    2. Crie a aplicação de teste
    3. Gere o .php que irá criar o .phar
    4. Teste o arquivo criado, por linha de comando
  5. Configure o Apache para executar arquivos .phar
  6. Executando .phar pelo navegador sem usar o Apache.
  7. Outras Funções
  8. Referências

O que é o Phar^

Análago ao .jar do Java, o Phar é utilizado para encapsular arquivos .php e outros em um único arquivo .phar. Uma aplicação inteira pode ser distribuida e executada em um único arquivo, junto com seus arquivos de auxiliares como imagens, css, etc. Não existe ferramenta para gerar .phar, estes são gerados pela classe Phar.

Exemplos de uso^

  • Publicar sua aplicação inteira com somente um arquivo;
  • Usar como um padrão para distribuição de plugins/drivers/etc. para uma aplicação;
  • Gerar arquivos de instalação “auto-instaláveis”.

Instalação^

O Phar já vem junto com o PHP desde a versão 5.3.0. Porém, nas versões anteriores é possível instala-lo através de uma extensão, como visto no seguinte link: http://pecl.php.net/package/phar.

Tutorial^

Neste tutorial será mostrado passo-a-passo como gerar um arquivo .phar a partir de arquivos .php e como executa-lo pelo navegador.

Habilite a escrita no php.ini^

Por razões de segurança, a geração de arquivos .phar é desabilitada por padrão no php.ini. Para habilitar a geração, mude a configuração phar.readonly para Off. Em um servidor de produção não é necessário deixar essa configuração inativa.

Crie a aplicação de teste^

index.php

  1. <?php
  2. include(‘include.php’);
  3. funcao();
  4. ?>

include.php

  1. <?php
  2. function funcao() {
  3. echo ‘Sim, funciona!’;
  4. }
  5. ?>

Gere o .php que irá criar o .phar^

gera_phar.php

  1. <?php
  2. // Cria o arquivo e define o tipo dele como phar não comprimido
  3. $phar = new Phar(‘testephar.phar’, 0, ‘testephar.phar’);
  4. $phar = $phar->convertToExecutable(Phar::PHAR);
  5.  
  6. // Adiciona os arquivos index.php e include.php no testephar.phar
  7. $phar->addFile(‘index.php’);
  8. $phar->addFile(‘include.php’);
  9.  
  10. // Define o index.php como arquivo padrão ao executar
  11. $phar->setMetaData(array(‘bootstrap’ => ‘index.php’));
  12. ?>

Execute o gera_phar.php, na linha de comando ou pelo navegador:

  1. $ php gera_phar.php

Teste o arquivo criado, por linha de comando^

Agora nosso arquivo já pode ser executado por linha de comando:

  1. $ php testephar.phar

Deve retornar:

  1. Sim, funciona!

Configure o Apache para executar arquivos .phar^

Se você acessar pelo navegador o arquivo .phar agora, ele irá baixar o arquivo ao invés de interpreta-lo, portanto precisamos configurar ou Apache (ou outro Servidor Web).

Adicione a seguinte linha ao arquivo httpd.conf:

  1. AddType application/x-httpd-php .phar

Após reiniciar o Apache, o .phar já pode ser executado pelo navegador, como mostrado abaixo:

Executando .phar pelo navegador sem usar o Apache.^

É possível executar arquivos .phar pelo navegador sem alterar as configurações do Apache, basta renomear o arquivo testephar.phar para testephar.phar.php, facilitando a distribuição de aplicações.

Outras Funções^

Além do que foi visto neste artigo, o pacote .phar tem várias funções, veja algumas delas:

  • Incluir arquivos de diretórios recursivamente;
  • Diversos tipos de compactação, como: zip, tar, gzip, bz2;
  • Adicionar e excluir arquivos on-the-fly;
  • “Incluir” arquivos de dentro do .phar a partir de um .php que esteja fora;
  • Utilizar funções de tratamento de arquivos (como fopen, etc.) dentro do .phar;
  • Converter arquivos .tar.gz (ou outros) em .phar prontos para execução.

Referências^

  • http://www.php.net/manual/en/book.phar.php

Tags: phar, tutorial
Posted in Uncategorized | No Comments »

  • Sobre o Blog

    Escrito e mantido por Ariel Patschiki, Empreendedor e Desenvolvedor Web.
    Sócio da Agência Digital MobVox.
  • Últimos Posts

    • O que o PHP não tem (e que nunca terá)
    • Backup em CakePHP
    • Aplicações Desktop em PHP: WinBinder versus PHP-GTK
    • Codificação de Caracteres – ISO-8859-1 versus UTF8
    • Sistemas Corporativos em CakePHP – Separação de Módulos
  • Projetos OpenSource

    • Cake Database Backup
    • Custom Finds
  • Núvem de Tags

    backup básico cakephp comparativo funcionalidade phar sistemas corporativos tipagem tutorial
  • Blogroll

    • ActiveInfo, empresa do Finger
    • Blog do Caio
    • Blog do Ciro Feitosa
    • Blog do Daniel
    • Blog do Finger
    • MobVox
    • Neckness, b2c da Monica
    • Poppy Convites, empresa da Guid
    • Web Töten, empresa do Jefferson
  • Twitter

      @arielpts

    Copyright © 2012 - Ariel Patschiki | Entries (RSS) | Comments (RSS)