Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Anderson Mello

Otimizando o PHP

Recommended Posts

Otimizando o PHP

 

Introdução

O objetivo deste artigo é listar vários pontos que, quando combinados corretamente, podem ajudar em muito no desempenho de sua aplicação. É importante avaliar cada caso e aplicar somente o que for necessário. São dicas gerais de PHP, configuração do Apache e uma pequena abordagem nas instruções MySQL (e demais bancos SQL).

 

Não hesite em contribuir com outras dicas, para enriquecer o conteúdo do artigo.

Uma boa leitura ;)

 

Tópicos abordados

1. Aspas simples ou duplas?

2. Falando em aspas, não esqueça-as!

3. echo() versus print()

4. register_globals

5. Evite as magic quotes

6. Exposição do PHP

7. Interpretação de arquivos não-PHP

8. Includes e requires

9. Casting

10. Referências

11. Mensagens de erro

12. Expressões regulares

13. Otimização de instruções SQL

14. Configuração do Apache

15. Seis dicas de doze

16. Consultas de referência

 

 

1. Aspas simples ou duplas?

Strings delimitadas por aspas simples são interpretadas mais rápidas que as duplas. Isto porque as variáveis em uma string com aspas duplas são interpretadas, não necessitando a concatenação, ou seja, sempre que encontrar essa situação, o PHP vasculhará a procura de uma variável, colocando o seu respectivo valor. Ao passo que, diferentemente, as strings com aspas simples não têm suas variáveis interpretadas, sendo exibidas de forma literal.

 

1.1 Exemplo

<?php$animal = "tartaruga";echo "Aspas duplas: Eu tenho um(a) $animal de estimação.<br />";echo 'Aspas simples: Eu tenho um(a) $animal de estimação.';?>
Note que na linha onde se imprime com aspas simples é retornada o nome da variável $animal, e não o seu valor.

Qual usar? Depende muito da situação. Onde for mais cômodo, pela leitura e interpretação das variáveis, utilize aspas duplas. Em índices de arrays, argumentos e strings que não contenham variáveis, prefira as simples.

 

 

2. Falando em aspas, não esqueça-as!

Uma string pode ser utilizada num array para criar um índice associativo. Ao definir um índice sem utilizar as devidas aspas na string desse associativo, além de gerar um erro do tipo E_NOTICE (que, por padrão, o PHP não o exibe e tudo funciona normalmente), torna o processamento mais lento do que já informá-lo corretamente. O que acontece é que sem as aspas (simples, pela otimização) o PHP procura por uma constante e, não encontrado-a, assume o valor como sendo uma string, passando então a definir ou procurar pelo índice.

 

2.1 Exemplo

<?php//Esse é sete vezes mais lento...$array[indice] = 'Meu valor.';echo $array[indice];//...que este$array['indice'] = 'Meu valor.';echo $array['indice'];?>

3. echo() versus print()

Quando precisar exibir algo na tela, ecoe. Usar print() é hábito do programador. Usar echo(), também é hábito. A leve diferença de processamento está em que print() retorna (sim, retorna!) true e echo() só exibe, sem retornar nada. O print() pode ser usado também em expressões, já o echo() não. Particularmente, nunca precisei ou mesmo pensei em usá-lo desta forma, mas acabei simpatizando com o construtor :)

 

3.1 Exemplo

<?php$retorno_print = print '"Alô mundo."<br />';print "Print retornou: {$retorno_print}";?>

4. register_globals

Além de trazer questões para grandes debates sobre o seu (mal) uso e a segurança de aplicações, a diretiva register_globals, que por padrão é Off desde o PHP versão 4.2.0, causa perda de desempenho, pois o PHP é forçado a inicializar no script todas as variáveis passadas, não importando o método. Ou seja, é provável que teremos diversas variáveis ocupando memória e que muitas delas nem serão ao menos utilizadas.

 

 

5. Evite as magic quotes

