English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Manuale di base PHP

Manuale avanzato PHP

PHP & MySQL

Manuale di riferimento PHP

Orientamento ad oggetti PHP

Nel design orientato agli oggetti (OOP in inglese, abbreviato in OOP), un oggetto è un'entità composta da informazioni e descrizioni del trattamento delle informazioni, è un'astrazione del mondo reale.

Nel mondo reale, tutte le cose che affrontiamo sono oggetti, come computer, televisioni, biciclette, ecc.

Le tre principali caratteristiche degli oggetti:

  • Comportamento degli oggetti: le operazioni che possiamo applicare agli oggetti, accendere e spegnere la luce sono comportamenti.

  • Forma degli oggetti: quando si applicano metodi, come rispondono gli oggetti, colore, dimensione, forma.

  • Rappresentazione degli oggetti: la rappresentazione degli oggetti è simile a un documento d'identità, la differenza specifica risiede nei comportamenti e nelle condizioni identici.

Ad esempio, Animal(animale) è una classe astratta, possiamo specificare un cane e una pecora, e cane e pecora sono oggetti concreti, che hanno attributi come il colore e comportamenti come camminare e correre.

Contenuto orientato agli oggetti

  • Classe − Definisce le caratteristiche astratte di una cosa. La definizione della classe include la forma dei dati e le operazioni sui dati.

  • Oggetto − È un esempio della classe.

  • Variabile membro − Definito all'interno della classe, le variabili di questo tipo sono invisibili all'esterno, ma possono essere accedute tramite funzioni membro. Dopo che la classe è esemplificata come oggetto, questa variabile può essere chiamata attributo dell'oggetto.

  • Funzione membro − Definito all'interno della classe, può essere utilizzato per accedere ai dati dell'oggetto.

  • 继承 − L'ereditarietà è il meccanismo per cui la sottoclasse condivide automaticamente i dati e i metodi della classe padre, che è un tipo di relazione tra classi. Quando si definisce ed implementa una classe, è possibile farlo sulla base di una classe esistente, utilizzando il contenuto definito dalla classe esistente come proprio contenuto e aggiungendo nuovi contenuti.

  • Classe padre − Una classe che viene ereditata da un'altra classe può essere chiamata classe padre, classe base o classe superiore.

  • Sottoclasse − Un classe che eredita da un'altra classe viene chiamata sottoclasse, anche chiamata classe derivata.

  • Polimorfismo − Polimorfismo significa che le stesse funzioni o metodi possono agire su diversi tipi di oggetti e ottenere risultati diversi. Diversi oggetti possono produrre risultati diversi ricevendo lo stesso messaggio, questo fenomeno si chiama polimorfismo.

  • Sovraccarico − In sintesi, è la situazione in cui le funzioni o i metodi hanno lo stesso nome ma una lista di parametri diversa. Tali funzioni o metodi con lo stesso nome e parametri diversi si chiamano funzioni o metodi sovraccaricati.

  • Astrazione − L'astrazione significa astrare gli oggetti che hanno una struttura dati (proprietà) e comportamenti (operazioni) consistenti in una classe. Una classe è una tale astrazione che riflette le proprietà importanti relative all'applicazione, ignorando altri contenuti non rilevanti. La classificazione di qualsiasi classe è soggettiva, ma deve essere relativa all'applicazione specifica.

  • Encapsulation − Encapsulation significa associare le proprietà e i comportamenti di un oggetto esistente nel mondo reale in un'unità logica.

  • 构造函数 − Principalmente utilizzato per inizializzare l'oggetto durante la creazione, ovvero assegnare valori iniziali alle variabili membro dell'oggetto, e viene sempre utilizzato insieme all'operatore new nelle istruzioni di creazione dell'oggetto.

  • funzione distruttiva − Il costruttore (constructor) è il contrario dell'distruttore, viene eseguito automaticamente dal sistema quando l'oggetto termina la sua vita (ad esempio quando la funzione in cui l'oggetto si trova è stata chiamata). L'distruttore viene spesso utilizzato per fare "pulizia e riordinamento" (ad esempio, quando si utilizza new per allocare un'area di memoria, dovrebbe essere liberata con delete prima di uscire).

Nella figura sottostante abbiamo creato tre oggetti attraverso la classe Car: Mercedes, Bmw e Audi.

$mercedes = new Car();
$bmw = new Car();
$audi = new Car();

Definizione della classe PHP

La sintassi di definizione della classe PHP di solito è la seguente:

<?php
class phpClass {
  var $var1;
  var $var2 = 'stringa costante';
  
  function myfunc ($arg1, $arg2) {
     [..]
  }
  [..]
}
?>

L'analisi è il seguente:

  • La classe utilizza class La parola chiave class followed by the class name defines.

  • Dopo la parola chiave della classe, possiamo definire variabili e metodi all'interno di un paio di parentesi graffe ({}).

  • Le variabili della classe utilizzano var per dichiarare, le variabili possono anche essere inizializzate con valori.

  • La definizione della funzione è simile alla definizione delle funzioni PHP, ma le funzioni possono essere accedute solo attraverso la classe e gli oggetti istanziati della classe.

Esempio

<?php
class Site {
  /* Variabile membro */
  var $url;
  var $title;
  
  /* Funzione membro */
  function setUrl($par){
     $this->url = $par;
  }
  
  function getUrl(){
     echo $this->url . PHP_EOL;
  }
  
  function setTitle($par){
     $this->title = $par;
  }
  
  function getTitle(){
     echo $this->title . PHP_EOL;
  }
}
?>

variabile $this rappresenta l'oggetto stesso.

PHP_EOL per il carattere di newline.

Creazione di oggetti in PHP

Dopo aver creato la classe, possiamo utilizzare new Operatore per istanziare l'oggetto della classe:

$w3codebox = new Site;
$taobao = new Site;
$google = new Site;

Nel codice sopra abbiamo creato tre oggetti, tre oggetti sono indipendenti l'uno dall'altro, ora vediamo come accedere ai metodi membri e alle variabili membri.

Chiamata del metodo membro

Dopo aver istanziato l'oggetto, possiamo utilizzare l'oggetto per chiamare i metodi membri, i metodi membri possono solo operare sulle variabili membri dell'oggetto:

// Chiamata della funzione membro, impostazione del titolo e dell'URL
$w3codebox->setTitle('基础教程网');
$taobao->setTitle('淘宝');
$google->setTitle('Google 搜索');
$w3codebox->setUrl('it.oldtoolbag.com');
$taobao->setUrl('www.taobao.com');
$google->setUrl('www.google.com');
// chiamata a funzione membro, ottenere titolo e URL
$w3codebox->getTitle();
$taobao->getTitle();
$google->getTitle();
$w3codebox->getUrl();
$taobao->getUrl();
$google->getUrl();

Il codice completo è il seguente:

Esempio online

<?php
class Site {
  /* Variabile membro */
  var $url;
  var $title;
  
  /* Funzione membro */
  function setUrl($par){
     $this->url = $par;
  }
  
  function getUrl(){
     echo $this->url . PHP_EOL;
  }
  
  function setTitle($par){
     $this->title = $par;
  }
  
  function getTitle(){
     echo $this->title . PHP_EOL;
  }
}
$w3codebox = new Site;
$taobao = new Site;
$google = new Site;
// Chiamata della funzione membro, impostazione del titolo e dell'URL
$w3codebox->setTitle('基础教程网');
$taobao->setTitle('天猫商城');
$google->setTitle('Google 搜索');
$w3codebox->setUrl('it.oldtoolbag.com');
$taobao->setUrl('www.tmall.com');
$google->setUrl('www.google.com');
// chiamata a funzione membro, ottenere titolo e URL
$w3codebox->getTitle();
$taobao->getTitle();
$google->getTitle();
$w3codebox->getUrl();
$taobao->getUrl();
$google->getUrl();
?>

Eseguendo il codice sopra, il risultato di output è:

Sito di base delle istruzioni
Cassa del Tmall
Google Ricerca
it.oldtoolbag.com
www.tmall.com
www.google.com

costruttore PHP

Il costruttore è un metodo speciale. Serve principalmente per inizializzare l'oggetto durante la creazione dell'oggetto, ovvero assegnare valori iniziali ai variabili membro dell'oggetto, utilizzato insieme all'operatore new nella dichiarazione dell'oggetto.

PHP 5 permette agli sviluppatori di definire un metodo come costruttore all'interno di una classe, con la seguente sintassi:

void __construct ([ mixed $args[, $... ]]]

Nell'esempio sopra possiamo inizializzare le variabili $url e $title tramite il metodo costruttore:

function __construct( $par1, $par2 ) {
   $this->url = $par1;
   $this->title = $par2;
}

Ora non dobbiamo chiamare più i metodi setTitle e setUrl:

Esempio online

$w3codebox = new Site('it.oldtoolbag.com', 'Sito di base delle istruzioni');
$tmall = new Site('www.tmall.com', 'Cassa del Tmall');
$google = new Site('www.google.com', 'Google Ricerca');
// chiamata a funzione membro, ottenere titolo e URL
$w3codebox->getTitle();
$tmall->getTitle();
$google->getTitle();
$w3codebox->getUrl();
$tmall->getUrl();
$google->getUrl();

funzione distruttiva

La funzione distruttiva (distruttore) è l'opposto del costruttore, viene eseguita automaticamente dal sistema quando l'oggetto termina la sua vita (ad esempio quando la funzione in cui l'oggetto si trova è stata chiamata)

PHP 5 ha introdotto il concetto di funzione distruttiva, simile ad altri linguaggi orientati agli oggetti, con la seguente sintassi:

void __destruct ( void )

Esempio

<?php
class MyDestructableClass {
   function __construct() {
       print "costruttore\n";
       $this->name = "MyDestructableClass";
   }
   function __destruct() {
       print "销毁 " . $this->name . "\n";
   }
}
$obj = new MyDestructableClass();
?>

Eseguendo il codice sopra, il risultato di output è:

构造函数
销毁 MyDestructableClass

继承

PHP 使用关键字 extends 要继承一个类,PHP 不支持多继承,格式如下:

class Child extends Parent {
   // 代码部分
}

Esempio

示例中 Child_Site 类继承了 Site 类,并扩展了功能:

<?php 
// 子类扩展站点类别
class Child_Site extends Site {
   var $category;
    function setCate($par){
        $this->category = $par;
    }
  
    function getCate(){
        echo $this->category . PHP_EOL;
    }
}

方法重写

如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫做方法的覆盖(override),也称为方法的重写。

示例中重写了 getUrl 与 getTitle 方法:

function getUrl() {
   echo $this->url . PHP_EOL;
   return $this->url;
}
   
function getTitle(){
   echo $this->title . PHP_EOL;
   return $this->title;
}

访问控制

PHP 对属性或方法的访问控制是通过在前面添加关键字 public(公有)、protected(受保护)或 private(私有)来实现的。

  • public(公有):公有的类成员可以在任何地方被访问。

  • protected(受保护):受保护的类成员可以被其自身以及其子类和父类访问。

  • private(私有):私有的类成员只能被其定义所在的类访问。

属性的访问控制

类的属性必须定义为公有、受保护或私有之一。如果使用 var 定义,则被视为公有。

<?php
/**
 * Definire MyClass
 */
class MyClass
{
    public $public = 'Public';
    protected $protected = 'Protected';
    private $private = 'Private';
    function printHello()
    {
        echo $this->public;
        echo $this->protected;
        echo $this->private;
    }
}
=$obj = new MyClass();
echo $obj->public; // Questo riga può essere eseguito normalmente
echo $obj->protected; // Questo riga produrrà un errore fatale
echo $obj->private; // Questo riga produrrà un errore fatale
$obj->printHello(); // Output Public, Protected e Private
/**
 * Definire MyClass2
 */
class MyClass2 extends MyClass
{
    // È possibile ridefinire public e protected, ma non private
    protected $protected = 'Protected2';
    function printHello()
    {
        echo $this->public;
        echo $this->protected;
        echo $this->private;
    }
}
$obj2 = new MyClass2();
echo $obj2->public; // Questo riga può essere eseguito normalmente
echo $obj2->private; // Non definito private
echo $obj2->protected; // Questo riga produrrà un errore fatale
$obj2->printHello(); // Output Public, Protected2 e Undefined
?>

Controllo di accesso ai metodi

I metodi della classe possono essere definiti come pubblici, privati o protetti. Se non vengono impostati questi keyword, il metodo diventa pubblico per default.

<?php
/**
 * Definire MyClass
 */
class MyClass
{
    // Dichiarare un costruttore pubblico
    public function __construct() { }
    // Dichiarare un metodo pubblico
    public function MyPublic() { }
    // Dichiarare un metodo protetto
    protected function MyProtected() { }
    // Dichiarare un metodo privato
    private function MyPrivate() { }
    // Questo metodo è pubblico
    function Foo()
    {
        $this->MyPublic();
        $this->MyProtected();
        $this->MyPrivate();
    }
}
$myclass = new MyClass;
$myclass->MyPublic(); // Questo riga può essere eseguito normalmente
$myclass->MyProtected(); // Questo riga produrrà un errore fatale
$myclass->MyPrivate(); // Questo riga produrrà un errore fatale
$myclass->Foo(); // Pubblico, protetto e privato possono essere eseguiti
/**
 /* Definizione di MyClass2
 */
class MyClass2 extends MyClass
{
    // Questo metodo è pubblico
    function Foo2()
    {
        $this->MyPublic();
        $this->MyProtected();
        $this->MyPrivate(); // Questa riga genererà un errore fatale
    }
}
$myclass2 = new MyClass2;
$myclass2->MyPublic(); // Questa riga può essere eseguita normalmente
$myclass2->Foo2(); // Gli pubblici e i protetti possono essere eseguiti, ma non i privati
class Bar 
{
    public function test() {
        $this->testPrivate();
        $this->testPublic();
    }
    public function testPublic() {
        echo "Bar::testPublic\n";
    }
    
    private function testPrivate() {
        echo "Bar::testPrivate\n";
    }
}
class Foo extends Bar 
{
    public function testPublic() {
        echo "Foo::testPublic\n";
    }
    
    private function testPrivate() {
        echo "Foo::testPrivate\n";
    }
}
$myFoo = new foo();
$myFoo->test(); // Bar::testPrivate 
                // Foo::testPublic
?>

interfaccia

Utilizzando l'interfaccia (interface), è possibile specificare quali metodi una classe deve implementare, senza definire il contenuto specifico di questi metodi.

Un'interfaccia è definita da interface La parola chiave per definire, come definire una classe standard, ma tutti i metodi definiti sono vuoti.

Tutti i metodi definiti nell'interfaccia devono essere pubblici, questa è una caratteristica dell'interfaccia.

Per implementare un'interfaccia, utilizzare implements L'operatore. La classe deve implementare tutti i metodi definiti nell'interfaccia, altrimenti viene generato un errore fatale. Una classe può implementare più interfacce, separando i nomi delle interfacce con la virgola.

<?php
// Dichiarazione di un'interfaccia 'iTemplate'
interface iTemplate
{
    public function setVariable($name, $var);
    public function getHtml($template);
}
// Implementa l'interfaccia
class Template implements iTemplate
{
    private $vars = array();
  
    public function setVariable($name, $var)
    {
        $this->vars[$name] = $var;
    }
  
    public function getHtml($template)
    {
        foreach($this->vars as $name => $value) {
            $template = str_replace('{'. $name .'}', $value, $template);
        }
 
        return $template;
    }
}

Costante

Puoi definire come costante un valore che rimane invariato nel contesto della classe. Non è necessario utilizzare il simbolo $ quando si definisce e si utilizza una costante.

Il valore della costante deve essere un valore costante, non può essere una variabile, una proprietà di classe, il risultato di un'operazione matematica o una chiamata di funzione.

Da PHP 5.3.0, è possibile chiamare dinamicamente una classe utilizzando una variabile. Tuttavia, il valore della variabile non può essere un nome riservato (come self, parent o static).

Esempio

<?php
class MyClass
{
    const constant = 'Valore costante';
    function showConstant() {
        echo self::constant . PHP_EOL;
    }
}
echo MyClass::constant . PHP_EOL;
$classname = "MyClass";
echo $classname::constant . PHP_EOL; // Da 5.3.0
$class = new MyClass();
$class->showConstant();
echo $class::constant . PHP_EOL; // Da PHP 5.3.0
?>

Classe astratta

Qualsiasi classe che abbia almeno un metodo dichiarato come astratto deve essere dichiarata come astratta.

Le classi definite come astratte non possono essere istanziate.

I metodi dichiarati come astratti dichiarano solo il modo di chiamata (parametri), ma non possono definire l'esatta implementazione della funzione.

Quando si herda da una classe astratta, il sottoclasse deve definire tutti i metodi astratti della classe padre; inoltre, il controllo di accesso di questi metodi deve essere lo stesso (o più permissivo) di quello della classe padre. Ad esempio, se un metodo astratto è dichiarato come protetto, allora il metodo implementato nel sottoclasse dovrebbe essere dichiarato come protetto o pubblico, non come privato.

<?php
abstract class AbstractClass
{
 // si richiede che le sottoclassi definiscano questi metodi
    abstract protected function getValue();
    abstract protected function prefixValue($prefix);
    // metodo normale (non astratto)
    public function printOut() {
        print $this->getValue() . PHP_EOL;
    }
}
class ConcreteClass1 extends AbstractClass
{
    protected function getValue() {
        return "ConcreteClass1";
    }
    public function prefixValue($prefix) {
        return "{$prefix}ConcreteClass1";
    }
}
class ConcreteClass2 extends AbstractClass
{
    public function getValue() {
        return "ConcreteClass2";
    }
    public function prefixValue($prefix) {
        return "{$prefix}ConcreteClass2";
    }
}
$class1 = new ConcreteClass1;
$class1->printOut();
echo $class1->prefixValue('FOO_') . PHP_EOL;
$class2 = new ConcreteClass2;
$class2->printOut();
echo $class2->prefixValue('FOO_') . PHP_EOL;
?>

Eseguendo il codice sopra, il risultato di output è:

ConcreteClass1
FOO_ConcreteClass1
ConcreteClass2
FOO_ConcreteClass2

Inoltre, il metodo della sottoclasse può includere parametri opzionali che non esistono nel metodo astratto della classe padre.

Ad esempio, se la sottoclasse definisce un parametro opzionale mentre la dichiarazione del metodo astratto della classe padre non lo contiene, può funzionare normalmente.

<?php
abstract class AbstractClass
{
    // La nostra metodo astratto richiede solo definire i parametri necessari
    abstract protected function prefixName($name);
}
class ConcreteClass extends AbstractClass
{
    // Le nostre sottoclassi possono definire parametri opzionali che non esistono nella firma del padre
    public function prefixName($name, $separator = ".") {
        if ($name == "Pacman") {
            $prefix = "Mr";
        } elseif ($name == "Pacwoman") {
            $prefix = "Mrs";
        } else {
            $prefix = "";
        }
        return "{$prefix}{$separator} {$name}";
    }
}
$class = new ConcreteClass;
echo $class->prefixName("Pacman"), "\n";
echo $class->prefixName("Pacwoman"), "\n";
?>

Il risultato dell'output è:

Mr. Pacman
Mrs. Pacwoman

Parola chiave static

Dichiarando le proprietà o i metodi della classe come static (statici), è possibile accedervi direttamente senza istanziare la classe.

Le proprietà statiche non possono essere accedute tramite un oggetto già istanziato della classe (ma i metodi statici possono essere chiamati).

Poiché i metodi statici possono essere chiamati senza un oggetto, il segnaposto $this non è disponibile nei metodi statici.

Le proprietà statiche non possono essere accedute tramite l'operatore -> da parte di un oggetto.

Da PHP 5.3.0 in poi, è possibile chiamare dinamicamente una classe utilizzando una variabile. Tuttavia, il valore di tale variabile non può essere i termini chiave self, parent o static.

<?php
class Foo {
  public static $my_static = 'foo';
  
  public function staticValue() {
     return self::$my_static;
  }
}
print Foo::$my_static . PHP_EOL;
$foo = new Foo();
print $foo->staticValue() . PHP_EOL;
?>

Eseguendo il programma sopra, il risultato di output sarà:

foo
foo

Parola chiave final

PHP 5 ha introdotto una parola chiave final. Se un metodo della classe padre viene dichiarato come final, la classe figlia non può sovrascrivere tale metodo. Se una classe viene dichiarata come final, non può essere ereditata.

L'esecuzione del seguente codice genererà un errore:

<?php
class BaseClass {
   public function test() {
       echo "BaseClass::test() called" . PHP_EOL;
   }
   
   final public function moreTesting() {
       echo "BaseClass::moreTesting() called" . PHP_EOL;
   }
}
class ChildClass extends BaseClass {
   public function moreTesting() {
       echo "ChildClass::moreTesting() called" . PHP_EOL;
   }
}
// Messaggio di errore: Fatal error: Cannot override final method BaseClass::moreTesting()
?>

Chiamata al metodo costruttore della superclasse

PHP non chiama automaticamente il metodo costruttore della superclasse nel metodo costruttore della sottoclasse. Per eseguire il metodo costruttore della superclasse, è necessario chiamarlo nel metodo costruttore della sottoclasse. parent::__construct(); .

<?php
class BaseClass {
   function __construct() {
       print "Classe BaseClass: metodo costruttore" . PHP_EOL;
   }
}
class SubClass extends BaseClass {
   function __construct() {
       parent::__construct(); // Il metodo costruttore della sottoclasse non può chiamare automaticamente il metodo costruttore della superclasse
       print "Classe SubClass: metodo costruttore" . PHP_EOL;
   }
}
class OtherSubClass extends BaseClass {
    // Eredita il metodo costruttore di BaseClass
}
// Chiamata al metodo costruttore di BaseClass
$obj = new BaseClass();
// Chiamata ai metodi costruttore di BaseClass e SubClass
$obj = new SubClass();
// Chiamata al metodo costruttore di BaseClass
$obj = new OtherSubClass();
?>

Eseguendo il programma sopra, il risultato di output sarà:

Classe BaseClass: metodo costruttore
Classe BaseClass: metodo costruttore
Classe SubClass: metodo costruttore
Classe BaseClass: metodo costruttore