Configurando o PHP para exibir erros

Por questões de segurança normalmente servidores configuram o php.ini para inibir a exibição de erros (se um usuário consegue identificar um erro e tem informações sobre ele fica mais fácil explorar o problema).

Configurando pelo php.ini

No php.ini você deve ter uma chave display_errors, que provavelmente está asssim:

display_errors = Off

Para configurar pelo php.ini é só trocar o valor Off por On e todas as páginas em PHP no servidor irão printar os erros – não faça isso em produção, pelo motivo de segurança que citei acima.

 

Configurando pelo código

Considero esta a melhor opção, manter sempre o php.ini configurado para não exibir erros e configurar isso em cada aplicação em que for necessário, pois alterar o php.ini modifica o funcionamento de todos os projetos que estiverem no servidor.

Na última versão do Code Igniter (2.0) ele vem com uma variável de configuração para definir em qual ambiente o projeto está rodando: dev, homologação, produção, e isso define se os erros serão ou não exibidos.

Para configurar no código a exibição de erros e log de erros, adicione o bloco abaixo no teu código:

ini_set('display_errors', 1);
ini_set('log_errors', 1);
ini_set('error_log', dirname(__FILE__) . '/error_log.txt');
error_reporting(E_ALL);

E não se esqueça de omitir os erros quando a aplicação for para ambiente de produção! 🙂

MySQL – innoDB e MyISAM

Quando nós viramos a nova versão do And After 2011 sofremos algun dias com problemas de performance – o MySQL que rodava no servidor funcionava normalmente por algum tempo (aleatório) e o consumo de processamento subia loucamente, o site parava de responder e logo o servidor morria. Um reset, e o ciclo voltava a acontecer…

Testei alguns métodos de cache: geração de html, cache de query mas nada foi muito satisfatório – ou quando resolvia o problema prejudicava um pouco a navegação e usabilidade do site (login, publicação de comentários, etc.).

O @fefurst e um pessoal do Twitter falou para eu verificar como estavam configuradas as tabelas do meu banco e falaram para eu tentar converter para MyISAM (o atual padrão de tabelas do mysql) – mas elas já estavam neste formato.

Alterei tudo para innoDB e o problema de performance acabou – o MySQL parou de derrubar o processador e o tempo de resposta voltou ao normal, ouf!

Principais diferenças entre innoDB e MyISAM

InnoDB usa proteção por registro (row locking) enquanto MyISAM usa proteção por tabelas (table locking), por isso em tabelas que são constantemente alteradas (é o caso de algumas tabelas do And After, com as tabelas de logs, comentários, etc) o InnoDB apresenta uma melhor performance do que o MyISAM – que em outros casos é melhor que InnoDB pois não funciona com transações.

Para tabelas usadas essencialmente para consultas (como tabela de localidades, ou de usuários de um sistema fechado) o MyISAM é o mais recomendado.

Dicas de performance com MySQL

Cache

Outra dica para performance – que o Chrisimplementou aqui no And After – é verificar a existência de querys complexas na sua aplicação e pensar em alguma forma de cache para estas querys. Usamos isso na tagcloud, acompanhem a lógica para confirmar a tagcloud:

  1. Percorrer todas as tags do banco
  2. Verificar quantos posts estão associados a cada tag
  3. Ordenar as tags de acordo com o número de posts que utilizam

Essa query é um pouco lenta, tem alguns innerjoins malucos e não é legal ter ela em quase todas as telas. Uma opção é configurar o cache do próprio MySQL, outra opção (que foi o que fizemos) é transformar esta query em uma rotina e criar uma segunda tabela para a tagcloud OU adicionar uma coluna na tabela de tags que representa a relevância daquela tag (no exemplo, o número de posts que a utilizam).

Indexação de buscas

Esta aí algo que eu não posso falar muito pois ainda não tenho familiaridade: sistemas de indexação de busca. Só conheço o Lucene – sei que funciona com o Zend (EN)  e tem como fazer isso funcionar com o Code Igniter (EN) – mas para aplicações com muita informação é uma opção que deve ser considerada com carinho.

Antes de sair por aí alterando coisas em produção verifique se está tudo certo com o agendamento de backup do seu MySQL.

Referências

27 maneiras de ser um melhor programador

Hoje o @chrisbenseler twittou sobre uma apresentação chamado  27 maneiras de ser um melhor programador PHP. São apenas tópicos específicos que servem para qualquer desenvolvedor – e algumas se aplicam para outras profissões.

Vale a pena ler até o final (em inglês) e rever alguns conceitos e atitudes que temos no dia a dia e que podemos mudar a fim de melhorar nossa carreira.

Ps: se você está pensnado em comentar reclamando que está em inglês e pedindo uma tradução eu tenho uma dica que vai te ajudar em qualquer carreira: estude inglês, recomendo o Live Mocha para isso. 🙂

Reflection no PHP

O PHP5 veio com uma API inteira nova de Reflection (não vou usar a tradução por não ser usada no dia-a-dia dos programadores). Com isso, foi dada a capacidade de se observar estruturas como classes, interfaces, funções e métodos em tempo de execução (runtime).

Veja um exemplo. Para o script abaixo:

class Post extends Page {
    private $title;
    private $url;
    private $date;
    function getTitle() {
        return $this->title;
    }
    function getUrl() {
        return $this->url;
    }
    function getDate() {
        return $this->url;
    }
}
$reflection = new ReflectionClass('Post');
var_dump($reflection->getMethods());
?>

A saída será:

array(3) { [0]=> &object(ReflectionMethod)#2 (2) { ["name"]=> string(8) "getTitle" ["class"]=> string(4) "Post" } [1]=> &object(ReflectionMethod)#3 (2) { ["name"]=> string(6) "getUrl" ["class"]=> string(4) "Post" } [2]=> &object(ReflectionMethod)#4 (2) { ["name"]=> string(7) "getDate" ["class"]=> string(4) "Post" } }

Ou seja, em tempo de execução o seu script consegue identificar através do método getMethods() quais são os métodos de uma determinada classe.
As possibilidades são imensas: você pode verificar para um determinado método a sua assinatura, pode verificar se uma classe é filha de outra, se implementa uma determinada interface…

É claro, o uso de Reflection não é comum no dia-a-dia de um programador, mas no caso de sistemas que geram códigos, no uso de metadados, Reflection é a saída (e não só no PHP, esse é um conceito quem vem de outras linguagens).

Links:

Slides – Introdução ao PHP

Param quem está pensando em começar a aprender PHP o slide abaixo pode ser uma boa ajuda, outra dica é ler as referências no Manual do PHP.

Também recomendo este outro slide sobre segurança em PHP, que é uma questão que deve receber atenção de qualquer desenvolvedor.