10 pegadinhas PHP escondidas na linguagem

10 pegadinhas PHP escondidas na linguagemHoje vou listar 10 pegadinhas PHP que encontrei durante alguns anos de experiência, instruções que as vezes ficamos pensando “porque não funciona se fiz tudo certo!” ou “não tem lógica isso não funcionar”. Na minha caminhada de estudos para tirar a certificação acabo tendo que ler bastante o conteúdo da documentação oficial e tirando muitas dúvidas também.

 
Algumas obervações sobre o conteúdo escrito, em praticamente todos os exemplos coloquei um link para página da documentação oficial do PHP sempre pertinente ao assunto que estamos tratando no momento. Eu aconselho o leitor a frequentar constantemente o site da documentação oficial, pois só lá podemos encontrar verdades absolutas. Outro ponto que será observado nos exemplos é que estou finalizando os scripts sempre “?>”, mas somente para identificar o final do código, pois sabemos que não é indicado usar “?>” uma vez que o script só contém código PHP.
 

Listando as 10 pegadinhas PHP

1º Exemplo – Função empty()

Nesse primeiro exemplo trabalhei com a função empty() que retorna TRUE se á variável passada como parâmetro estiver vazia e FALSE caso contenha valor. Observem que na variável $valor1 atribui uma string “0” e verifiquei com a função empty(). Mesmo com o valor “0” a função retornou TRUE, isso porque a própria documentação do PHP informa que os seguintes valores são considerados vazios: 
 
– “” (string vazia)
– 0 (0 como integer)
– “0” (0 como string)
– NULL
– FALSE
– array() 
– var $var; 
 

2º Exemplo – Comparação entre diferentes tipos de dados

No segundo exemplo demonstrei uma situação que gera dúvidas constantemente nos colegas de profissão, atribui o valor “2015William” para variável $valor1 e posteriormente comparei essa variável com o valor inteiro 2015. Para nossa surpresa o PHP imprimiu que os 2 valores são iguais, isso porque conforme a documentação durante a comparação com IF o PHP avalia a string como um valor numérico e tenta converter o valor “2015William” para um tipo numérico o que resulta em 2015. Para contornar esse problema podemos usar o operador lógico “===” que compara os valores e os respectivos tipos se são iguais.
 

3º Exemplo – Função strpos()

Nesse exemplo estamos trabalhando com a função strpos() que procura a ocorrência do carácter passado como parâmetro dentro da string informada e se encontrar retorna o índice (iniciando em 0), caso não encontre retorna FALSE, aí mora o problema. Valores booleanos podem ser convertidos em valores inteiros, FALSE = 0 e TRUE = 1. No exemplo acima atribui a string “William” para variável $valor1, na comparação com IF a função strpos() encontrou o “W” mas ele está na posição “0” o que nesse caso dá problema. Na condição IF esse “0” será convertido para FALSE então foi impresso “Não achou”, para resolver recorremos novamente ao operador “===” para compara valores e tipos, nesse caso o valor “0” retornado pela função strpos() não é do tipo boolean então ele imprime “Achou”, porque “0” não é igual a FALSE.


4º Exemplo – Função isset()

Nesse exemplo estamos usando a função isset() que informa se a variável passada como parâmetro foi iniciada, se sim retorna TRUE senão retorna FALSE. Isso provoca uma certa dúvida também, porque muitas literaturas afirmam que a função isset() verifica se a variável existe, sendo que no exemplo acima é possível notar que atribui o valor NULL para variável $valor1 e na comparação com isset() foi impresso “Não Existe”, logo abaixo eu atribui um valor vazio ” para variável $valor2 na comparação foi impresso “Variável Existe”. Isso porque essa função como descrito na documentação verifica se a variável foi iniciada e NULL não é considerado um valor de inicialização.
 

5º Exemplo – Função count()

Nesse exemplo estamos trabalhando com a função count() que retorna um valor inteiro contendo a quantidade elementos em um array() ou propriedades de um objeto. O que acontece é que a função count() pode retornar 0 para um array que não foi definido e também para um array definido mas que não contem elementos, como podemos ver no exemplo acima e na documentação. Na primeira comparação será disparado um erro “Notice: Undefined variable: array”, porque não define o array antes de chamar na comparação, mas mesmo assim será impresso “Não existe” porque a função count() retornou “0”. Aparentemente podemos pensar, “mas isso vai dar erro e eu vou saber”, mas existem programadores que gostam de usar “@” antes de executar certas instruções, isso esconde a exibição dos erros no PHP e nesse caso poderia esconder o fato de estarmos usando um array que não existe.
 

6º Exemplo – Função strlen() x mb_strlen()