As magic quotes (diretivas magic_quotes_gpc, magic_quotes_runtime e magic_quotes_sybase) também contribuem para a perda de desempenho, pois o PHP se obriga a verificar cada string passada procurando um caracter que necessita ser devidamente "escapado". Como o caso da register_globals, nem sempre precisamos escapar as strings ou todas as strings.

 

 

6. Exposição do PHP

A diretiva expose_php é responsável por permitir ou negar a exibição de informações detalhadas - phpinfo() - sobre o PHP e o servidor onde está rodando. Além de garantir uma segurança extra em não expor estes dados, desabilitar a expose_php proporciona ganho em desempenho.

 

 

7. Interpretação de arquivos não-PHP

Alguns desenvolvedores, preocupados com a segurança de suas aplicações, acabam forçando o PHP a ser interpretado com outras extensões ou, até mesmo, como uma extensão HTML. Facilmente isso pode ser feito através do arquivo de configuração do Apache - httpd.conf - ou, se disponível, através de arquivo .htaccess.

 

7.1 Exemplo - disfarçando o PHP como HTML

# Coloque a linha abaixo no seu .htaccessAddType application/x-httpd-php .htm .html
Utilizando a linha acima no seu .htaccess, será possível colocar código PHP (devidamente entre suas tags <?php e ?>) e interpretá-los normalmente num arquivo HTML, salvo com uma as extensões citadas acima. Porém, essa prática ocasiona perda de performance, já que o interpretador irá avaliar todos os arquivos HTML, mesmo que não contenha código em PHP.

 

 

8. Includes e requires

É comum utilizar arquivos que complementam o funcionamento da aplicação. Tanto os arquivos incluídos por include() ou include_once(), quanto os por require() ou require_once() têm seu desempenho otimizado quando utilizado o caminho absoluto para o(s) arquivo(s). Isto por que evita-se que o sistema de arquivos procure a referência de seu caminho.

 

8.1 Exemplo

<?php//Formato não recomendadorequire 'arquivo.php';//Mesma situação acima, porém declarando o caminho do arquivo, dentro do diretório atualrequire './arquivo.php';?>

9. Casting

A manipulação de tipos de variáveis (ou casting) não é feita de forma declarada no PHP. Ou seja, a variável inicializada terá o seu tipo definido pelo valor que possui. Porém, trabalhar com tipos diferentes dos esperado em determinadas expressões pode tornar a aplicação lenta pois, silenciosamente, o PHP converte as variáveis para o formato esperado quando utilizadas. Além disso, utilizar tipos não esperados pode comprometer a segurança em algumas instruções, como acontece com SQL injection.

 

9.1 Exemplo - casting para garantir número inteiro

<?phpif (isset($_GET['pagina'])) {	$_GET['pagina'] = (int) $_GET['pagina'];}?>

10. Referências

As referências, feitas com o operador &, são grandes aliadas na otimização de desempenho do código. Preferencialmente, devem ser usadas quando é passado um argumento grande para uma função, como um objeto retornado após a consulta a um banco de dados. Assim, evitamos criar uma cópia (desnecessária) no escopo da função, o que consume memória (liberada após a execução da função) e gera perda no desempenho.

 

10.1 Exemplo

<?php//O primeiro argumento, um objeto, é passado por referência://note o operador & antes do nome da variávelfunction geraGrade(&$objeto, $titulo) {	//... conteúdo da função}$q = mysql_query("SELECT * FROM tabela");$r = mysql_fetch_object($q);geraGrade($r);?>
No exemplo acima se não for passado o argumento por referência, o PHP irá criar uma nova variável dentro do escopo da função geraGrade(). Essa mesma situação pode ser feita em argumentos com strings ou arrays (incluindo multi-dimensionais).

 

 

11. Mensagens de erro

