count(null) genera un TypeError da PHP 8.0. Se lo incontri dopo un aggiornamento a PHP 8.4, non significa che il comportamento sia stato introdotto dalla 8.4: può essere un percorso applicativo che i test precedenti non avevano eseguito.
La correzione dipende dal significato di null. Se rappresenta legittimamente una lista assente, puoi normalizzarlo. Se indica un dato inatteso o una lettura fallita, trasformarlo in una lista vuota può nascondere il problema.
Cosa è cambiato nel linguaggio
Il manuale PHP di count documenta la sequenza: dalla 7.2 un tipo non valido produce un warning; dalla 8.0 viene lanciato un TypeError. Gli argomenti ammessi sono array e oggetti che implementano Countable.
$items = null;
count($items); // TypeError in PHP 8
Il messaggio identifica il valore arrivato alla funzione, non la causa che lo ha prodotto. Partirei dallo stack trace e risalirei al punto in cui quel valore viene creato o trasformato.
Definire il contratto prima della guardia
Se la funzione accetta soltanto un array opzionale e null significa “nessun elemento”, la regola può essere espressa nella firma:
function countOptionalItems(?array $items): int
{
return count($items ?? []);
}
Questa funzione restituisce zero per null e conta gli array. Un oggetto Countable non appartiene al contratto scelto. Se il dominio ammette anche quel tipo, bisogna rappresentarlo esplicitamente oppure verificare il valore con is_countable.
Non userei un cast (array) come correzione universale: una stringa diventa un array con un elemento, mentre un oggetto può essere trasformato secondo proprietà che non corrispondono agli elementi da contare. L’errore scompare, ma il risultato può restare sbagliato.
Controllare le trasformazioni nei plugin WordPress
In WordPress, la chiamata originale e il valore finale possono essere separati da filtri o wrapper. La documentazione di get_post_meta distingue il comportamento in base ai parametri e alla validità dell’identificatore. Va confrontata con gli argomenti effettivi, non con il caso più comune.
Seguirei ogni trasformazione fino a count, annotando tipo atteso e tipo osservato. Un controllo sulla sola chiamata al database può non mostrare il ramo che introduce null dopo la lettura.
Se la causa è in un plugin, verificherei versione, aggiornamenti e un caso minimo riproducibile. Un hook di mitigazione deve esistere davvero ed essere richiamato nel punto giusto: un nome plausibile copiato in functions.php non offre alcuna protezione.
Un test deve distinguere assenza ed errore
Per la funzione di esempio proverei null, array vuoto e array con elementi. Aggiungerei poi il caso applicativo che aveva prodotto il valore: metadato mancante, risposta incompleta o filtro specifico.
Se l’input non valido deve interrompere il processo, il test deve aspettarsi quell’errore. Se deve generare una risposta controllata, verificherei anche l’effetto sul risultato finale. “La pagina non va più in 500” è necessario, ma non dimostra che mostri i dati corretti.
Preferirei riprodurre il problema in una copia isolata. In produzione conserverei il dettaglio nei log protetti, evitando di mostrare errori e stack trace al visitatore. Dati e token presenti nel contesto non devono finire nei report condivisi.
Chiudere la correzione con un controllo osservabile
Dopo il rilascio confronterei errori e richieste sul percorso interessato, con finestra e denominatore dichiarati. Un errore raro può sparire nella media dell’intero sito pur continuando a colpire una funzione specifica.
Il postmortem senza colpevolizzazione serve a individuare condizioni e azioni concrete: un test mancante, un contratto ambiguo o un log insufficiente. La riga da cambiare può essere piccola; la parte utile è rendere riconoscibile la stessa classe di errore prima del prossimo rilascio.
