Warning: Undefined array key "tbm_guide_level" in /data/websites/htmlit/web/app/themes/htmlit/src/ViewModel/Post/Templates/SingleGuide.php on line 113

Warning: Trying to access array offset on value of type null in /data/websites/htmlit/web/app/themes/htmlit/src/ViewModel/Post/Templates/SingleGuide.php on line 113

Warning: Undefined array key "tbm_guide_level" in /data/websites/htmlit/web/app/themes/htmlit/src/ViewModel/Post/Templates/SingleGuide.php on line 113

Warning: Trying to access array offset on value of type null in /data/websites/htmlit/web/app/themes/htmlit/src/ViewModel/Post/Templates/SingleGuide.php on line 113

Warning: Undefined array key "tbm_guide_level" in /data/websites/htmlit/web/app/themes/htmlit/src/ViewModel/Post/Templates/SingleGuide.php on line 113

Warning: Trying to access array offset on value of type null in /data/websites/htmlit/web/app/themes/htmlit/src/ViewModel/Post/Templates/SingleGuide.php on line 113
Introduzione e primo approccio a SPL: la libreria di classi per Php 5 | HTML.it
Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Introduzione e primo approccio a SPL: la libreria di classi per Php 5

Cosa è, da cosa è composta e come può essere utilizzata la Standard Php Library (SPL): la libreria di classi per Php 5
Cosa è, da cosa è composta e come può essere utilizzata la Standard Php Library (SPL): la libreria di classi per Php 5
Link copiato negli appunti

Con l'uscita di Php 5 e le notevoli migliorie apportate al modello ad oggetti è cresciuta sempre di più la necessità di avere a disposizione degli oggetti e strutture di dati che permettessero un approccio più completo e diretto verso la programmazione ad oggetti con un linguaggio che fino ad ora era stato per lo più funzionale. I designer e gli sviluppatori di Php hanno deciso di aggiungere alla lista di funzioni compilate con la distribuzione ufficiale di Php un insieme di classi per migliorare l'approccio alla programmazione ad oggetti e potenziarne le funzionalità; questo insieme di classi è stato raggruppato all'interno della Standard Php Library (a cui d'ora in poi faremo riferimento utilizzando l'acronimo SPL) che si sta arricchendo di funzionalità a mano a mano che le versioni di Php avanzano.

In questo articolo introdurrò alcune delle classi più utili della SPL, fornendo qualche esempio pratico sul loro utilizzo. Approfondiremo le altre classi in altri articoli cercando di fornire con il tempo una panoramica più completa a questa interessante soluzione.

Struttura della libreria

