Porównanie wartości, które nie są liczbami w PHP

Jeśli kiedykolwiek programowałeś w PHP, na pewno spotkałeś się z sytuacją, w której wynik porównania zaskoczył Cię. Może to było coś w stylu:

var_dump("0" == false); // true?!

I wtedy zaczyna się myślenie: „Chwileczkę… przecież ‘0’ to string, a false to wartość logiczna. Jak to możliwe, że PHP mówi, że są równe?”.

Właśnie o tym będzie ten artykuł. Dowiesz się, jak PHP porównuje wartości, które nie są liczbami, dlaczego czasem wyniki są nieintuicyjne i jak unikać błędów. Będzie prosto, po ludzku i z konkretnymi przykładami.

Czym właściwie jest „porównanie” w PHP?

W PHP porównania możesz wykonywać na różne sposoby, ale najczęściej spotkasz dwa operatory:

  • == → porównanie z konwersją typów (tzw. loose comparison),
  • === → porównanie bez konwersji typów (tzw. strict comparison).

Jeśli PHP widzi ==, to często „dopasowuje” typy, żeby je dało się porównać.
To znaczy, że jeśli porównasz string z liczbą, PHP spróbuje przekonwertować string na liczbę.

Ale kiedy porównujesz np. true i "hello", sprawa robi się ciekawa.
PHP ma swoje wewnętrzne zasady, które decydują, jak dokonać takiej konwersji — i to właśnie one prowadzą do zaskoczeń.

Jak PHP konwertuje typy podczas porównań?

Zasada ogólna:

Gdy porównujesz dwa różne typy (np. string i bool), PHP konwertuje je według ustalonej hierarchii, by móc wykonać porównanie.

Przykład 1: String vs liczba

Jeśli jeden z operandów to liczba, a drugi to string, PHP próbuje zamienić string na liczbę.

var_dump("10" == 10); // true
var_dump("10 piesków" == 10); // true (!)

W drugim przykładzie PHP patrzy na początek stringa, widzi „10”, zamienia go na 10 i ignoruje resztę.
Czyli “10 piesków”10.

Zatem: 10 == 10true.

To logiczne… ale tylko do momentu, aż natrafisz na:

var_dump("pieski" == 0); // true

Dlaczego? Bo „pieski” nie da się zamienić na liczbę, więc PHP traktuje taki string jako 0.
I wychodzi 0 == 0true.

Porównanie z wartością logiczną (true / false)

Tu robi się jeszcze ciekawiej.
Jeśli porównujesz cokolwiek z wartością logiczną (true lub false), PHP zawsze konwertuje drugą wartość do typu bool.

Przykład 2: String vs bool

var_dump("0" == false);  // true
var_dump("" == false);   // true
var_dump(" " == false);  // false
var_dump("PHP" == true); // true

Dlaczego "0" == false daje true?
Bo "0" jest traktowany jako fałsz.
Natomiast " " (spacja) to niepusty string, więc jest traktowany jako prawda (true).

To może prowadzić do bardzo nieoczywistych wyników w kodzie.

Porównanie stringów między sobą

Kiedy porównujesz dwa stringi za pomocą ==, PHP nie konwertuje ich (dopóki nie wykryje liczb na początku).
Czyli:

var_dump("abc" == "abc"); // true
var_dump("abc" == "ABC"); // false

Proste, prawda?

Ale jeśli w stringach występują cyfry, PHP może spróbować uznać je za liczby.
Na przykład:

var_dump("123" == "0123"); // true (!)

Dlaczego?
Bo oba stringi są konwertowane na liczby (123 i 123) zanim zostaną porównane.

Żeby uniknąć takiego zachowania, należy używać ścisłego porównania (===):

var_dump("123" === "0123"); // false

Tutaj PHP nie konwertuje wartości – porównuje je dokładnie, znak po znaku.

Typowe pułapki podczas porównywania nieliczbowych wartości

Pusty string i false

var_dump("" == false); // true

To może być bardzo zdradliwe, np. w warunkach:

$password = "";
if ($password == false) {
    echo "Brak hasła!";
}

Zadziała, ale gdyby $password miało wartość "0", efekt byłby taki sam — a to już może być błąd logiczny.

null kontra puste stringi

var_dump(null == ""); // true
var_dump(null === ""); // false

W pierwszym przypadku PHP uznaje, że null i pusty string to „prawie to samo” — oba są czymś „brakiem wartości”.
Ale w rzeczywistości to inne rzeczy. null to brak zmiennej lub brak wartości, a "" to po prostu pusty tekst.