Essenciais para uma aplicação em desenvolvimento, as mensagens de erro ou avisos padrão do PHP, além de não instruir corretamente o usuário final, consome recurso desnecessário de um sistema em produção. Correto e otimizado é fazer o tratamento adequado dos erros e informando mensagens adequadas ao caso, abortando, se necessário, em seguida a execução do script.

 

Ocultar erros utilizando o operador @ (arroba) também causa perda no desempenho, pois as mensagens apenas não são exibidas, porém os procedimentos que necessitam atenção, ocorrem de forma silenciosa.

 

Veja mais: Tratamento de Erros

 

 

12. Expressões regulares

O PHP aceita uma grande flexibilidade nas combinações de ER, porém isso torna os processos lentos. Sempre que possível, utilize respectivas funções comuns do PHP para executar estas tarefas e o ganho em desempenho será considerável. Para determinadas tarefas, utilize:

 

- substituição: str_replace(), substr_replace(), strstr();

- busca: strpos(), stripos(), strchr(), strrchr();

- checagem por tipos: extensão CType, habilitada por padrão desde o PHP versão 4.2.0;

- comparação: strcmp(), strncascmp().

 

 

13. Otimização de instruções SQL

Esta otimização exige dois pontos de atenção: funções do PHP e instruções nativas do SGBD. Para cada tipo de banco de dados, variadas técnicas de otimização podem ser combinadas. As dicas são pra MySQL mas podem ser aplicadas na maioria dos bancos.

 

13.1 Query chaining

Quando há a necessidade de se inserir vários registros, sempre que possível monte uma única instrução e chame a função mysql_query() uma única vez. O MySQL aceita esse tipo de query a partir da versão 4.0+.

 

13.1.1 Exemplo

<?php// Neste bloco, cada laço do loop faz uma chamada à função mysql_query()for ($i = 0; $i < 30; $i++) {	mysql_query("INSERT INTO nomes VALUES('', 'Nome $i')");}//Aqui a query é concatenada e executada numa única chamada, após o loop$query = '';for ($i = 0; $i < 30; $i++) {	$query .= "INSERT INTO nomes VALUES('', 'Nome $i');";}mysql_query($query);?>
É importante considerar o tempo para a execução do script de um código como no exemplo acima, pra evitar time out. Se necessário, defina o valor padrão de 30 segundos (diretiva max_execution_time) para um maior, com a função set_time_limit().

 

 

13.2 Relacionamentos

O uso de JOINs permite simplificar e reduzir o número de chamadas de funções do PHP para consultas ao banco de dados. Porém, se mal aplicados, podem causar efeito contrário. Sempre utilize a instrução EXPLAIN (próximo item) para fazer uma avaliação e alterações necessárias, otimizando o desempenho.

 

13.3 EXPLAIN

A instrução EXPLAIN pode ser utilizada para analisar consultas e verificar se está utilizando os índices de forma apropriada. No artigo de Otimização de consultas MySQL - Parte II, de autoria do tmferreira, você pode encontrar dicas valiosas de como utilizar a instrução de forma adequada. Recomendo também a leitura da primeira e terceira parte deste mesmo artigo.

 

 

14. Configuração do Apache

O muito conhecido e utilizado servidor Apache possui várias diretivas para configurar, restringir e otimizar seu comportamento. Veremos algumas dicas para otimização de desempenho, modificando diretivas no httpd.conf.

 

14.1 MaxRequestsPerChild

Esta diretiva tem o seu valor padrão em 10000, que define o número de requisições mantidas em por um processo filho. Algumas versões do Apache, trazem esta diretiva com valor ilimitado (0 - zero), o que pode em momento ou outro causar sobrecarga. Conforme comentários do próprio httpd.conf, para plataforma Windows a diretiva é recomendada se deixar ilimitada mesmo.

 

14.2 DirectoryIndex

