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 이전 버전에서는 지원되지 않지만 몇 가지 대안이 있습니다.
유형 선언이 있는 getter 및 setter를 통해서만 액세스할 수 있는 개인 속성을 만들 수 있습니다.
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; }
게터, 세터, 문서 블록을 조합할 수 있습니다.
모험심이 강하다면 , , , 마법의 방법으로 가짜 부동산을 만들어 직접 유형을 확인할 수 있습니다.근데 추천할 수 있을지 모르겠어요.
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
는 현재 오브젝트에 선언된 setter가 있는지 확인합니다(method_exists($this, $setter)
그렇지 않은 경우 값은 통상대로만 설정됩니다.
type-hinted 인수를 수신하는 setter 메서드(setBar)를 선언합니다.setBar(Bar $bar)
).
PHP가 감지하는 한,Bar
인스턴스가 세터로 전달되면 치명적인 오류가 자동으로 트리거됩니다.Uncaught TypeError: Foo::setBar()에 전달된 인수 1은 바의 인스턴스여야 하며 지정된 NotBar의 인스턴스여야 합니다.
PHP 7.4용 편집:
PHP 7.4에서는 속성(Documentation/Wiki)을 입력할 수 있습니다.이것에 의해, 다음의 조작이 가능하게 됩니다.
class Foo {
protected ?Bar $bar;
public int $id;
... }
Wiki에 따르면 허용되는 모든 값은 다음과 같습니다.
- bool, int, float, 문자열, 배열, 객체
- 반복할 수 있다
- 자기, 부모
- 임의의 클래스 또는 인터페이스 이름
- ?type // 여기서 “type”은 위 중 하나입니다.
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일 수 있으므로 php 7.1(nullable) 이후의 막대입니다(ph7.0에서는 사용할 수 없습니다).
php7.1 이후 반환을 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 ...