quinta-feira, 21 de janeiro de 2010

[Dica]50 dicas sobre desempenho e segurança no PHP

Como devem saber, o PHP é uma linguagem de scripting “server-side“, Open-Source e bastante popular, sendo utilizada por inúmeros sites e aplicações web dinâmicas, inclusive o próprio pplware e seu fórum. O facto de ser Open-Source significa que qualquer pessoa pode contribuir para o projecto, por exemplo, consultando o seu código fonte e sugerindo possíveis correcções, optimizações e funcionalidades, ou testando e documentando o mesmo, ou mesmo compilar e construir os binários à sua medida, escolhendo as bibliotecas que deseje e alterando o código fonte do que desejar ou precisar.

peluche-php

Como qualquer linguagem de programação, esta encontra-se optimizada para se obter o maior rendimento possível das suas funcionalidades, mas cabe ao programador a decisão da abordagem que irá tomar para desenvolver a sua aplicação e chegar a um consenso entre segurança e desempenho.

Venho então trazer um conjunto de dicas e boas práticas para optimização do vosso código PHP, para melhorar o desempenho geral das vossas aplicações web. Muitas destas dicas foram confirmadas em tutoriais, apresentações e relatórios pela própria Zend (empresa que desenvolve activamente o PHP), ou em outros locais, sendo citado esses mesmos locais onde estas foram encontradas.

