De programação

39 dicas de performance PHP

Uma boa programação faz toda a diferença no resultado de um site, principalmente quando ele possui muitos acessos, que é a intenção de 99% dos sites. Eu não poderia deixar de compartilhar estas dicas que encontrei no blog do Lucas.

  1. Se um método pode ser estático, declare-o estático. O fator de otimização é 4x+
  2. echo é mais rapido que print. Veja
  3. Prefira usar echo com múltiplo parâmetros ao invés de concatenar string
    1. echo “parametro um”, $var , “outro parametro”
  4. Defina o valor máximo do seus loops antes do for e não no for
    #onde:
    1. for($i=0;$i<count($array);$i++)
    2. #use:
    3. $max_for = count($array);
    4. for($i=0;$i<$max_for;$i++)
  5. Sempre dê unset em variáveis que não serão mais usadas, principalemente grandes arrays.
  6. Tente não usar métodos mágicos, como: __get, __set, __autoload
  7. require_once() tem custo elevado, prefira include[_once], como alertado pelo Pablo, o include_once é mais custoso que o include.
  8. Use caminhos completos em includes e requires, o PHP gastara menos tempo resolvendo os caminhos.
  9. Se você deseja descobrir quando o script começou a ser executado, $_SERVER[’REQUEST_TIME’] é melhor que time()
  10. Se você puder, use strncasecmp, strpbrk e stripos no lugar de funcões regex
  11. str_replace é mais rápida que preg_replace, mas strtr é ainda 4x mais rapida que str_replace.
  12. Se uma função, como troca de string , aceitar tanto arrays quanto caracteres unicos e a sua lista de argumentos não for muito longa, considere escrever algumas vezes o mesmo código passando um caracter por vez ao invés de uma linha passando arrays nos argumentos de pesquisa e troca.
  13. É melhor usar switch/case do que multiplos if’s e else.
  14. Usar supressão de erros com @ na frente da função é muito lento.
  15. Ative o mod_deflate do apache( modulo de compressão de resposta).
  16. Feche as conexões ao banco de dados quando você não for mais usa-lo.
  17. $row[’id’] é 7x mais rapido que $row[id]
  18. Mensagens de erros tem custo elevado, desligue-as em produção.
  19. Não use funcões dentro de loops, como:
    1. for ($x=0; $x < count($array); $x)

    A função count() é chamada em cada iteração.

  20. Incrementando uma variavel local é mais rapido.
  21. Incrementando uma variavel global é 2x mais lento que em uma variavel local.
  22. Incrementando uma propriedade ( $this->prop++) é 3x mais lento que em uma variavel local.
  23. Incrementando uma variavel local não definida é de 9x a 10x mais lento do que uma variavel local pré-inicializada.
  24. Declarando uma variável global sem usá-lo em uma função também atrasa as coisas (com aproximadamente a mesma quantidade incrementando como uma variavel local).O PHP provavelmente faz um checagem para ver se existe a nível global
  25. A invocação de métodos parece ser independente do número de métodos definidos em uma classe, em uma classe de teste onde se adicionou 10 metódos não teve mudança de performance.
  26. Métodos em classes derivadas rodam mais rápido do que aqueles definidos na classe base.
  27. Use ‘ ao invés de ” em strings quando não for preciso usar variaveis ou escapes, assim o PHP não necessita procurar e interpretar esses caracteres especiais.
  28. Prefira usar HTML puro se for possivel, scripts PHP são servidos de 2x a 10x mais lentos que equivalentes.
  29. Em cada requisição seus scripts PHP são recompilados, use uma solução de cache, isso pode te dar um ganho de 25 a 100% . Veja
  30. Quando lidando com string e você precisar verificar se a string possui certo tamanho, você entendidamente desejara usar a função strlen().
    Essa função é bastante rapida, já que ela não faz nenhum calculo, apenas retorna o tamanho ja conhecido da string disponivel na estrutura zval(estrutura interna do C usada para guardar variaveis PHP). No entanto como strlen() é uma função ela ainda assim é lenta, porque o PHP precisa fazer varias operações como lowercase e buscas na hashtable, e em seguida executar a dita função.
    Algumas vezes você podera aumentar a velocidade do seu código usando um truque com isset().
    Exemplo: Digamos que voce tem :

    if (strlen($foo) < 5) { echo “Foo is too short”; }
    1. # versus
    2. if (!isset($foo{5})) { echo “Foo is too short”; }

    Usando isset() sera mais rapido que strlen(), porque diferente de strlen(), isset() é um construtor de linguagem e não uma função, isso quer dizer que a sua execução não necessita busca na hashtable nem uso de lowercase. Virtualmente você não sobrecarga no código atual para determinar o tamanho da string.

  31. Quando incrementando ou decrementando o valor de uma variavel, $i++ normalmente é mais lenta que ++$i. Isso é especifico para PHP, ou seja, não se aplica a outras linguagens, não sai por ai modificando seu código java ou C. Isso se da porque $i++ usa 4 opcodes enquanto ++$i precisa de somente 3.
  32. Nem tudo precisa ser OOP, gera muita sobrecarga, cada chamada de método e objeto consome um monte de memória.
  33. Não implemente cada estrutura de dados como uma classe, arrays são utéis também.
  34. Não divida muito os métodos, pense bem cada código que sera reusado.
  35. Você sempre podera dividir o código no futuro, caso necessario.
  36. Faça uso das incontaveis funções pré-definidas.
  37. Se você tem muito tempo consumido por funções em seu código, considere escreva-las como extensões C.
  38. Faça Profile do seu código. Um profiler mostra quanto tempo cada parte do seu código consome. A extensão Xdebug ja contém um profiler.
  39. Excelente artigo sobre otimização PHP de John Lim (inglês)

