Capitolo 18. Classi e Oggetti (PHP 4)

Classi

Una classe � una collezione di variabili e funzioni che utilizzano queste variabili. Una classe si definisce usando la seguente sintassi:

<?php
class Cart {
    var 
$items;  // Articoli nel carrello
   
    // Aggiunge $num articoli di $artnr nel carrello
 
    
function add_item ($artnr$num)  {
        
$this->items[$artnr] += $num;
    }
   
    
// Prende $num articoli di $artnr e li rimuove dal carrello
 
    
function remove_item ($artnr$num) {
        if (
$this->items[$artnr] > $num) {
            
$this->items[$artnr] -= $num;
            return 
true;
        } elseif (
$this->items[$artnr] == $num) {
            unset(
$this->items[$artnr]);
            return 
true;
        } else {
            return 
false;
        }   
    }
}
?>

Il codice definisce una classe chiamata Cart composta da un array associativo che archivia gli articoli nel carrello e due funzioni per aggiungere e rimuovere gli articoli dal carrello stesso.

Avvertimento

NON spezzate una definizione di classe in pi� file o in pi� blocchi PHP. Si pu� anche EVITARE di spezzare la definizione di una classe in pi� blocchi PHP, a meno che la suddivisione non sia all'interno della dichiarazione di un metodo. Il seguente codice non funziona:

<?php
class test {
?>
<?php
    
function test() {
        print 
'OK';
    }
}
?>

Tuttavia � permessa la seguente struttura:

<?php
class test {
    function 
test() {
        
?>
        <?php
        
print 'OK';
    }
}
?>

Le seguenti note cautelative sono valide per PHP 4.

Attenzione

Il nome stdClass � usato esclusivamente da Zend ed � riservato. Non � quindi possibile creare una classe chiamata stdClass in PHP.

Attenzione

I nomi di funzione __sleep e __wakeup sono riservati e magici nelle classi PHP. Non � possibile creare funzioni con questi nomi nelle classi definite dall'utente, a meno che non sia desiderata la funzionalit� magica connessa a questi nomi. Si veda sotto per avere pi� informazioni.

Attenzione

PHP riserva tutti i nomi di funzione che iniziano con __ a funzioni magiche. Si suggerisce di non usare nomi di funzioni che utilizzano con i caratteri __ in PHP a meno che non si desideri implementare una funzionalit� magica.

In PHP 4, sono permesse inizializzazioni di variabili con valori costanti solamente grazie all'uso di var. Per inizializzare variabili con valori non-costanti, bisogna creare una funzione d'inizializzazione che � chiamata automaticamente all'istanziazione di un oggetto da una classe. Questo tipo di funzione si chiama costruttore (vedi sotto).

<?php
class Cart {
/* questo non funziona in PHP 4. */
    
var $todays_date date("Y-m-d");
    var 
$name $firstname;
    var 
$owner 'Fred ' 'Jones';
    
/* E' permesso l'uso di matrici contenenti costanti */
    
var $items = array("VCR""TV");
}

/* Questo � corretto. */
class Cart {
    var 
$todays_date;
    var 
$name;
    var 
$owner;
    var 
$items;
    var 
$items = array("VCR""TV");
    function 
Cart() {
        
$this->todays_date date("Y-m-d");
        
$this->name $GLOBALS['firstname'];
        
/* etc ... */
    
}
}
?>

Le classi sono tipi del linguaggio, e sono modelli per variabili reali. Per creare una variabile oggetto si usa l'operatore new.

<?php
$cart 
= new Cart;
$cart->add_item("10"1);

$another_cart = new Cart;
$another_cart->add_item("0815"3);
?>

Il codice sopra, genera gli oggetti $cart e $another_cart, dalla classe Cart. La funzione add_item() dell'oggetto $cart � chiamata per aggiungere una ricorrenza dell'articolo numero 10 a $cart. Ad $another_cart sono aggiunte 3 ricorrenze dell'articolo numero 0815.

Sia $cart che $another_cart dispongono delle funzioni add_item(), remove_item() e della variabile $items, ma per ogni oggetto queste sono funzioni e variabili sono distinte. Potete pensare agli oggetti come a qualcosa di simile alle directories di un filesystem. In un filesystem si possono avere due diversi files README.TXT, purch� siano in directories differenti. Cos� come in un filesystem dovete digitare il nome (percorso) completo per raggiungere un determinato file partendo da una directory toplevel, cos� dovete specificare il nome completo di una funzione o variabile che desiderate richiamare da un oggetto. Per PHP, la directory toplevel � il namespace globale dell'oggetto ed il separatore del pathname (/) � ->. Cos� $cart->items e $another_cart->items sono due diverse variabili che differiscono per il nome. Si noti che la variabile si chiama $cart->items, e non $cart->$items, questo perch� le variabili il PHP si scrivono con un unico simbolo di dollaro.

<?php
// corretto con un singolo $
$cart->items = array("10" => 1); 

// non valido, perch� $cart->$items diventa $cart->""
$cart->$items = array("10" => 1);

// corretto, ma non sempre pu� funzionare:
// $cart->$myvar diventa $cart->items
$myvar 'items';
$cart->$myvar = array("10" => 1);  
?>

Quando si definisce una classe, non � possibile prevedere quale nome avr� l'oggetto istanziato nel programma. Quando la classe Cart � stata scritta, non si poteva prevedere che l'oggetto istanziato da essa si sarebbe potuto chiamare $cart o $another_cart. Quindi non � possibile scrivere $cart->items all'interno della classe Cart in fase di progettazione. Per poter accedere alle funzioni e alle variabili interne di una classe perci� si usa la pseudo-variabile $this che pu� essere letta come 'la mia\il mio' o 'di questo oggetto'. Quindi, '$this->items[$artnr] += $num' pu� essere letto come 'aggiungi $num al contatore $artnr al del mio array degli articoli' o 'aggiungi $num al contatore $artnr dell'array degli articoli di questo oggetto'.

Nota: La pseudo variabile $this di norma non � definita se il metodo in cui � utilizzata � richiamato staticamente. Tuttavia questa non � la regola: $this � definita se il metodo � chiamato staticamente da un'altro oggetto. In questo caso il valore di $this � l'oggetto chiamante. Tutto ci� viene illustrato dal seguente esempio:

<?php
class A
{
    function 
foo()
    {
        if (isset(
$this)) {
            echo 
'$this is defined (';
            echo 
get_class($this);
            echo 
")\n";
        } else {
            echo 
"\$this is not defined.\n";
        }
    }
}
 
class 
B
{
    function 
bar()
    {
        
A::foo();
    }
}
 
$a = new A();
$a->foo();
A::foo();
$b = new B();
$b->bar();
B::bar();
?>

Il precedente esempio visualizzer�:

$this is defined (a)
$this is not defined.
$this is defined (b)
$this is not defined.

Nota: Ci sono molte utili funzioni per manipolare classi ed oggetti. Se desiderate conoscerle potete dare un'occhiata alle Class/Object Functions.