50 dicas sobre desempenho e segurança no PHP:


  1. A função echo é mais rápida que print. [Citação] Mas a diferença não é muito notável, sendo mais lento em algumas ocasiões. [Citação]
  2. Ao trabalhar com Strings, caso não utilize avaliação de variáveis no meio da string ( “Olá {$name} !” ), evite utilizar aspas duplas (“) e opte por aspas simples (‘) porque o PHP irá sempre procurar pela existência de variáveis em strings com aspas duplas (“string exemplo”). [Citação]
  3. Prefira usar a função sprintf ao invés de variáveis no meio de strings com aspas duplas. É aproximadamente 10x mais rápido. [Citação]
  4. Utilize múltiplos parâmetros na função echo (echo ’string1′, ’string2′ , ’string 3′ ; )em vez de concatenação de strings ( echo ’string1′. ’string2′ . ’string 3′ ; ). Note que a diferença está entre a utilização de ponto (.) – concatenação, e vírgula (,) – parâmetro. Isto apenas se refere a strings na função echo! [Citação]
  5. Evite realizar cálculos dentro de ciclos. Defina o limite máximo para os seus ciclos for antes e não lá dentro. Neste exemplo: for ($x=0; $x <>count é chamada a cada iteração do ciclo, quando o valor poderia estar ser guardado numa variável $max=count($array); antes desse mesmo ciclo. [Citação]
  6. Realize o Unset das suas variáveis ou atribua-lhes o valor NULL para libertar memória, especialmente em arrays com grandes dimensões. No caso de objectos, ambas as acções anteriores irão causar a invocação do destrutor (função __destruct()) da classe. Note que no caso da atribuição de NULL, a variável só será destruída assim que perder todas as referências para a mesma. [Citação]
  7. Evite métodos mágicos como __get, __set, __autoload. [Citação]
  8. Utilize require() / include() invés de require_once() / include_once(), pois estas últimas necessitam de verificar se o ficheiro já não foi incluído no código. [Citação]
  9. Utilize caminhos absolutos em includes e requires ao invés de caminhos relativos (../ficheiro.php) porque levam menos tempo a serem resolvidos para endereços reconhecíveis pelo sistema operativo. [Citação]
  10. require() e include() são idênticos com uma diferença: Na função require, a execução falha com erro fatal se o ficheiro estiver em falta. [Citação]
  11. Desde a versão 5 do PHP, o momento temporal em que o script iniciou a sua execução pode ser encontrado em $_SERVER[’REQUEST_TIME’]. Utilize isto em vez das funções time() ou microtime(). [Citação]
  12. Regex baseado em bibliotecas PCRE é muito mais rápido que EREG, mas se possivel recorra a funções nativas mais rápidas como strncasecmp, strpbrk e stripos. [Citação]
  13. Quando analisar XML no PHP, experimente xml2array, que faz uso das funções XML do PHP. Para HTML pode experimentar DOM document do PHP ou DOM XML na versão 4 do PHP. [Citação]
  14. str_replace é mais rápido que preg_replace, mas às vezes strtr é mais rápido que str_replace com grandes strings. Utilizar array() dentro de str_replace é usualmente mais rápido que múltiplos str_replace. [Citação]
  15. Ao contrário de outras linguagens de programação populares, declarações“else if” no PHP são mais rápidas que declarações select também conhecido como case/switch. [Citação] Com a evolução contínua do php, actualmente a diferença é muito insignificante, mas denota-se que a utilização do operador === (idêntico) nas condições if é mais rápido que a utilização do operador == (igual).
  16. Supressão de erros com @ é bastante custoso a nível de desempenho. [Citação]
  17. Para reduzir a utilização de largura de rede, active mod_deflate no Apache v2 [Citação] ou tente mod_gzip em Apache v1. [Citação]
  18. Encerre as conexões à sua base de dados quando não precisar mais delas. [Citação]
  19. Utilizar $row[’id’] é 7 vezes mais rápido que $row[id], porque se não fornecer aspas, o PHP terá que “adivinhar” qual o índice que se refere, assumindo que não seja uma constante. [Citação]
  20. Utilize as tags para declarar PHP pois todos os outros estilos encontram-se classificados como DEPRECATED, incluindo as tags curtas ( ). [Citação]
  21. Utilize códico estrito, evite supressao de erros, notificações (notices) e avisos (warnings) resultando num código mais limpo e com menos sobrecargas. Considere activar sempre error_reporting(E_ALL) (em ambiente de desenvolvimento). [Citação]
  22. Scripts PHP são gerados 2-10 vezes mais lentamente pelo httpd do Apache que uma pagina estática. Tente utilizar mais páginas estáticas em vez de scripts no servidor. [Citação]
  23. Os scripts PHP (se não utilizarem cache) são interpretados e compilados no momento e cada vez que são chamados. Instale um produto de gestão de cache do PHP (como o memcached ou eAccelerator ou Turck MMCache) para tipicamente incrementar o desepenho em 25-100% removendo o tempos de compilação. Pode também configurar eAccelerator no cPanel utilizando EasyApache3. [Citação]
  24. Uma alternativa às técnicas de cache quando se tem páginas que não mudam muito frequentemente é realizar cache do HTML produzido pelas páginas PHP. Tente Smarty ou Cache Lite. [Citação]
  25. Utilize a função isset onde possivel em lugar da função strlen. (por exemplo: if (strlen($foo) < href="http://blog.dynom.nl/archives/String-length-vs-isset-to-check-string-lengths_20070807_5.html" target="_blank">[Citação]
  26. ++$i é mais rápido que $ i++, logo utilize pre-incremento quando possível. [Citação]
  27. Faça uso das inúmeras funções predefinidas do PHP, não tente construir as suas próprias pois as nativas irão ser com certeza muito mais rápidas. Se tiver funções dispendiosas a nível temporal e recursos, considere escreve-las como extensões C ou módulos. [Citação]
  28. Crie um perfil (profile) do seu código. Um profiler revelará os consumos das variadas secções do seu código. O Xdebug debugger já contem um profiler. Profiling irá mostrar uma síntese dos gargalos existentes. [Citação]
  29. Documente o seu código! Adopte o estilo de documentação do phpdoc (semelhante a javadoc do Java), para poder utilizar sem problemas a ferramenta de geração automática de documentação do php. [Citação]
  30. Aprenda a diferença entre bom código e mau código. [Citação]
  31. Agarre-se aos padrões de programação, pois estes irão facilitar a compreensão dos códigos criados por outras pessoas e vice-versa. [Citação]
  32. Separa o código, conteúdo e apresentação: deixe o seu código PHP separado do seu HTML. [Citação]
  33. Não se preocupe em utilizar sistemas complexos de templates como Smarty, se possivel utilize funções incluídas no PHP como ob_get_contents e simplesmente puxe os dados da sua base de dados (aconselho vivamente a leitura da citação). [Citação]
  34. *Nunca* confie nas variáveis provenientes do lado do utilizador (como o $_POST) utilize mysql_real_escape_string quando recorrer ao mysql, e htmlspecialchars quando realizar output dessas mesmas variáveis para HTML. [Citação] Utilize mysql_real_escape_string em vez de mysql_escape_string (DEPRECATED) ou addslashes.[Citação]
  35. Por questões de segurança, nunca deixe algo que possa expor informação sobre caminhos, extensões e configurações, como o display_errors ou phpinfo() na sua directoria raiz (aplica-se principalmente em ambientes de produção). [Citação]
  36. Desligue as register_globals (estão desactivadas por defeito por alguma razão!). Nenhum script em ambiente de produção necessita disto activado, pois representa um enorme risco de segurança. Corrija qualquer script que necessite esta funcionalidade activa e que recorra a unregister_globals(). Faça isto o mais rapidamente possivel porque a funcionalidade será removida no PHP6. [Citação]
  37. Evite usar texto simples quando armazenar ou avaliar passwords, evitando assim qualquer exposição. Ao invés, utilize uma hash, como a hash md5 ou sha1 ou uma combinação de ambas (e se possivel e necessário, recorrendo a sal (salt)). [Citação]
  38. Utilize ip2long() e long2ip() para armazenar endereços IP como inteiros (long) ao invés de strings. [Citação]
  39. Quando utilizar header(‘Location: ‘.$url); lembre-se de colocar à frente um die(); porque o script continua a executar mesmo que a localização mude. [Citação]
  40. Em Programação Orientada a Objectos, se existir um método que possa ser estático (static method), declare-o estático. Velocidade é melhorada por um factor de 4. [Citação].
  41. Incrementar uma variável local num método de Programação OO é o mais rápido, sendo aproximadamente o mesmo que aceder a uma variável local numa função. Incrementar uma variável global é 2 vezes mais lento que uma variável local. [Citação]
  42. Incrementar uma propriedade de um objecto (eg. $this->prop++) é 3 vezes mais lento que incrementar uma variável local. [Citação]
  43. Incrementar uma variável local não definida é 9 a 10 vezes mais lento que incrementar uma variável pré-inicializada. [Citação]
  44. Somente declarar uma variável global dentro de uma função sem a utilizar têm efeitos negativos no desempenho (aproximadamente o mesmo que incrementar uma variável local), visto o PHP provavelmente verificar se a mesma já existe. [Citação]
  45. Invocação de métodos parece ser independente do número de métodos definidos na classe, porque ao adicionar 10 métodos extras na classe de teste (antes e depois do método de teste), não houve mudanças no desempenho. [Citação]
  46. Métodos em classes derivadas executam mais depressa que que os métodos nas classes base. [Citação]
  47. A chamada de uma função com um parâmetro e sem corpo (corpo vazio), leva aproximadamente o mesmo tempo que fazer 7-8 operações de incrementação de variáveis locais ($var++). Chamadas de métodos similares levam aproximadamente o tempo de 15 operações de incrementação de variáveis locais. [Citação]
  48. Nem tudo precisa de ser realizado em Programação Orientada a Objectos, pois normalmente só sobrecarrega o programa, visto as chamadas de métodos e objectos consumirem muita memória. [Citação]
  49. Evite o problema de injecção de cabeçalhos na função mail() do PHP. [Citação]
  50. RTFM! O PHP oferece um enorme e fantástico manual, sendo possivelmente um dos melhores na Internet, contendo a documentação de todas as bibliotecas em inglês simples (também disponível em português do Brasil), um conjunto de exemplos práticos e participação da comunidade com ainda mais exemplos e dicas. Simplesmente UTILIZE-O!!! [Citação]

A lista foi retirada, traduzida e adaptada de hm2k.com.

Denoto este site onde poderão verificar alguns testes simples de benchmarking onde se analisa a velocidade de diferentes funções e estruturas de decisão. Tenham em mente que os testes podem ser facilmente adulterados pela carga do servidor onde a página está alojada, sendo necessário actualizar (recarregando a página) e observar os resultados varias vezes.

Sem comentários:

Enviar um comentário