Už žádné psaní testovacích skriptů, když si nejste stoprocentně jistí. Už žádné zdlouhavé listování v dokumentaci. Konečně je tu tabulka pravdy PHP. Připravil jsem pro vás definitivní PHP Comparison Cheat Sheet. Je to mapa pro území, kde neplatí ===.

Protože PHP 8 v tomto ohledu přepsalo pravidla, tabulky jsou dvě:

👉 Tabulka pro PHP 8.x (Současnost, kterou musíte znát)
👉 Tabulka pro PHP 7.x (Pro legacy warriors a archeology)

Všichni jsme se naučili používat ===, abychom měli klidné spaní. Je to naše jistota. Jenže co ve chvíli, kdy nepotřebujete vědět, jestli jsou hodnoty totožné, ale která je větší nebo menší? Tady veškerá jistota končí. Pro operátory <, >, <= a >= totiž žádná „strict“ verze neexistuje. PHP v tu chvíli přebírá otěže a spouští type juggling. Víte s jistotou, jak se zachová porovnání čísla a řetězce? Nebo null a false?

Stačí se podívat do tabulky a okamžitě vidíte, jak se k sobě typy chovají, když je PHP nutí do interakce. Začíná kompletním přehledem všech operátorů včetně spaceship (<=>).

Odhalíte tiché chyby dřív, než nastanou

Uveďme si dva příklady, které vás mohou stát hodiny ladění. Různé PHP funkce používají různé strategie porovnávání. Třeba funkce sort() má jako výchozí nastavení SORT_REGULAR.

Jak se zachová u řetězců, které vypadají jako čísla, například "042" a " 42"? Jak je seřadí?

  • V tabulce si najdu sekci SORT_REGULAR
  • Podívám se na průsečík těchto hodnot.
  • Vidím symbol =
  • Co to znamená: PHP je v tomto režimu považuje za identické. Výsledné pořadí těchto prvků po seřazení bude náhodné (nedefinované). Pokud na pořadí záleží, máme problém.

A co array_unique()? „Nezkanibalizuje“ mi potichu data, když se v poli potká "042" a " 42"? Nemusíte nic zkoušet.

  • Funkce array_unique() má jako výchozí nastavení SORT_STRING
  • Podívám se na průsečík těchto hodnot.
  • Vidím symbol <
  • Co to znamená: Dopadne do dobře, hodnoty se liší (protože se vše převede na string)

Díky tabulce nemusíte hádat. Okamžitě vidíte, kdy musíte přepnout flag, aby aplikace dělala přesně to, co chcete.

(A ano, žádný flag pro striktní porovnávání bez type juggling v PHP neexistuje 😤)

Fajnšmekroviny: DateTime a Closures

Aneb co nejspíš nevíte o porovnávání objektů v PHP.

Vezměte si takový DateTime. Mnoho vývojářů má zafixováno, že objekty se porovnávat nedají, a tak data zoufale převádí na timestampy nebo formátované stringy typu 'Y-m-d H:i:s', jen aby zjistili, co nastalo dřív. Zbytečně! Třídy DateTime a DateTimeImmutable mají implementovanou logiku pro běžné porovnávací operátory. Můžete se ptát na větší/menší stejně přirozeně jako u čísel. Žádné helpery, žádné formátování, čistá syntaxe. Proto si to zasloužilo vlastní sekci DateTime v tabulce.

Ještě větší zábava začíná u rovnosti. Zatímco === je u objektů nekompromisní a zajímá ho, jestli držíte v ruce identickou instanci, operátor == je u data mnohem pragmatičtější a porovnává časovou hodnotu. Díky tomu můžete porovnat dva různé objekty, a pokud ukazují stejný čas, PHP řekne „ano, to se rovná“. A co víc – funguje to i křížem mezi DateTime a DateTimeImmutable!

A třešnička na dortu? Closures. I anonymní funkce jsou objekty. Kdy jsou dvě closures rovny? Podívejte se do tabulky!