Prima di affrontare qualunque esempio pratico è buona norma introdurre l'argomento che si andrà a trattare in modo complessivo. La SPL è una serie di interfacce e classi native che sono state sviluppate con lo scopo di permettere la risoluzione delle problematiche di programmazione comuni e l'implementazione di classi per l'accesso efficiente ai dati. Possiamo raggruppare le funzionalità esposte in sette gruppi principali:

  • Iteratori

  • Directory e File

  • XML

  • Array Overloading

  • Counting

  • Eccezioni

  • Observer

  • Ognuna delle classi o interfacce esposte risulta molto utile poichè l'engine di Php 5 è stato sviluppato affichè possa gestire in modo specifico oggetti che estendono determinate interfacce, rendendo così il linguaggio un po' più duttile e meno statico a livello strutturale.

    Array overloading

    Sicuramente l'overload degli oggetti per permettergli di comportarsi come se fossero array non è una delle funzionalità più importanti della SPL, ma a mio parere permette delle soluzioni implementative molto interessanti e per questo mi appresto a descriverla per prima. Questo gruppo espone fondamentalmente tre classi: ArrayObject, ArrayIterator e RecursiveArrayIterator. Le ultime due sono semplicemente delle implementazioni specifici di iteratori che permettono di effettuare cicli foreach su un ArrayObject, mentre la prima classe è quella più interessante:

    <?php
    
    class RangeObject extends ArrayObject
    {    
        private $min;
        private $max;
        private $step;
    
        public function __construct($min, $max, $step=1)
        {
            parent::__construct();
            $this->min = $min;
            $this->max = $max;
            $this->step = $step;
        }
        
        public function append($value)
        {
            throw Exception('Non possono essere aggiunti valori ad un RangeObject');
        }
        
        public function offsetExists($offset)
        {
            $o = $offset * $this->step;
            return $o <= $this->max and $o >= $this->min;
        }
        
        public function offsetGet($offset)
        {
            return $offset >= count($this) ? null : ($offset * $this->step) + $this->min;
        }
        
        public function offsetSet($offset, $value)
        {
            throw Exception('Non possono essere assegnati valori ad un RangeObject');
        }
        
        public function offsetUnset($offset)
        {
            throw Exception('Non possono essere rimossi valori da un RangeObject');
        }
        
        public function count()
        {
            return floor(($this->max - $this->min) / $this->step) + 1;
        }
    }
    
    $obj = new RangeObject(2, 23, 3);
    
    echo "Il quarto valore è: ".$obj[3]."<br />";
    echo "Il settimo valore è: ".$obj[6]."<br />";
    
    echo "Numero di elementi: ".count($obj)."<br />";
    
    ?>
    

    L'implementazione non pretende di essere utile, ma permette di creare un oggetto che si comporta come un array restituito dalla funzione range con la differenza che gli elementi vengono generati solamente quando richiesti, sia direttamente usando l'operatore [] che automaticamente all'interno di un ciclo foreach quando avremo aggiunto il supporto agli iteratori.

    Le funzioni fondamentali da implementare sono le seguenti:

    • append

    • count

    • offsetExists

    • offsetSet/offsetGet

    • offsetUnset

    • Ovviamente il parametro offset può essere sia una stringa che un numero, quindi possiamo emulare anche il comportamento di tabelle hash.

      Un breve sguardo agli iteratori

      L'iteratore è un oggetto che permette di ciclare sui singoli elementi di una collezione a cui questo fa riferimento. Vediamo prima un'implementazione che aggiunge all'ArrayObject precedente il supporto all'iterazione, poi discuteremo brevemente il funzionamento e l'utilità:

      <?php

      class RangeIterator extends ArrayIterator
      {
          private $obj;
          private $i;
         
          public function __construct(RangeObject $obj)
          {
              $this->obj = $obj;
              $this->i = 0;
          }
         
          public function current()
          {
              return $this->obj[$this->i];
          }
         
          public function key()
          {
              return $this->i;
          }
         
          public function next()
          {
              $this->i += 1;
          }
         
          public function rewind()
          {
              $this->i = 0;
          }
         
          public function seek($pos)
          {
              $this->i = $pos;
          }
         
          public function valid()
          {
              return $this->i < count($this->obj);
          }
         
      }

      class IterableRangeObject extends RangeObject
      {
          public function getIterator()
          {
              return new RangeIterator($this);
          }
      }

      $obj = new IterableRangeObject(2, 23, 3);

      foreach($obj as $key => $value)
      {
          echo $key," => ",$value,"<br/>";
      }

      ?>

      Con poche righe di codice abbiamo ottenuto un oggetto che emula un array e che può essere ciclato usando il costrutto foreach. Anche se non sembra abbiamo ottenuto un enorme vantaggio: possiamo permetterci di iterare su un range immenso senza doverci preoccupare della memoria occupata dato che i valori vengono generati solamente quando richiesti mentre l'utilizzo della funzione range avrebbe creato un array in memoria delle dimensioni necessarie. Usando approcci simili è possibile anche creare iteratori che operino su oggetti con un numero infinito o imprecisato di elementi. Se questo probabilmente non accade spesso nello sviluppo Web, in determinate applicazioni desktop potrebbe risultare molto comodo.

      In questa implementazione specifica abbiamo implementato ArrayIterator anche se il pattern standard per lo sviluppo degli iteratori in Php prevede l'implementazione dell'interfaccia Iterator per l'iteratore e di IteratorAggregate per l'oggetto che deve essere iterabile. In questo caso ArrayObject implementa già l'interfaccia richiesta. Un esempio:

      <?php

      class MyIterator implements Iterator
      {
          // ....
      }

      class MyObject implements IteratorAggragate
      {
          // .....

          public function getIterator()
          {
              return new MyIterator($this);
          }
      }

      ?>

      La SPL espone un sacco di interfacce per l'implementazione degli iteratori che permettono l'iterazione ricorsiva, l'iterazioni su Directory e l'iterazione con caching degli elementi. Comunque, tutte queste interfacce presuppongono che l'implementazione definisca i seguenti metodi:

      • current

      • key

      • next

      • rewind

      • seek

      • valid

      • Le funzioni omonime ai metodi sopra definiti possono essere utilizzate per operare su un iteratore come se questi fosse un array.

        Conclusioni

        Lo spazio è terminato e le cose da dire sono ancora moltissime. Nei prossimi articoli cercherò di trattare in modo più approfondito i vari tipi di iteratori implementabili, fornendo esempi pratici di utilizzo. Comprendere il funzionamento e l'utilità della SPL è un primo passo verso l'acquisizione della capacità di produrre codice più completo e manutenibile, nonchè un modo per sfruttare implementazioni native molto veloci di soluzioni che in caso di implementazione manuale senza appoggio dell'engine risulterebbero sicuramente più lente e macchinose. A settimana prossima.

Ti consigliamo anche