php 7はクラスプロパティの型ヒントをサポートしていますか?
つまり、セッター/ゲッターだけでなく、プロパティ自体にも当てはまります。
何かのようなもの:
class Foo {
/**
*
* @var Bar
*/
public $bar : Bar;
}
$fooInstance = new Foo();
$fooInstance->bar = new NotBar(); //Error
php 7はクラスプロパティの型ヒントをサポートしていますか?
つまり、セッター/ゲッターだけでなく、プロパティ自体にも当てはまります。
何かのようなもの:
class Foo {
/**
*
* @var Bar
*/
public $bar : Bar;
}
$fooInstance = new Foo();
$fooInstance->bar = new NotBar(); //Error
回答:
PHP 7.4は、次のような型付きプロパティをサポートします。
class Person
{
public string $name;
public DateTimeImmutable $dateOfBirth;
}
PHP 7.3以前はこれをサポートしていませんが、いくつかの代替手段があります。
型宣言を持つゲッターとセッターを介してのみアクセス可能なプライベートプロパティを作成できます。
class Person
{
private $name;
public function getName(): string {
return $this->name;
}
public function setName(string $newName) {
$this->name = $newName;
}
}
パブリックプロパティを作成し、docblockを使用して、コードを読んでIDEを使用しているユーザーに型情報を提供することもできますが、これでは実行時型チェックは提供されません。
class Person
{
/**
* @var string
*/
public $name;
}
そして実際、ゲッターとセッター、およびdocblockを組み合わせることができます。
あなたはもっと冒険している場合は、あなたが偽のプロパティを作ることができる__get
、__set
、__isset
と__unset
魔法の方法、および種類を自分で確認してください。でも、お勧めするかどうかはわかりません。
array_push($this->foo, $bar)
またはsort($this->foobar)
大したことになるでしょう。
(new Person())->dateOfBirth = '2001-01-01';
...提供さdeclare(strict_types=0);
れます。DateTimeImmutable
コンストラクターをスローまたは使用しますか?その場合、文字列が無効な日付であると、どのようなエラーがスローされますか?TypeError
?
7.4以降:
@Andreaが指摘したように、新しいリリースで実装されることは朗報です。誰かが7.4より前にそれを使用したい場合に備えて、このソリューションをここに残しておきます
7.3以下
私がまだこのスレッドから受け取っている通知に基づいて、そこにいる多くの人々が私と同じ問題を抱えていた/抱えていると思います。この場合の私のソリューションを組み合わせたセッター+__set
この動作をシミュレートするために、形質内の魔法の方法を。ここにあります:
trait SettersTrait
{
/**
* @param $name
* @param $value
*/
public function __set($name, $value)
{
$setter = 'set'.$name;
if (method_exists($this, $setter)) {
$this->$setter($value);
} else {
$this->$name = $value;
}
}
}
そしてここにデモンストレーションがあります:
class Bar {}
class NotBar {}
class Foo
{
use SettersTrait; //It could be implemented within this class but I used it as a trait for more flexibility
/**
*
* @var Bar
*/
private $bar;
/**
* @param Bar $bar
*/
protected function setBar(Bar $bar)
{
//(optional) Protected so it wont be called directly by external 'entities'
$this->bar = $bar;
}
}
$foo = new Foo();
$foo->bar = new NotBar(); //Error
//$foo->bar = new Bar(); //Success
説明
まず、bar
PHPが__set
自動的にキャストするようにプライベートプロパティとして定義します。
__set
現在のオブジェクト(method_exists($this, $setter)
)で宣言されているセッターがあるかどうかを確認します。それ以外の場合は、通常どおりに値を設定するだけです。
タイプヒント付き引数(setBar(Bar $bar)
)を受け取るセッターメソッド(setBar)を宣言します。
PHPがBar
インスタンスではないものがセッターに渡されていることを検出する限り、致命的なエラーを自動的にトリガーします:Uncaught TypeError:Foo :: setBar()に渡される引数1はBarのインスタンスである必要があり、NotBarのインスタンスが指定されている必要があります
PHP 7.4用に編集:
PHP 7.4以降、属性(ドキュメント/ Wiki)を入力できます。つまり、次のことができます。
class Foo
{
protected ?Bar $bar;
public int $id;
...
}
ウィキによると、すべての許容値は次のとおりです。
PHP <7.4
それは実際には不可能であり、実際にそれをシミュレートする方法は4つしかありません。
ここでそれらすべてを組み合わせました
class Foo
{
/**
* @var Bar
*/
protected $bar = null;
/**
* Foo constructor
* @param Bar $bar
**/
public function __construct(Bar $bar = null){
$this->bar = $bar;
}
/**
* @return Bar
*/
public function getBar() : ?Bar{
return $this->bar;
}
/**
* @param Bar $bar
*/
public function setBar(Bar $bar) {
$this->bar = $bar;
}
}
null(php7.0では使用できない)である可能性があるため、php 7.1(null可能)以降、実際にはリターンを?Barとして入力できることに注意してください。
php7.1以降、returnをvoidとして入力することもできます
セッターが使えます
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 ...