저는 가능한 한 강력하게 입력하려고하는 프레임 워크에서 작업하고 있습니다. (저는 PHP에서 일하고 있고 C#에서 좋아하는 아이디어를 취하여이 프레임 워크 내에서 활용하려고합니다.) 도메인 엔티티/객체의 컬렉션 인 Collection 클래스를 만듭니다. 그것은 닷넷의 List<T>
객체를 모델링 한 것입니다.PHP 'instanceof'가 클래스 상수와 함께 실패했습니다.
나는이 클래스를 타이핑하는 것을 방해하는 장애물에 부딪혔다. UserCollection을 가지고 있다면 User 객체를 그 안에 넣어야합니다. PostCollection이있는 경우 Post 객체 만 허용해야합니다.
모든이 프레임 워크의 컬렉션에는 추가, 제거, 반복과 같은 특정 기본 기능이 있어야합니다. 인터페이스를 만들었지 만 다음 작업을 수행 할 수 없다는 것을 알았습니다.
interface ICollection { public function add($obj) }
class PostCollection implements ICollection { public function add(Post $obj) {} }
이것은 인터페이스를 위반 한 것입니다. 하지만 모든 컬렉션이 같은 유형이므로 인터페이스를 강력하게 입력 할 수 없습니다. 이 코드를 실행하려고하면
interface ICollection { public function add($obj) }
abstract class Collection implements ICollection { const type = 'null'; }
class PostCollection extends Collection {
const type = 'Post';
public function add($obj) {
if(!($obj instanceof self::type)) {
throw new UhOhException();
}
}
}
, 내가 instanceof
문에 syntax error, unexpected T_STRING, expecting T_VARIABLE or '$'
를 얻을 : 그래서 나는 다음 시도했다. 문제에 대한 약간의 조사와 원인의 근본 원인은 $obj instanceof self
이 클래스에 대한 테스트에 유효하다는 것입니다. PHP는 표현식에 전체 self::type
상수 문장을 처리하지 않는 것으로 보입니다. self::type
변수에 괄호를 추가 예기치 않은 '('에 관한 오류가 발생했습니다.
확실한 해결 방법은 $type
가 변수로 선언 된 경우 상수. 표현은 $obj instanceof $this->type
물론, (잘 작동 type
변수를 확인하지 않는 것입니다)
변수를 나중에 변경하지 못하도록 상수로 값을 정의하고 싶으므로이를 피할 수있는 방법이 필요합니다.이 방법을 달성 할 수있는 방법에 대한 생각 또는 이 점에있어서 PHP를 사용하는 데 한계가 있습니까? self::this
을 "이스케이프 (escape)"하거나 캡슐화하여 PHP를 처리 할 때 PHP가 죽지 않게 할 방법이 있습니까?
업데이트 아래 의견에 따라, 나는 시도 할 무언가를 생각했습니다 - 아래 코드가 작동합니다! 누구나 1) 이것을하지 않는 이유, 2) 이것이 궁극적으로 효과가없는 이유, 또는 3) 이것을 제거하는 더 좋은 방법을 생각할 수 있습니까?
interface ICollection { public function add($obj) }
abstract class Collection { const type = null; protected $type = self::type; }
class PostCollection extends Collection {
const type = 'Post';
public function add($obj) {
if(!($obj instanceof $this->type)) {
throw new UhOhException();
}
}
}
업데이트 # 2 : 생산에 위의 코드를 넣어 후에는 작동하지 않습니다 밝혀졌습니다. 테스트했을 때 어떻게 작동하는지 전혀 모르지만 전혀 작동하지 않습니다. 나는 protected
변수를 사용하고있다.
은 내가 1 또는 2를 대답 생각 - 심지어 t 불구하고 그는 변수가'protected'이며, 여전히 코드에서 변경 될 수 있습니다. '$ type' 변수가 우발적으로 변경되지 않도록하는 방법으로 실제 보안을 설정할 필요가 없습니다. 내가 바라는 것은 그것에 대한 보험이었다. –
올바르게 이해했다면 classof 일 때 instanceof 연산에 문자열 ($ this-> type)을 부여합니다 (http://php.net/manual/en/language.operators.type.php 참조) . 나는 당신이 대신 $ this-> type이 무엇인지를 기대하는 'is_a'를 사용해야한다고 생각한다. – gacrux
진실한 진술이 아닙니다 - 연결된 페이지의 예제 # 5를보십시오. –