PHP 7에서 속성에 대한 힌트를 입력하시겠습니까?

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 

설명.

먼저, 정의한다.barPHP가 캐스트할 수 있도록 개인 자산으로서__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 ...