sábado, 21 de janeiro de 2012

Cache de OpCodes para PHP

Sabe como diminuir o uso de memória e o tempo de resposta de suas aplicações PHP sem precisar modificar seu código? Não? E ainda tem mais! Você não precisa gastar nada para conseguir isso!

Parece bom demais para ser verdade não é mesmo? Mas existe uma ferramenta chamada APC (Alternative PHP Cache) que faz exatamente isso. O APC é uma extensão PECL que armazena e otimiza os opcodes PHP.

Os opcodes são as instruções que a máquina virtual PHP efetivamente lê. Todo código PHP que você escreve é transformado nestes opcodes e depois executado. O problema é que esse processo é feito para toda requisição recebida. Este processo é bem rápido, mas dependendo da quantidade de requisições recebidas em um determinado período (pense em algo como 500 requisições por segundo) e da capacidade de seu servidor, seus usuários vão ter de esperar cada vez mais para receber o conteúdo enviado pelo servidor.

Usando-se a ferramenta APC estes opcodes são gerados uma vez e armazenados na primeira requisição, nas próximas requisições o passo de ler o código PHP e gerar os opcodes já está feito, assim economizamos tempo e memória que seria usada na criação dos opcodes.

Se você tem o PECL instalado, a instalação do APC é bem simples. No linux execute:
#sudo pecl install apc

Eu tive um problema durante a compilação do APC e para resolver tive que também instalar o seguinte pacote:
#sudo apt-get install libpcre3-dev

Após fazer isso você pode copiar o script /usr/share/php/apc.php para uma pasta do apache. Quando você acessar este script através de seu navegador você poderá ver várias informações sobre o estado do APC no seu sistema. No menu "System Cache Entries" você pode ver quais scripts estão com seus opcodes armazenados.

Uma informação importante mostrada no apc.php é o Cache full count. Este número te diz quantas vezes o cache ficou totalmente cheio e o APC teve que excluir opcodes de scripts que estavam armazenados mas não foram acessados dentro do número de segundos estipulado por apc.ttl. Exemplo:
A página A.php está sendo acessada e o APC vai criar o cache dos opcodes para ela. Como a memória dedicada para o cache já está toda utilizada, o APC vai excluir o cache de D.php que não foi acessado nos últimos 5 segundos, estes 5 segundos estão definidos na varável de configuração apc.ttl. Você deve configurar o APC para que o Cache Full count não seja um número muito alto, pois este processo de limpar o cache frequentemente pode ter impacto na performance de seu sistema. Ou você aumenta a memória dedicada ao APC ou usa a configuração apc.filters para diminuir o número de scripts armazenados.

Espero que com esta dica vocês possam impressionar seus usuários com a velocidade de suas aplicações!

Ah sim! O APC não é a única ferramenta para cache de opcodes PHP:
http://en.wikipedia.org/wiki/List_of_PHP_accelerators

sexta-feira, 13 de janeiro de 2012

Novas características PHP 5.4 - Indireção de Arrays

Devo dizer que não me esforcei muito para me inteirar sobre as mudanças feitas na versão 5.3 da linguagem PHP. Não tive muitos problemas migrando código escrito para versões anteriores da linguagem. Os mais comuns foram warnings do tipo E_DEPRECATED causados por expressões deste tipo (dica para consertar o código: removam o "&"):
$obj =& new Class();

O uso de funções como eregi, split também passou a gerar warnings E_DEPRECATED.

Outra confissão é que eu nunca escrevi código que usa namespaces. E olha que a versão 5.3 foi lançada em junho de 2009!

Mas estou aqui para falar da vindoura versão 5.4 que possui algumas mudanças bem interessantes como a indireção de arrays. Mas o que é esta tal de indireção? Bom em inglês eles usam a palavra "dereference". Em computação é quando usamos uma referência ou endereço (pense nos ponteiros da linguagem C) para acessar e manipular um determinado valor. Em PHP quando usamos a referência $this para acessar algum membro da classe estamos fazendo uma indireção, ou seja, usando um endereço representado por $this para acessar o valor que realmente queremos seja uma varável escalar, uma instância de outra classe ou até mesmo um método.

