„count(): Argument must be of type Countable|array” – naprawa błędu po PHP 8
W PHP 7 tylko ostrzeżenie, od PHP 8 awaria: count() na null albo tekście. Dlaczego ten błąd tak często pojawia się po aktualizacji PHP i jak go porządnie usunąć.
W skrócie: od PHP 8.0 funkcja count() przerywa działanie błędem, gdy nie dostaje tablicy ani obiektu, który da się policzyć, tylko np. null albo tekst. W PHP od 7.2 do 7.4 było to tylko ostrzeżenie, dlatego błąd często wychodzi dopiero po aktualizacji PHP. Rozwiązanie: przed liczeniem upewnić się, że trafia tam tablica, przez ?? [] albo sprawdzenie is_countable().
Fatal error: Uncaught TypeError: count(): Argument #1 ($value) must be of type
Countable|array, null given in /var/www/html/inc/koszyk.php:41
W przeciwieństwie do wielu innych komunikatów po aktualizacji PHP to nie jest ostrzeżenie, tylko przerwanie działania. Strona pokazuje białą stronę, błąd 500 albo w WordPressie błąd krytyczny.
Dlaczego ten błąd jest tak częsty
Starszy kod PHP często zakładał, że count(null) po prostu daje 0. Było to wygodne: lista, której w ogóle nie wczytano, uchodziła za pustą. PHP 7.2 wprowadził na to ostrzeżenie, PHP 8.0 prawdziwy błąd. Kto przeskakuje od razu z PHP 7.0 albo 7.1 na PHP 8, dostaje wszystkie te błędy naraz.
Typowe miejsca
- Zapytanie do bazy albo funkcja zwraca
nulllubfalsezamiast pustej listy. - Pole formularza z wielokrotnym wyborem nie zostało wypełnione, więc nie ma go w
$_POST. - Zmienna jest tworzona jako tablica tylko w jednej gałęzi
if. - Liczony jest tekst, np. wartość z bazy jako ciąg znaków. Do tego służy
strlen(), a niecount().
Jak to naprawić
Pusta tablica jako wartość domyślna
// przed
if (count($produkty) > 0) { … }
// po
if (count($produkty ?? []) > 0) { … }
Sprawdzenie przez is_countable()
$liczba = is_countable($produkty) ? count($produkty) : 0;
is_countable() istnieje od PHP 7.3. To właściwy wybór, gdy wartość bywa raz tablicą, raz czymś innym.
Naprawa u źródła
Najczyściej jest, gdy funkcje zwracające listy zawsze zwracają tablicę, w razie potrzeby pustą. Wtedy nie każde miejsce, które liczy, musi samo uważać.
function wczytajProdukty(BazaDanych $db, int $kategoria): array
{
$lista = $db->pobierzProdukty($kategoria);
return $lista ?: [];
}
Deklaracja typu : array sprawia też, że PHP od razu zgłosi, jeśli funkcja kiedyś spróbuje zwrócić coś innego.
Sprawdzanie pustej listy bez count()
Często count() służy tylko do sprawdzenia, czy cokolwiek jest. Do tego wystarczy !empty($produkty). Działa z tablicami, null i brakującymi zmiennymi i nie zgłasza błędu. Wyjątek: przy obiektach, które da się policzyć, np. kolekcjach, empty() zwraca false, nawet gdy są puste.
W WordPressie i innych systemach
Jeśli błąd pochodzi z wtyczki albo motywu, zwykle jest to przestarzała wersja. Najpierw trzeba zaktualizować. Jeśli aktualizacji już nie ma, wtyczkę trzeba wymienić albo poprawić kod. Jak bezpiecznie przenieść stronę WordPress na nowe PHP, opisuję w artykule Zmiana wersji PHP w WordPressie.
Profesjonalna pomoc
Przenoszę starsze aplikacje PHP na PHP 8 i usuwam takie błędy u źródła, a nie tylko w miejscu, w którym akurat wyszły. Więcej w usługach naprawa błędów PHP i modernizacja starego systemu.