2016-05-16 17 views
26

php 7 supporta il tipo di suggerimento per le proprietà di classe?Tipo suggerimento per le proprietà in PHP 7?

Voglio dire, non solo per setters/getters ma per la proprietà stessa.

Qualcosa di simile:

class Foo { 
    /** 
    * 
    * @var Bar 
    */ 
    public $bar : Bar; 
} 

$fooInstance = new Foo(); 
$fooInstance->bar = new NotBar(); //Error 
+1

Non che io sappia. Tuttavia, in generale * qualsiasi * vincolo sul valore di una proprietà dovrebbe comunque essere fatto attraverso un setter. Dal momento che il setter può facilmente avere un typehint per l'argomento "value", sei a posto. –

+0

Molti framework utilizzano gli attributi _protected_ (principalmente per i controller). Per quei casi in particolare sarebbe molto utile. – CarlosCarucce

risposta

37

PHP 7.0, che è l'attuale versione minore al momento della scrittura (2016 -05-16), non supporta questo. Ci sono stati alcuni sforzi in questa direzione (come lo Typed Properties RFC, che è stato rifiutato per PHP 7.1), ma al momento non esiste un supporto diretto.


Nel frattempo, ci sono alcune alternative.

È possibile effettuare una proprietà privata che è accessibile solo attraverso getter e setter che hanno dichiarazioni di tipo:

class Person 
{ 
    private $name; 
    public function getName(): string { 
     return $this->name; 
    } 
    public function setName(string $newName) { 
     $this->name = $newName; 
    } 
} 

si può anche fare una proprietà pubblica e utilizzare un docblock per fornire informazioni sul tipo di persone che leggono il codice e l'utilizzo di un IDE, ma questo non fornisce alcun tipo di runtime-checking:

class Person 
{ 
    /** 
     * @var string 
     */ 
    public $name; 
} 

e in effetti, è possibile combinare getter e setter e un docblock.

Se sei più avventuroso, puoi creare una proprietà contraffatta con lo __get, __set, __isset and __unset magic methods e controllarne i tipi. Non sono sicuro se lo consiglierei comunque.

+0

Suoni davvero buoni. Non vedo l'ora di vedere cosa sta arrivando nelle prossime uscite! – CarlosCarucce

+10

Ugh. Peccato che RFC abbia fallito :( –

+2

C'è qualche spiegazione sul perché questa RFC è stata rifiutata? –

0

È possibile utilizzare setter

class Bar { 
    public $val; 
} 

class Foo { 
    /** 
    * 
    * @var Bar 
    */ 
    private $bar; 

    /** 
    * @return Bar 
    */ 
    public function getBar() 
    { 
     return $this->bar; 
    } 

    /** 
    * @param Bar $bar 
    */ 
    public function setBar(Bar $bar) 
    { 
     $this->bar = $bar; 
    } 

} 

$fooInstance = new Foo(); 
// $fooInstance->bar = new NotBar(); //Error 
$fooInstance->setBar($fooInstance); 

uscita:

TypeError: Argument 1 passed to Foo::setBar() must be an instance of Bar, instance of Foo given, called in ... 
Problemi correlati