Essa diretiva mantém uma lista de arquivos que o Apache deve indentificar como o default da página, como, por padrão, ocorre com arquivos de nome index.html. Normalmente essa lista é incrementada, incluindo também as linguagens utilizadas pelo servidor, como o PHP. O recomendado é manter esta lista o mais enxuta possível pois, a cada requisição de listagem, o Apache irá procurar pelos arquivos (na ordem declarada).

 

14.3 .htaccess

Apesar de útil, o uso de arquivos .htaccess faz com que o Apache localize e interprete o conteúdo das configurações aplicadas a cada diretório. Em servidores onde não for necessário a utilização do .htaccess, desative no httpd.conf sua utilização, deixando o diretório raiz com AllowOverride none.

 

14.4 mod_rewrite

Se Friendly URLs não forem aplicadas, deixe o módulo mod_rewrite desabilitado. Quando utilizar o módulo, evite o exceder em expressões complexas.

 

14.5 Logs de erros

Se logs não são necesários, desabilite-os.

 

14.6 Regras de permissões

Ao utilizar regras de permissões (deny ou allow) utiliza IP no lugar de domínios. Isso previne a resolução desnecessária de nomes de domínios.

 

14.7 Links simbólicos

Use Options FollowSymLinks para simplificar o processo de acesso a arquivo no Apache.

 

14.8 Assinatura do Apache

Deixe a diretiva ServerSignature Off para ganhar desempenho. Essa diretiva exibe, nas mensagens de Not Found por exemplo (presumindo que nenhuma página de erro personalizada foi configurada através de qualquer método), a assinatura com a linha, nome e versão do Apache no rodapé das páginas.

 

 

15. Seis dicas de doze

A idéia aqui é apresentar seis dicas que não foram citadas ao longo do artigo. Estas dicas foram retiradas do artigo "12 PHP optimization tips", postada no blog de Alex Moskalyuk.

 

1. Numa classe, se um método puder ser estático, declare ele como estático;

2. Evite utilizar mágicas como __get, __set e __autoload;

3. Apesar de recomendado, require_once() consome muito recurso;

4. Se precisa pegar a hora em que o script iniciou a execução, prefira usar $_SERVER[’REQUEST_TIME’] ao invés de time();

5. Se uma função aceita tanto arrays, quanto simples variáveis (como na str_replace()), e seu conteúdo no array não for tão longo, considere utilizar algumas linhas de instruções repetidas do que, numa única linha, passar o argumento em array, que é mais lento;

6. Não utilize funções dentro de um loop, como for ($i=0; $i < count($array); $i). A função count() será chamada desnecessariamente a cada execução.

 

 

16. Consultas de referência

Alex Moskalyk - http://www.moskalyuk.com/

Ilia Alshanetsky - http://ilia.ws/

 

 

Abraços,

Anderson Mello

Compartilhar este post


Link para o post
Compartilhar em outros sites

O.o

muito bom O.o

 

tinha coisas ai que até mesmo eu duvidava ^^

 

voce merece =)

 

http://forum.imasters.com.br/public/style_emoticons/default/worshippy.gif http://forum.imasters.com.br/public/style_emoticons/default/worshippy.gif http://forum.imasters.com.br/public/style_emoticons/default/worshippy.gif http://forum.imasters.com.br/public/style_emoticons/default/worshippy.gif http://forum.imasters.com.br/public/style_emoticons/default/worshippy.gif

Compartilhar este post


Link para o post
Compartilhar em outros sites

Muito bom, mas fiquei meio encucado com a recomendação de não usar __autoload()... :( É bem mais fácil usar __autoload() do que encher de require() ou criar um arquivo de inicialização que inclua todas as classes do nosso sistema.

 

Assim que eu tiver um tempo, pesquisarei sobre o __autoload(), a fim de descobrir por que não é recomendado. Mas se alguém tiver a resposta, pode postá-la! ;)

 

Parabéns pelo artigo, Anderson! http://forum.imasters.com.br/public/style_emoticons/default/clap.gif

 

Abraços,

Beraldo

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.