2016-05-16 9 views
26

Поддерживает ли тип поддержки php 7 свойства класса?Тип намека на свойства в PHP 7?

Я имею в виду не только для сеттеров/геттеров, но и для самой собственности.

Что-то вроде:

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

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

Не то, чтобы я знал. Однако, вообще говоря, * любые * ограничения на значение свойства должны выполняться через сеттер в любом случае. Так как сеттер может легко иметь typehint для аргумента «value», вам хорошо идти. –

+0

Многие фреймворки используют атрибуты _protected_ (в основном для контроллеров). Для этих случаев, в частности, это было бы очень полезно. – CarlosCarucce

ответ

37

PHP 7.0, который является текущим минорный релиз на момент написания (+2016 -05-16), не поддерживает это. Были предприняты некоторые усилия в этом направлении (например, Typed Properties RFC, который был отклонен для PHP 7.1), но в настоящее время нет прямой поддержки.

В то же время есть несколько альтернатив.

Вы можете сделать частную собственность, которая доступна только через добытчиками и сеттеров, которые имеют объявление типа:

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

Вы можете также сделать публичную собственность и использовать заголовочный блок для предоставления информации о типе людей, читающих код и с помощью IDE, но это не обеспечивает выполнения проверки типов:

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

и действительно, вы можете комбинировать методы получения и установку и заголовочный блок.

Если вы более предприимчивы, вы можете сделать фальшивое имущество с помощью __get, __set, __isset and __unset magic methods и сами проверить типы. Хотя я не уверен, рекомендую ли я это.

+0

Звучит очень хорошо. Не могу дождаться, чтобы посмотреть, что произойдет в следующих выпусках! – CarlosCarucce

+10

Ugh. Поразите, что RFC не удалось :( –

+2

Есть ли какое-то объяснение, почему этот RFC был отклонен? –

0

Вы можете использовать сеттер

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); 

Выход:

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