PHP

Programmazione a oggetti

La classe in PHP

La classe in PHP è definita usando la parola chiave class seguida da un nome identificativo e da una coppia di parentesi graffe

class Beginner {
  // Codice della classe
}

Il codice PHP, racchiuso fra le parentesi graffe di apertura e chiusura della classe, può definire costanti, variabili e funzioni. Le variabili (e le costanti) sono anche  dette proprietà mentre le funzioni sono i metodi della classe.


class Beginner {
  // Proprietà
  public $value = 1;
  // Metodi
  function printer() {
    echo 'Hello World!';
  }
}

Proprietà e metodi possono avere lo stesso nome


class Beginner {
  // Proprietà
  public $printer = "Hello World!";

  public function printer() {
     echo "Hi!";
  }
}

Un oggetto della classe si crea con la parola chiave new seguita dal nome della classe e le parentesi tonde. L’oggetto può essere assegnato a una variabile per utilizzi successivi.


new Beginner;
// Oppure se riceve argomenti
new Beginner( $arg1, $arg2, ... );
// Oppure
$obj1 = new Beginner();  

Per creare un oggetto c’è un metodo alternativo: si usa una variabile contenente il nome della classe


$classname = 'Beginner';
$obj1 = new $classname();

La pseudo variabile $this è un riferimento per l’oggetto creato con la classe ed è disponibile quando un metodo (o una proprietà) è chiamato nel contesto di quell’oggetto.


class Beginner {
  function printer() {
    if ( isset ( $this ) ) {
      echo "Hello ", get_class( $this ), "!\n";
    } else {
      echo "Hello World\n";
    }
  }
}

$obj1 = new Beginner();
// Stampa: Hello Beginner!
$obj1->printer(); 

In genere è usato dentro la classe dell’oggetto


class Beginner {
  function printer() {
    if ( isset ( $this ) ) {
      echo "Hello ", get_class( $this ), "!\n";
      $this->tasks();
    } else {
      echo "Hello World\n";
    }
  }
  function tasks() {
    echo "Your first task.\n";
  }
}

$obj1 = new Beginner();
// Stampa: Hello Beginner! Your first task.

$obj1->printer(); 

Per chiamare staticamente un metodo si usa un’istruzione formata dal nome della classe, una coppia di due punti e il nome del metodo


Beginner::printer();

Fino alla versione PHP 5.x, la variabile $this era disponibile anche nel metodo di una classe chiamato staticamente dal contesto di un altro oggetto


class Beginner {
  /* PHP 5.x: se questo metodo è chiamato staticamente 
     da un oggetto di un'altra classe, $this è disponibile */
  function printer() {
    if ( isset ( $this ) ) {
      echo "Hello ", get_class( $this ), "!\n";
    } else {
      echo "Hello World\n";
    }
  }
}

class Intermediate {
  function loader() {
    // Chiamata statica di un metodo di Beginner
    Beginner::printer();
  }
}

$obj2 = new Intermediate();
// Stampa: "Hello Intermediate!"
$obj2->loader();

Se $this è disponibile in Beginner e fa riferimento a Intermediate allora è possibile chiamare i metodi nella classe dell’oggetto obj2


class Beginner {
  function printer() {
    if ( isset ( $this ) {
      echo "Hello", get_class( $this ), "!\n";
      // Chiama il metodo dell'oggetto Intermediate
      $this->tasks();
    } else {
      echo "Hello World!\n";
    }
  }
}

class Intermediate {
  function loader() {
    Beginner::printer();
  }

  function tasks() {
    echo "Your first task.\n";
  }
}
$obj2 = new Intermediate();
// Stampa: "Hello Intermediate! Your first task."
$obj2->loader();

Il codice precedente eseguito con l’interprete PHP 7 stampa invece la frase Hello World perché il contesto è considerato incompatibile e quindi la variabile $this non è definita.

Proprietà

Le variabili presenti nel corpo della classe sono dette proprietà e sono definite con una delle seguenti parole riservate del linguaggio PHP: public, protected, private. Le parole riservate stabiliscono la visibilità, per il resto le proprietà si comportano come normali variabili e necessitano di un nome identificativo.


class Beginner {
  // Proprietà 1: visibilità pubblica
  public $prop1 = "Have a nice day!\n";
	
  public function printer() {
    echo $this->prop1;
  }
  // Proprietà 2: visibilità privata.
  private $prop2 = "Hello World\n";

  // Il codice seguente genera un errore
  // private $prop3 = $this->prop2;
  // Anche l'assegnamento con chiamata di funzione
  // genera un errore fatale.
  // private $prop4 = rand();
}

$obj = new Beginner;
$obj->printer();


L'inizializzazione della variabile deve essere sempre fatta con valori costanti. A partire dalla versione di PHP 5.3 le proprietà possono essere inizializzate anche con dati heredocs e nowdocs statici, cioè dati che non contengono valori variabili.


class Beginner {
  private $text =<<<TEXT
Hello World!\n
TEXT;

  function printer() {
    echo $this->text;
  }
}

$obj = new Beginner;
$obj->printer();

Ereditarietà fra classi

È possibile estendere una classe esistente con un'altra classe che aggiunge metodi e componenti. Questo è il concetto di ereditarietà. Si fa seguire alla parola chiave extends il nome della classe da estendere.


// Classe da estendere
class Beginner {
  public function printer( $text ) {
    echo "$text";
  }
}
// Classe derivata
class Elementary extends Beginner {
  // Aggiunge un nuovo metodo
  public function printer_ln( $text ) {
    echo "$text\n";
  }
}

$obj = new Elementary;
$obj->printer( "Hello " );
$obj->printer_ln( "World!" );

La classe da estendere è anche chiamata genitrice (in inglese parent) o base, e i suoi metodi e le sue proprietà possono essere sovrascritti nella classe derivata o figlia (in inglese child) mantenendone i nomi.


// Classe derivata: ridefinisce printer()
class Elementary extends Beginner {
  public function printer( $text ) {
    echo "\n$text";
  }
}

$obj = new Elementary;
$obj->printer( "Hello World" );

La parola chiave final impedisce che un metodo nella classe base venga ridefinito nella classe derivata. Un metodo della classe base è disponibile nella classe derivata usando la parola chiave parent:: seguita dal nome del metodo.


class Beginner {
  public function printer( $text ) {
    echo "$text";
  }

  final function printer_ln( $text ) {
    echo "$text\n";
  }
}

class Elementary extends Beginner {
  public function printer( $text ) {
    // Chiama il metodo della classe base
    parent::printer_ln( $text );
  }
  // Senza commento genera un Fatal error I
  /* public function printer_ln() {
       echo "\n";
  } */
}

$obj = new Elementary;
$obj->printer( "Hello World" );

Just another WordPress *Development* site