PHP 7은 클래스 속성에 대한 유형 힌트를 지원합니까?
내 말은, setter / getters 뿐만 아니라 속성 자체를 위해서도 말입니다 .
다음과 같은 것 :
class Foo {
/**
*
* @var Bar
*/
public $bar : Bar;
}
$fooInstance = new Foo();
$fooInstance->bar = new NotBar(); //Error
PHP 7은 클래스 속성에 대한 유형 힌트를 지원합니까?
내 말은, setter / getters 뿐만 아니라 속성 자체를 위해서도 말입니다 .
다음과 같은 것 :
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;
}
그리고 실제로 getter와 setter와 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 이하
이 스레드에서 여전히 수신하는 알림을 기반으로 많은 사람들이 내가 가진 동일한 문제를 가지고 있다고 생각합니다. 이 경우에 대한 내 솔루션은 이 동작을 시뮬레이션하기 위해 특성 내부에 setter + __set
magic 메서드를 결합하는 것이 었습니다 . 여기있어:
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
자동으로 캐스트되도록 private 속성으로 정의 합니다.
__set
현재 객체 ( method_exists($this, $setter)
)에 선언 된 setter가 있는지 확인합니다 . 그렇지 않으면 평소처럼 값만 설정됩니다.
유형 힌트 인수 ( setBar(Bar $bar)
) 를받는 setter 메서드 (setBar)를 선언합니다 .
PHP가 Bar
인스턴스 가 아닌 것이 setter에 전달되고 있음을 감지하는 한, Fatal Error : Uncaught TypeError : Argument 1 pass to Foo :: setBar () must be an instance of Bar, instance of NotBar given to
PHP 7.4 수정 :
PHP 7.4부터 속성 ( 문서 / 위키 )을 입력 할 수 있습니다.
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;
}
}
php 7.1 (nullable) 이후로 반환 값을? Bar로 입력 할 수 있습니다. 이는 null 일 수 있기 때문입니다 (php7.0에서는 사용할 수 없음).
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 ...