PHP

Risolvere l’errore Undefined offset in PHP

In questi giorni, ho avuto la necessità di ammodernare del codice PHP scritto un po’ più di dieci anni fa; all’epoca, la versione 4 del linguaggio all’epoca ancora largamente diffusa. Per quanto ancora funzionante, le modifiche apportate a PHP hanno suggerito di intervenire per sfruttarne le innovazioni più moderne e per rimuovere il codice deprecato o, in qualche caso, addirittura rimosso. Tra le altre cose, in una classe del framework ho trovato questa funzione:

/**
 * Return the current object data. Maps to $this->getWhere().
 */function &get() //($where='', $sort='', $limitOffset=-1, $limitNumRows=-1, $assocKey=null, $force=false, $distinct=false)    
{
list($where, $sort, $limitOffset, $limitNumRows, $assocKey, $force, $distinct) = func_get_args();
  if(!isset($where)) {$where = '';}
  if(!isset($sort)) {$sort = '';}
  if(!isset($limitOffset)) {$limitOffset = -1;}
  if(!isset($limitNumRows)) {$limitNumRows = -1;}
  if(!isset($assocKey)) {$assocKey = null;}
  if(!isset($force)) {$force = false;}
  if(!isset($distinct)) {$distinct = false;}
  return $this->getWhere ($where, $sort, $limitOffset, $limitNumRows, $assocKey, $force, $distinct);    
}

Questa implementazione mi ha sorpreso, perché nel contesto dell’applicazione non ho visto la necessità di usare né una funzione Variadic, né l’overloading; ho pensato che gli autori si preparassero a un refactoring del codice introducendo un’interfaccia generica e non volessero vincolarsi a una signature precisa. Questo programma, infatti, è stato scritto nel 2009, quando per molti sviluppatori non era ancora chiaro come usare correttamente le nuove funzionalità di PHP5.

Il motivo per il quale questa funzione ha richiamato la mia attenzione è che in PHP 7 genera l’errore di tipo notice“Undefined offset” quando il numero di parametri è minore del numero di argomenti della funzione list.

L’errore “”Undefined offset”

Per quanto non ami l’uso non giustificato della funzione func_get_args, in diverse circostanze possono risolvere elegantemente problemi altrimenti complicati. Ho preferito, quindi, conservare la scelta degli autori e cercare un modo compatto di risolvere il problema senza reintrodurre la dichiarazione esplicita dei parametri. La soluzione è stata semplice: per prima cosa si definisce un array con le proprietà di default; quindi si estrae la parte che eccede il numero dei parametri e infine la si accoda a questi in un unico array.

Il risultato è:

/**
 * Return the current object data. Maps to $this->getWhere().
 */function &get() //($where='', $sort='', $limitOffset=-1, $limitNumRows=-1, $assocKey=null, $force=false, $distinct=false)    
{
  $defaultValues = array('', '', -1, -1, null, false, false);
  $args = func_get_args();
  $slice = array_slice($defaultValues, count($args));
  $fullArgs = array_merge($args, $slice);
  list($where, $sort, $limitOffset, $limitNumRows, $assocKey, $force, $distinct) = $fullArgs;
  return $this->getWhere ($where, $sort, $limitOffset, $limitNumRows, $assocKey, $force, $distinct);    
}

Non c’è più bisogno di verificare che le variabili siano effettivamente valorizzate, perché l’array su cui lavora la funzione list è completo. È richiesta una buona documentazione dei parametri e delle variabili su cui si sta lavorando, perché il codice è meno esplicativo; in compenso, questo semplice metodo risolve anche il problema dei valori di default, che func_get_args ignora, in quanto si limita a restituire una copia dei parametri ricevuti.

Conclusioni

Dopo questa semplice modifica, l’errore “Undefined offset” è definitivamente scomparso dai log. Questa tecnica si può applicare in molte situazioni simili anche per garantire la coerenza dei parametri di una funzione Variadic.

Paolo Morandotti

Professionista nel campo del software con trent'anni di esperienza, ama studiare le ricadute sociali delle tecnologie sulle quali ha realizzato vari programmi radiofonici.

Share
Published by
Paolo Morandotti
Tags: PHP errors

Recent Posts

Riflessioni sulla filatelia tematica

Gli articoli sulla filatelia tematica, vista da una prospettiva semantica e semiotica, sono elencati sotto…

2 anni ago

Da Gliwice a Grigoriopol?

Il paragone tra Gliwice e Grigoriopol è spontaneo; ma quanto è giustificato? Analizziamo i fatti…

2 anni ago

La comunicazione russa e il conflitto in Ucraina

Alcune considerazioni sulla comunicazione russa che ha preceduto il conflitto in Ucraina spingono al pessimismo.

2 anni ago

L’unità narrativa nella filatelia tematica

Definire un'unità narrativa nella filatelia tematica può rendere lo sviluppo tematico più completo e coinvolgente,…

2 anni ago

Un orologio multiuso per Delphi

TplFmxClock è il nuovo componente per Delphi rilasciato come open source da morandotti.it. Si tratta…

2 anni ago

Filatelia tematica e multimedialità

Concludiamo la serie di articoli sulla filatelia tematica affrontando una delle sfide più urgenti: quella…

2 anni ago