Mas porque eu falei disso tudo? Até a versão 5.3 sempre que tínhamos uma função retornando um array nós só poderíamos acessar os valores do array usando uma varável para armazená-los, exemplo:

$meu_array = $objeto->retorna_array();
echo $meu_array[0];

Mas na versão 5.4 este código pode ficar menor:
echo $objeto->retorna_array()[0];

Agora nós podemos acessar o array diretamente na chamada do método que o criou. Acredito que o código ainda é fácil de ser entendido, pelo menos se o leitor já tiver um pouco de experiência.

Que venha o PHP 5.4!

sábado, 31 de dezembro de 2011

Documento XHTML 1.0 mínimo

Seus sites seguem os padrões web? Um jeito rápido de você saber é usando o serviço de validação do W3C (World Wide Web Consortium), o Markup Validation Service. Nele podemos validar documentos HTML e XHTML. Mas porque ter o trabalho a mais de manter os meus sites dentro dos padrões web? Bom, além de torná-lo um cidadão modelo na internet, sites que seguem os padrões web são melhores vistos por engines de busca como a google o que melhora a posição e visibilidade de seus sites. O uso de padrões também melhora a acessibilidade dos sites para pessoas com deficiências, isso é especialmente importante para sites governamentais. Outra vantagem é que com os padrões é mais fácil evitar problemas de incompatibilidades entre diferentes browsers, hoje um site tem que ser exibido corretamente em no mínimo três browsers diferentes: Firefox, Chrome e Internet Explorer. Sem contar os browsers de dispositivos móveis que são um boa parte dos acessos hoje em dia.

Eu geralmente uso XHTML 1.0 nos meus sites, e toda página servida deve uma estrutura mínima para estar dentro dos padrões. Aqui vai o exemplo:



Este documento usa o DOCTTYPE XHTML 1.0 Strict, que é bem rígido com a estrutura do documento. O DOCTYPE define os DTD (Document Type Definitions) usados para validar a sintaxe e gramática da marcação XHTML. Existem várias regras para escrever um documento xhtml válido como todas as tags tem que ser escritas com letras minúsculas, todas as tags de abertura devem ter a tag de fechamento correspondente, os atributos das tags também devem ser escritos com letras minúsculas etc.

O DOCTYPE Strict é mais indicado para páginas onde a marcação html e a apresentação são totalmente separadas através do uso de CSS. Um DOCTYPE mais flexível é o Transitional, que permite o uso de elementos em desuso, ou quando o documento mistura marcação e regras de apresentação. Neste caso o exemplo seria:



Muitas das informações neste post foram obtidas no excelente livro "Construindo sites com CSS e (X)HTML" de Maurício Samy Silva.

Quer você use XHTML ou HTML eu acho muito importante seguirmos os padrões web, desta forma sempre estaremos tornando a web um lugar melhor.

domingo, 18 de dezembro de 2011

Como escrever javascript com PHP?

Quem já tem alguma experiência com desenvolvimento web já deve ter passado pela experiência de escrever código javascript usando código PHP. A técnica é bem interessante e poderosa, pois você está gerando código javascript dinamicamente usando PHP que também é uma linguagem dinâmica, Batman e Robin ficariam orgulhosos.

Aqui vai um exemplo: Você tem um site bastante visitado e que usa bastante ajax para evitar recarregar toda a página para cada ação do usuário. Mas e que tal você economizar até nas chamadas ajax? Supondo aquela situação básica onde o usuário do site escolhe uma opção em um select e algum lugar da página é recarregado automaticamente de acordo com a opção escolhida. Supondo ainda que as informações envolvidas não mudem com muita frequência, vamos fazer com todas as informações já estejam na página permitindo o código javascript carregar as informações na página sem uma requisição ajax.



O código simplesmente preenche o input "sentimento_cor" de acordo com a cor escolhida no select. Como vocês podem ver estou preenchendo o array javascript "sentimentos_cores" com os valores vindos do array PHP "sentimento_cores". Desta forma a função "mostra_sentimentos" vai somente pegar o valor do input diretamente do array javascript sem a necessidade de uma requisição ajax.