Dlatego w praktyce zawsze warto używać operatora ścisłego (===).

Tablice i porównania

Z tablicami jest trochę inaczej. PHP nie konwertuje ich na liczby ani stringi.
Porównuje je element po elemencie.

var_dump([1, 2] == [1, 2]); // true
var_dump([1, 2] == [2, 1]); // false

Tu kolejność ma znaczenie.
A przy ścisłym porównaniu (===) liczy się również typ kluczy.

var_dump([1 => "a"] === ["1" => "a"]); // false

Porównanie wartości nieliczbowych w praktyce – przykłady

Zobaczmy kilka rzeczywistych scenariuszy, które mogą Cię zaskoczyć.

Przykład 1 – weryfikacja formularza

Załóżmy, że użytkownik wprowadza wartość w formularzu, np. numer telefonu.

$phone = $_POST['phone']; // może być pusty string

if ($phone == false) {
    echo "Proszę podać numer telefonu.";
}

Jeśli użytkownik wpisze "0", to warunek się spełni – a przecież "0" to niepusty string.
Rozwiązanie?

Użyj ścisłego porównania:

if ($phone === "" || $phone === null) {
    echo "Proszę podać numer telefonu.";
}

Przykład 2 – porównanie z bazą danych

Załóżmy, że pobierasz dane z bazy i chcesz sprawdzić, czy użytkownik jest aktywny.

$status = "0"; // z bazy danych (VARCHAR)
if ($status == false) {
    echo "Użytkownik nieaktywny";
}

PHP potraktuje "0" jako false, więc wszystko działa…
Ale jeśli w przyszłości kolumna zmieni się na np. "off", logika już się posypie.

Bezpieczniej porównywać ściśle:

if ($status === "0") {
    echo "Użytkownik nieaktywny";
}

Prosty skrypt do testowania porównań

Jeśli chcesz zobaczyć, jak PHP naprawdę porównuje różne wartości, możesz uruchomić ten mały eksperyment:

<?php
$values = ["0", "", " ", "abc", "10abc", 0, null, false, true];

foreach ($values as $a) {
    foreach ($values as $b) {
        echo json_encode($a) . " == " . json_encode($b) . " → ";
        var_dump($a == $b);
    }
    echo str_repeat("-", 40) . "\n";
}
?>

Ten skrypt wypisze całą tablicę wyników porównań.
Zdziwisz się, ile z nich zwróci true!

Najlepsze praktyki – jak bezpiecznie porównywać w PHP?

  1. Używaj === zamiast ==, jeśli tylko możesz.
    Dzięki temu PHP nie będzie zgadywać, co miałeś na myśli.
  2. Ręcznie konwertuj typy, jeśli naprawdę potrzebujesz porównać liczby ze stringami: if ((int)$a === (int)$b) { ... }
  3. Nie ufaj „prawdziwości” stringów"0" i "" zachowują się inaczej, niż się wydaje.
  4. Uważaj na dane z formularzy i baz danych – one są zawsze stringami, nawet jeśli wyglądają jak liczby.
  5. Testuj porównania w sytuacjach granicznych – zwłaszcza, jeśli logika warunkowa ma znaczenie dla bezpieczeństwa lub płatności.

Porównywanie wartości, które nie są liczbami w PHP, może być zdradliwe.
PHP automatycznie konwertuje typy w tle, co czasem prowadzi do niespodziewanych wyników.

Najważniejsze zasady, które warto zapamiętać:

  • ==luźne porównanie z konwersją typów,
  • ===ścisłe porównanie, bez konwersji,
  • String "0" to false, ale " " (spacja) to true,
  • Pusty string i null są różne,
  • Zawsze porównuj tablice i obiekty ściśle (===).

Bonus: mała ściągawka

Wartość 1Wartość 2OperatorWynikDlaczego
"0"false==✅ true"0" traktowane jako false
" "false==❌ falsespacja to niepusty string
""false==✅ truepusty string to false
"123abc"123==✅ truestring konwertowany do liczby
"abc"0==✅ truenie da się przekonwertować, więc 0 == 0
null""==✅ truePHP traktuje null jak pusty string
null""===❌ falseróżne typy

Porównywanie nieliczbowych wartości w PHP to temat, który na pierwszy rzut oka wydaje się prosty, ale potrafi złapać w pułapkę nawet doświadczonych programistów.
Najlepszą praktyką jest zawsze myśleć o typach danych i używać ścisłych operatorów (===, !==) wszędzie tam, gdzie to możliwe.

Szukasz taniego i dobrego hostingu dla swojej strony www? - Sprawdź Seohost.pl