Iniciante php PHP 15 min de leitura

Contextos Comparativos

Contextos Comparativos

Compreendendo Como o PHP Lida com Diferentes Tipos de Dados

Ao trabalhar com PHP, é crucial entender como a linguagem trata diferentes tipos de dados, especialmente ao realizar operações que esperam um tipo específico. O comportamento do PHP pode, por vezes, ser inesperado, levando a erros ou resultados que você talvez não antecipe inicialmente. Vamos explorar como o PHP "equilibra" tipos de dados e a distinção importante entre igualdade e identidade.

Erros de Tipo e Strings Não Numéricas

Se você tentar usar um valor que não é um número em uma operação matemática, o PHP lançará um TypeError. Este erro sinaliza que a operação não é suportada para os tipos de dados envolvidos e interromperá a execução do seu script.

Para exemplificar, considere este cenário:

<?php
$answer = (1 + "April 1");
?>

Este código irá gerar um TypeError porque "1º de abril" é uma string e não pode ser somado matematicamente a um inteiro. Da mesma forma, tentar somar uma string vazia a um número também resulta em um TypeError. Ao contrário de algumas outras linguagens de programação, uma string vazia não é automaticamente convertida para zero em PHP durante operações aritméticas.

Conversões Implícitas de String

PHP às vezes converte automaticamente valores para strings, mesmo quando você não o instrui explicitamente a fazê-lo. Esta conversão implícita, ou "malabarismo", ocorre em algumas situações comuns.

Primeiramente, funções como print e echo esperam que seus argumentos sejam strings. Portanto, se você passar um tipo de dado diferente, PHP o converterá para uma string. Valores booleanos, por exemplo, são convertidos para "1" para true e "" (uma string vazia) para false quando usados com essas funções. Números também são convertidos para seus equivalentes de string.

Em segundo lugar, o operador de concatenação de strings (.) requer que ambos os operandos sejam strings. Se não forem, PHP os converterá. Vamos explorar outras instâncias desse comportamento com mais detalhes no Capítulo 3.

Comparações e Manipulação de Tipos de Dados

A manipulação de tipos de dados do PHP também entra em jogo ao comparar valores de tipos diferentes. Expressões comparativas, que avaliam para verdadeiro ou falso, dependem das regras do PHP para determinar como diferentes tipos de dados devem ser tratados durante a comparação. Essas regras são acionadas por operadores de comparação como == (igual a) e > (maior que).

Identidade vs. Igualdade

O PHP distingue entre dois conceitos importantes: igualdade e identidade. Embora possam parecer relacionados, eles representam tipos diferentes de comparações. Vamos nos aprofundar nessas distinções em breve.

Distinguindo Identidade e Igualdade

Em PHP, é crucial entender a diferença entre dois operadores de comparação: == e ===. Estes operadores avaliam diferentes aspetos dos valores que estão a ser comparados. O operador === verifica a identidade, enquanto o operador == verifica a igualdade.

Comparisons de identidade usando === requerem que tanto o tipo de dado como o valor sejam os mesmos. Se os operandos forem de tipos diferentes, a comparação retorna imediatamente false. Comparação de igualdade usando ==, por outro lado, permite o "type juggling". Isto significa que PHP tentará converter os operandos para um tipo comum antes de avaliar a comparação.

Vamos ilustrar com um exemplo envolvendo uma string e um inteiro:

<?php
var_dump("1" === 1);
var_dump("1" == 1);
?>

A primeira comparação, "1" === 1, resulta em false. Isso ocorre porque um operando é uma string e o outro é um inteiro – eles são fundamentalmente tipos de dados diferentes. A segunda comparação, "1" == 1, avalia para true. PHP converte automaticamente a string "1" para o inteiro 1 antes de realizar a comparação, resultando em uma correspondência.

PHP também oferece os operadores !== e !=, que são os opostos lógicos de === e == respectivamente. Eles verificam a não-identidade e a não-igualdade.

Considere esta comparação entre um inteiro e um número de ponto flutuante:

<?php
var_dump(1 !== 1.0);
var_dump(1 != 1.0);
?>

O operador !== retorna true porque os operandos têm tipos diferentes. O operador != retorna false porque PHP converte ambos os valores para o mesmo tipo (neste caso, um float) antes de fazer a comparação.

Nota: O operador <> em PHP funciona identicamente ao operador !=. Para consistência e para alinhar com outras construções "não" em PHP (como o operador lógico !), é geralmente recomendado usar !=.

Comparações de Strings e Números no PHP 8.0 e Versões Posteriores

O PHP 8.0 introduziu uma mudança na forma como as strings e números são comparados. Ao usar o operador ==, o PHP agora realiza uma comparação numérica apenas se a string que está sendo comparada for inteiramente numérica. Se a string contiver caracteres não numéricos, o PHP volta a uma comparação de string.

Por exemplo:

<?php
var_dump(1 == "1"); // true (numeric comparison)
var_dump(1 == "1 dollar"); // false (string comparison)
?>

No primeiro exemplo, "1" é uma string totalmente numérica, então o PHP trata a comparação como numérica, resultando em true. O segundo exemplo demonstra que, quando a string contém caracteres não numéricos (como "dollar"), o PHP realiza uma comparação de string, e o resultado é false. O inteiro 1 é implicitamente convertido para a string "1" para a comparação.