Até aí tudo bem. No entanto se você testar este código vai perceber que um erro javascript vai aparecer logo de cara na seguinte linha:
sentimentos_cores.push("depressão, luto e "escuridão"");
Como a palavra escuridão está entres aspas duplas estas se misturaram com as aspas duplas do código javascript formando um comando inválido. O problema aqui foi que nós não escapamos a saída javascript. E como já comentei em um artigo anterior não escapar a saída pode trazer sérios problemas para sua aplicação web.

E como escapamos a saída javascript? Muito simples, a linguagem PHP já possui uma função que faz isso, embora o nome da função não seja óbvio, a função json_encode. Assim o trecho onde a PHP gera o código javascript ficaria assim:



Agora vá e observe a saída gerada pela linguagem PHP:



As aspas foram escapadas e os acentos foram convertidos para uma representação unicode. Na verdade nós poderíamos ter simplificado o código usando a função json_encode diretamente no array PHP o teria gerado a seguinte string:

["al\u00edvio e paz","amor e paix\u00e3o","depress\u00e3o, luto e \"escurid\u00e3o\""];

Esta string é código javascript, e pode ser usado diretamente no código javascript da página:



Espero que este post seja útil para quem estiver usando PHP para gerar javascript, até a próxima!

segunda-feira, 28 de novembro de 2011

Sobre como montar árvores armazenadas em bancos de dados relacionais

Sumário: Neste post vou falar sobre como montar a árvore de relacionamentos de uma estrutura hierárquica armazenada em uma tabela de um banco de dados relacional, e em seguida aplicar isso na exibição de um select(html) onde os relacionamentos entre pais e filhos são demonstrados. Download de código de exemplo no final do post.

Em um projeto que ajudo a desenvolver no trabalho, um CMS, temos uma tabela no banco de dados chamada Páginas. Esta tabela armazena informações sobre as página de um site, estas páginas indicam cada local de conteúdo de um site, como Home, Busca, Notícias, etc. Acontece que as páginas são inter-relacionadas, ou seja, a página Home pode ser pai da página Notícias e a página Notícias pode ser pai da página Destaques. A estrutura simplificada da tabela Página é a seguinte:
Tabela Páginas
id nome id_pagina_pai

1

Home

null

2

Notícias

1

3

Destaques

2

4

Busca

1

5

Menu

null

Como vocês podem ver a coluna id_pagina_pai é uma referência a coluna id da mesma tabela, por exemplo, olhando no registros da tabela podemos ver que a página Destaques é filha de Notícias.

Este tipo de estrutura hierárquica é muito comum em muitos softwares e sistemas e no dia-a-dia como relações familiares, grupos e sub-grupos, sistemas de arquivos com suas pastas e sub-pastas e muitos outros. Acontece que bancos de dados relacionais não são as melhores ferramentas para armazenar e manipular estes tipos de informações. Por exemplo, como faríamos para exibir a estrutura da tabela de Páginas mostrada acima em um select html da seguinte forma?:



No código exemplo que pode ser obtido abaixo eu demonstro a forma que eu encontrei para fazer isso. Provavelmente não é a melhor forma, mas resolveu meu caso muito bem. Só lembrando que em bancos de dados como Oracle e Postgre existem recursos como queries recursivas que ajudam na hora de manipular dados hierárquicos. No exemplo estou usando o banco de dados Mysql.

A Função que faz a Mágica
O principal trecho do código é função create_pool_tree, reproduzida abaixo:


Esta função basicamente cria toda a árvore que está armazenada na tabela paginas usando referências dentro de um array. Um pouco difícil de entender? Vamos por partes:

O primeiro foreach do código basicamente pega todas as páginas e as coloca em um array com uma estrutura pré-preparada. A imagem abaixo vai ilustrar o processo tomando como exemplo os dados da tabela Páginas acima:
Array $pool

Cada quadrado destes é um elemento do array $pool. Os nomes Home1, Noticias2, Destaques3, Busca4 e Menu5 são os índices. O índice pagina dentro de cada item é o objeto pagina. E filhas é um array vazio por enquanto.

O próximo foreach vai criar referências onde cada item de $pool vai ser referenciado por uma referência no array filhas de seu pai que também está em $pool. Complicado? A figura abaixo deve ajudar:
Array $pool com as refrências.

Vejam que todos os elementos estão no array e como as referências nos permitem saber a estrutura da árvore. Observem como Home e Menu não são referenciados por ninguém, o que significa que são os nós raízes da árvore.