Nesse exemplo estou trabalhando com a função strlen() que retorna um  valor inteiro contendo o tamanho da string passada como parâmetro e se a string estiver vazia retorna 0. Até ai tudo normal pois a função strlen() funciona bem com encoding “ISO-8859-1”, mas o problema surge quando queremos saber o tamanho de uma string com encoding UTF-8 (todos meus scripts PHP, HTML estão em UTF-8) cujo conteúdo possui acentos. No exemplo acima atribui o valor “João” para variável $size1, capturei o retorno da função strlen() e foi impresso “5”, mas “João” só tem 4 caracteres, isso ocorre porque caracteres especias com acentos nesse exemplo “ã” possuem 2 bytes, já caracteres sem acentos “a” possuem apenas 1 byte, por isso foi contabilizado um carácter a mais. A solução para isso é usar a função mb_strlen() que recebe 2 parâmetros, sendo o primeiro a string a ser contada e o segundo o encoding da string, no segundo exemplo acima os 2 bytes do carácter com acento foram transformados em apenas 1 e com isso o retorno agora está correto “4”.
 

7º Exemplo – Função is_null()

Nesse exemplo estou usando a função is_null() que retorna TRUE se a variável passada como parâmetro é possuir o valor NULL e FALSE caso contrário. No exemplo podemos observar que atribui o valor ” vazio para variável $valor1 e na verificação usando a  função is_null() foi impresso “Variável não contém Null”, já no outro exemplo quando atribuo o valor NULL para variável $valor2 a função is_null() retorna TRUE e nesse caso é impresso “Variável Null”. Isso ocorre porque o valor NULL é diferente de vazio “” e no PHP NULL é considerado um tipo de dado.
 

8º Exemplo – Estrutura de Controle

Nesse exemplo não estou usando nenhuma função, e sim um exemplo com estrutura de controle nesse caso o famoso IF muito utilizado em diversas linguagem de programação. O objetivo desse exemplo é demonstrar como a falta de organização e edentação no código fonte pode gerar confusões. Os 2 exemplos imprimem o mesmo conteúdo “José”, mas foram escritos de forma diferente, isso porque no primeiro exemplo não usei os delimitadores “{}” para iniciar e finalizar a instrução IF. No PHP quando uma instrução IF executa apenas 1 linha de bloco de código podemos optar em não usar os delimitadores, mas observem que o código está mal edentado e por isso passa a impressão que as 2 instruções echo serão executadas somente se a condição IF for verdadeira. O segundo exemplo é quase idêntico ao primeiro mas coloquei o delimitadores “{}” para demarcar início e fim da instrução IF, isso deixa o código mas legível.
 

9º Exemplo – Retornando apenas 1 registro na consulta com PDO

Nesse  exemplo vou demonstrar uma particularidade da extensão PDO quando precisamos exibir apenas 1 registro de uma consulta que retorna vários. Não vou explicar toda a sintaxe sobre conexão e execução de instruções SQL com PDO pois aqui mesmo no blog já publiquei diversos artigos sobre esse assunto. Observem apenas esse trecho do exemplo acima “$dados = $stm->fetchAll(PDO::FETCH_OBJ);” onde atribuo para variável $dados todos os registros retornados pela consulta dentro de outro array, isso é possível através do comando “$stm->fetchAll“. Mas e se a necessidade fosse retornar apenas 1 registro como no segundo exemplo, observem que agora a instrução está ligeiramente diferente “$dados = $stm->fetch(PDO::FETCH_OBJ);” ao invés de usar “$stm->fetchAll” usei somente “$stm->fetch“. Esse comando retorna apenas o primeiro registro dentro de um array, mesmo que existam mais registros somente 1 é retornado, podem ler isso na documentação. Existe uma discussão na comunidade sobre o “fetchAll” se mais performático que o “fetch“, mas isso é tema para outro artigo. 
 

10º Exemplo – Concatenar string com variável

Nesse último exemplo estou demonstrando a diferença entre trabalhar com aspas duplas ” e apóstrofos ‘ na concatenação e manipulação de strings com variáveis no PHP. Observem que no primeiro exemplo atribui ‘William’ para variável $nome e em seguida com o comando echo mandei imprimir na tela ‘Meu nome é $nome’ isso tudo delimitado por apóstrofos. Foi impresso junto a string ‘$nome’ literalmente isso porque usamos apóstrofos  para delimitar, mas minha intenção era que fosse exibido o conteúdo da variável $nome. Para que a variável seja reconhecida e interpretada temos que delimitar a string com aspas duplas “, assim o PHP vai conseguir interpretar as variáveis dentro da string como mostra documentação. Existem outras características ao se usar aspas para delimitar strings, não vou abrange-las aqui, mas basicamente deixo uma dica, usem aspas somente se for necessário que o PHP interprete algo dentro da string, pois o uso do apóstrofo tende a ser mais performático uma vez que exige menos processamento do PHP na procura elementos para interpretar dentro da string.
 
Bom pessoal nesse artigo demonstrei algumas das várias pegadinhas existentes na linguagem PHP, aconselho o leitor a estudar com calma a documentação oficial nesse link. Posso garantir que algumas das situações que foram mencionadas acima já me fizeram perder horas e até dias a procura de um bug no sistema, aparentemente são comparações inofensivas onde achamos que a resposta é fácil, mas estudando mais profundamente as funções conseguimos notar algumas variações para utiliza-las.
 
Até a próxima, abraços …
Show Buttons
Hide Buttons