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!