O link para download do código exemplo está logo abaixo. São apenas dois arquivos, um de código php e outro com o banco de dados exemplo. Acho que o código não deve ser muito difícil de se adaptar para as necessidades de cada um. Qualquer dúvida, sugestão ou crítica sou todo ouvidos.


segunda-feira, 14 de novembro de 2011

Mais um pequeno Jogo que desenvolvi - DarkMatters

Link para o jogo

ScreenShot:


Um pequeno jogo desenvolvido usando Flixel e a biblioteca Flixel Power Tools, usada pelo método de colisão usando a transparência dos sprites. Devo dizer que demorei muito mais tempo do que eu imaginava para finalizar este game, e é um jogo bem simples, mesmo!

sábado, 29 de outubro de 2011

Escapar saída htm em PHP

Você está escapando a saída de todo o conteúdo inseguro nos seus scripts PHP? E por conteúdo inseguro eu digo tudo o que não for interno da aplicação como qualquer informação enviada pelos usuários, dados de outros servidores, webservices, banco de dados etc.

Uma boa notícia é que se você usa algum dos modernos frameworks php (Code Igniter, Symfony, Cake PHP) corretamente ele provavelmente já está cuidando disso para você, mas é bom você checar só por precaução. O problema é que muitos de nós desenvolvedores PHP temos sites ou sistemas que já tem um bom tempo de estrada e não usam nenhum framework.

Agora, você deve estar se perguntando, o que é este negócio de escapar a saída (output escape)?! Bem, como você deve saber desde os primórdios da internet a principal função de um browser web é exibir documentos html. E um documento html nada mais é do que um arquivo de texto, formado por tags html e texto puro. Aqui vai um exemplo de um típico trecho de um documento html:


Como você pode ver neste trecho de html temos um pouco texto comum, mas também temos as nossas famosas tags. As tags nada mais são do que comandos para o browser. Insira um imagem aqui, uma parágrafo aqui e crie uma div neste ponto...

Como o browser identifica estas tags? Através de caracteres especiais como < e >. Existem alguns outros caracteres importantes como ', " e &. E o que isso tem a ver com escape de saída? Bom imagine que em um blog um dos usuários insira um comentário com um conteúdo como este:


O que você acha que vai acontecer? Bom o browser de qualquer visitante que exibir este comentário vai executar o que quer que esteja no script perdeu_mane.js. Podem ser ações desde de redirecionar o usuário, exibir anúncios, quebrar o layout do site, roubar senhas e cookies, e até mesmo fazer com que usuários logados com previlégios de administrador executem ações no site. Isso meu amigo, é o famoso ataque XSS(Cross-site Scripting).

Escapar a saída nada mais é do que exibir aqueles caracteres especiais de uma forma representativa fazendo com que o browser não execute nenhuma ação disparada por tags. Neste caso < e > são escritos como &lt; e &gt;.

Uau! E como eu faço isso? Bom, escapar exibição de html em PHP não é particularmente difícil.
Exibir texto simples em uma página web:


Exibir text simples dentro de uma tag html:


Se você sempre usa aspas-duplas " nas suas tags, como por exemplo <input type="text" name="nome aqui" /> você pode usar ENT_COMPAT ao invés de ENT_QUOTES. ENT_COMPAT diz para a função transformar apenas as aspas-duplas, ENT_QUOTES vai transformar tanto aspas-duplas quanto aspas-simples.

Importante! Quando escapar a saída?
Você deve estar pensando que ao invés de ficar sempre chamando a função htmlspecialchars na hora de exibir o conteúdo você pode chamá-la apenas uma vez na hora de salvar o conteúdo? Talvez não seja uma boa ideia, hoje em dia é muito provável que você não vai exibir seu conteúdo apenas em páginas html, você também tem rss, json, csv, arquivos texto, emails e outras opções. Para cada uma destas opções de exibir conteúdo o processo de escape é diferente. Se você quiser salvar processamento você pode armazenar uma versão inalterada do conteúdo junto com versões já escapadas de acordo com sua necessidade.

Por enquanto é isso pessoal, espero que o artigo seja útil a vocês.
 
BlogBlogs.Com.Br