Esta alteração tem uma consequência prática: espaços à esquerda ou à direita são ignorados durante comparações de strings numéricas.

Comparando Valores: Além da Simples Igualdade

Quando PHP compara valores, o tipo de dado que está sendo comparado impacta significativamente o resultado. Igualdade (==) nem sempre é tão previsível quanto pode parecer, especialmente ao lidar com diferentes tipos de dados. Por exemplo, uma string vazia ("") não é tratada como equivalente ao número zero.

var_dump(0 == "");

Este trecho de código irá gerar bool(false). Isso ocorre porque PHP tenta converter o inteiro 0 em uma string "0" para permitir a comparação. A string vazia e a string "0" são então comparadas, e são determinadas como desiguais.

Comparações Numéricas

Operadores como menor que (<), maior que (>), menor ou igual a (<=), e maior ou igual a (>=) funcionam como esperado ao comparar números.

var_dump(1 < 2);

Isto retorna bool(true), uma comparação direta. Similarmente:

var_dump(1 <= 1.01);
var_dump(2 >= 2);
var_dump(2 > 2);

produzem bool(true), bool(true), e bool(false) respectivamente.

Comparações com Tipos de Dados Mistos

Esses mesmos operadores de comparação também podem ser usados com dados não numéricos, mas as regras para avaliação se tornam mais complexas. Por exemplo, o valor booleano true é considerado maior que false e também maior que NULL.

Estes retornarão ambos bool(true).

Comparações de Strings

Strings são comparadas caractere por caractere, com a ordem das letras no alfabeto influenciando o resultado. "abc" é considerado menor que "acb".

var_dump("abc" < "acb");

retorna bool(true).

É importante notar que o PHP trata letras minúsculas como maiores que letras maiúsculas durante as comparações de strings. Portanto, "a" é considerado maior que "B".

var_dump("a" > "B");

produz bool(true).

Finalmente, strings são geralmente consideradas maiores que números. Por exemplo, "abc" é considerado maior que 123.

Regras Críticas

Retornará bool(true).

Compreendendo Comparações Contextuais em PHP

Ao realizar comparações em PHP, é importante lembrar que o comportamento da linguagem nem sempre é direto. PHP emprega o que é chamado de "manipulação de tipos", o que significa que ele converte automaticamente os tipos de dados para tornar as comparações possíveis. Isso pode levar a resultados inesperados se você não estiver ciente das regras.

Strings vs. Números

Uma situação comum surge ao comparar strings e números. Geralmente, se uma string contém apenas dígitos, o PHP a converterá em um número antes de realizar a comparação. Por exemplo:

Este código avaliará para bool(true) porque "15" é tratado como o número 15 durante a comparação. No entanto, esta conversão automática nem sempre ocorre.

Caracteres Especiais e Comparações de String

Strings que começam com caracteres especiais (como !, #, $, %, &, ', (, ), *, +, ,, -, ., ou /) são sempre consideradas menores que qualquer número. Este é um ponto crucial a lembrar.

<?php
var_dump("*77" < 5);
?>

O exemplo acima resultará em bool(true) porque a string "*77" é tratada como menor que o número 5.

Número vs. String com Números Iniciais

Quando um número é comparado a uma string que começa com números, mas também contém caracteres não numéricos, o número é convertido para uma string. A comparação então prossegue caractere por caractere.

Por exemplo, considere isto:

<?php
var_dump("1a" > 10);
?>

Isto avalia para bool(true). Eis porquê: PHP converte o número 10 para a string "10". Então, "1a" é comparado a "10". O primeiro caractere, '1', é igual. No entanto, o caractere 'a' (uma letra) é considerado maior que o caractere '0' (um dígito) na comparação de strings.

Inversamente:

<?php
var_dump("1a" > 20);
?>

Isto avalia para bool(false). O número 20 é convertido para a string "20". "1a" é então comparado a "20". O '2' em "20" é maior que o '1' em "1a", tornando a expressão geral falsa.

Melhores Práticas: Validação é a Chave

Confiar nessas regras de conversão implícitas pode facilmente introduzir bugs no seu código. É muito mais seguro validar e converter explicitamente strings para números antes de fazer comparações. Por exemplo, ao lidar com dados enviados de um formulário web (como um preço), sempre verifique se a entrada é realmente numérica antes de usá-la em cálculos ou comparações. Exploraremos técnicas para validação de dados em um capítulo posterior.

O Operador Naves Espaciais (<=>)

O PHP 7 introduziu um operador útil chamado operador naves espaciais. Este operador fornece um resultado mais granular do que os operadores tradicionais ==, !=, <, >, <= e >=. Em vez de retornar true ou false, ele retorna um inteiro:

  • 0: Se as duas expressões forem iguais após a manipulação de tipos.
  • 1: Se a primeira expressão for maior que a segunda.
  • -1: Se a segunda expressão for maior que a primeira.

Aqui está uma ilustração simples:

<?php
var_dump(11 <=> 22);
?>

Este código irá gerar int(-1), indicando que 22 é maior que 11. O operador "spaceship" pode ser particularmente útil quando você precisa determinar a ordem relativa de dois valores sem um resultado booleano simples.