Comentarios

Conexão ao MySQL

No php:

<?php
if ($conexao = mysql_connect("servidor","usuario","senha"))
{
if (!$banco = mysql_select_db("banco"))
{
die("Erro ao conectar ao banco: ".mysql_error());
}
} else {
die("Erro ao conectar ao servidor: ".mysql_error());
}
?>

Em asp:

<%
strConnection = "Driver={MySQL ODBC 3.51 Driver}; SERVER=servidor; DATABASE=nome_do_banco; UID=usuario; PWD=senha;"
%>

Comentarios

Página de contato em ASP.Net

Em ASP.Net, utilize o seguinte código:

Dim Msg As New System.Web.Mail.MailMessage
Msg.Fields("http://schemas.microsoft.com/cdo/configuration/smtpserver") = "mail.seudominio"
Msg.Fields("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25
Msg.Fields("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
Msg.Fields("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = 1
Msg.Fields("http://schemas.microsoft.com/cdo/configuration/sendusername") = "suaconta@seudominio"
Msg.Fields("http://schemas.microsoft.com/cdo/configuration/sendpassword") = "senha"
Msg.To = "contadodestinataria@dominio"
Msg.From = "suaconta@seudominio"
Msg.Subject = "Assunto"
Msg.Body = "Mensagem"
System.Web.Mail.SmtpMail.SmtpServer = "mail.seudominio"
System.Web.Mail.SmtpMail.Send(Msg)

Pegue o código-fonte em http://noticias.aspecto.net/aspnet/contato.aspnet.txt.

Relacionados:

Comentarios

Converter formato de data para o formato BR, em uma linha de código só

Vou pedir licença ao Frederico e também palpitar sobre a possibilidade de, em uma linha, converter o formato de data do banco (funciona para o MySQL e outros bancos) para o formato brasileiro em php.

Considerando que <?php $data = "2008-01-09 14:56:06"; ?>:
<?php echo date('d/m/Y H:m:s', strtotime($data)); ?> mostrará 09/01/2008 14:01:06.
<?php echo date('d/m/Y', strtotime($data)); ?> mostrará 09/01/2008.

Simples assim. :-)

Essa solução funciona para datas no formato yyyy-mm-dd hh:mm:ss e yyyy-mm-dd.

Publiquei em Converter formato de data para o formato BR, em uma linha de código só.

Comentario (1)

Google não ajuda a descobrir senhas de blogs

A Juliana Barreto, da Info, divulgou que o Google ajuda a descobrir senhas de blogs, especificamente o Wordpress. Outros meios de comunicação também divulgaram, mas mencionei a Info por ser um canal de renome quanto as informações de tecnologia (embora o MeioBit já se tornou o canal mais poderoso e correto em minha opinião).

Tudo não passou de uma notícia divulgada apressadamente, sem uma apuração cuidadosa do fato. Levo em conta que uma jornalista que esteja trabalhando na Info conheça algo de tecnologia, ou pelo menos sabe onde procurar informações que dêem embasamento às suas informações e notícias. Tivemos, infelizmente, uma disseminação da insegurança àqueles que utilizam o wordpress.

O Élcio, preocupado com a falta de segurança noticiada, resolveu apurar e o resultado é muito diferente do divulgado. Convido-os a visitar o Blog Fecha Tag para ver o que ele escreveu (e também convido-os a acompanhar, pois há conteúdo de primeira qualidade). De qualquer forma, peço licença a ele para copiar aqui:

Para começar, leia o trecho a seguir desta notícia na INFO Online:

Mas, quando tentou o Google, o especialista descobriu que serviço de publicação de blogs Wordpress é vulnerável a pesquisas específicas. O site armazena dados como hashes MD5, que podem conter senhas, de uma maneira visível ao buscador. Bastaria informar um trecho do algoritmo para encontrar dados relacionados ao usuário e suas senhas.

Uau, belo trabalho jornalístico esse hein? Espalhando o medo. Imagine a reação de um leigo, que tenha um um blog Wordpress, ao ler essa pérola da desinformação. Não parece, lendo esse texto, que o Wordpress tem uma seríssima falha de segurança que pode ser explorada usando o Google? Que se alguém “informa um trecho do algoritmo” vai descobrir uma porção de dados seus? Bom, fui ao site do sujeito e li o artigo em que ele explica como quebrou a senha.

O que aconteceu é que o Wordpress do tal Murdoch foi invadido por um cracker, que criou uma conta de usuário. O Wordpress guarda suas senhas em um formato chamado MD5, um formato de criptografia que transforma qualquer senha num hexadecimal de 32 caracteres, assim:

  • “Sylar” = 7bef5e9683a92c37a266283bf229c2e8
  • “Cap. Nascimento” = 40a4b69d3132bd562dc03e2de30fda3e
  • “Pat Morita” = 261f3880c4eab23075356dbc6b5befc3

O Wordpress faz isso para proteger você. Se alguém invadir seu blog, mesmo assim não vai descobrir sua senha. Então o Murdoch não tinha a senha do sujeito que invadiu o blog dele, tinha apenas o texto “20f1aeb7819d7858684c898d1e98c1bb”. O jeito comum de se descobrir essa senha é o chamado ataque de dicionário. Você consegue um enorme dicionário de palavras e nomes comuns, e faz um programa que converte cada um deles para MD5. Se, ao converter algum, você encontrar o tal texto “20f1…”, pronto, você descobriu qual é a senha.

O problema é que esses ataques levam tempo, pois o computador tem que processar milhões de palavras. E se a senha não for uma palavra comum do dicionário, ela não vai ser encontrada. Assim, “banana” vai ser encontrada, mas “Xbanana43″ não. Acontece que palavras muito, muito comuns, como “banana”, ou nomes de pessoas, provavelmente já tem seu hash MD5 publicados em alguma página na web. E, se está publicado, o Google encontra. Por exemplo, procure pelo MD5 de banana.

Então, ao procurar o MD5 da senha do invasor, o Murdoch achou páginas como essa aqui, uma lista de pessoas chamadas “Anthony”. Ele resolveu tentar então “Anthony” como senha, e funcionou.

Perceba que isso não torna o Wordpress mais vulnerável, porque a senha ia ser descoberta de qualquer maneira, só ia levar um pouco mais de tempo. E para fazer isso, o sujeito tem que ter acesso ao banco de dados com as senhas. Ou seja, já tem que ter invadido o sistema.

Foi só isso. Não há nenhuma vulnerabilidade no Wordpress que, se alguém vai ao Google e “informa um trecho do algoritmo”, vai descobrir seu CPF e número de cartão de crédito. Aliás, será que esse repórter sabe o que significa “algoritmo”? Aprendi quando era criança, quando minha mãe ouviu meu primeiro palavrão, que gente não devia usar palavras que a gente não sabe o que significa.

Você que usa Wordpress, não precisa se desesperar. Só não use senhas óbvias, não acredite em tudo o que você lê por aí e não entre em pânico.

Só lembrando: em Janeiro tem Oficina de Wordpress na Visie

(Publicado no meu Blog)

Comentario (1)

« Anteriores