2013-02-11 3 views
10

ArrayAccess를 구현하는 객체 또는 객체를 허용 할 수 있습니까? 예를 들어Array 또는 ArrayAccess를 허용하는 PHP 유형 힌팅

:

내가 배열 또는 ArrayAccess 중 하나에 합격 할 수 있도록하려면
class Config implements ArrayAccess { 
    ... 
} 

class I_Use_A_Config 
{ 
    public function __construct(Array $test) 
    ... 
} 

.

수동으로 매개 변수 유형을 확인하는 것 이외의 다른 방법이 있습니까?

답변

10

아니요, "깨끗한"방법이 없습니다.

array 타입은 프리미티브 타입입니다. ArrayAccess 인터페이스를 구현하는 개체는 클래스를 기반으로하며 복합 유형이라고도합니다. 이 두 가지를 모두 포함하는 유형 힌트가 없습니다.

배열로 ArrayAccess을 사용하고 있기 때문에 그냥 캐스팅 할 수 있습니다. 예를 들면 :

$config = new Config; 
$lol = new I_Use_A_Config((array) $config); 

그 옵션이 다음 단지 타입 힌트를 제거하고 배열 또는 ArrayAccess 중 하나입니다 있는지 확인 (당신이 그것을 그대로 Config 객체를 사용하려면)이 아닌 경우. 나는 당신이 그것을 피하고 싶다는 것을 알고 있지만 큰 문제는 아닙니다. 그것은 단지 몇 줄에 불과하며 모든 것이 끝나면 중요하지 않습니다.

+0

내가 원하는 바가 아니지만 배열에 캐스트하는 것은 실제로 좋은 생각입니다. 감사합니다. – Supericy

+0

이것은 나쁜 습관입니다. 클라이언트는 라이브러리가 할 수있는 것을해서는 안됩니다. – danidacar

+0

ArrayAccess가 구현되어 있는지 여부는 배열에 객체를 전송해도 상관이 없습니다. 캐스팅 기능을 변경하는 유일한 방법은 ArrayObject 클래스를 서브 클래 싱하는 것입니다. 완전히 정답없는 그) –

-3

잘 PHP는 배열/개체에 대한 형식 힌트를 지원합니다. 그래서 배열 잘 작동합니다. 그러나 Array 유형에 대해서만 허용 된 메소드에 ArrayAccess 객체를 전달하면 오류가 발생할 수 있습니다. ArrayAccess는 주로 foreach에서 사용하는 것과 같은 방식으로 ArrayAccess 객체를 반복하는 목적으로 주로 사용됩니다.

-1

그들은 PHP 7.1에서 실질적인 솔루션을 제공합니다.

http://php.net/manual/en/migration71.new-features.php#migration71.new-features.iterable-pseudo-type

반복 가능한 의사 형

당신이 원하는합니다. 모든 배열 또는 Traversable 유형 (반복자의 기본 인터페이스)은이 검사를 통과합니다.

이제 심층적 인 분석을 원하는 사람이라면 누구나 명확하게 이해할 수 있습니다. 그렇습니다. 이 러한 경우를 생각하고 스스로 해결해야하지만 누군가가 키를 통해 액세스 할 수없는 통과 가능한 요소를 전달할 경우이를 수행 할 수 있는지 확인해야합니다.

http://php.net/manual/en/function.iterator-to-array.php

지금에 관계없이 유형 - 힌트를 전달 무엇을, 당신은 배열을해야하지만,이 메모리 감소를 위해 발전기를 사용의 이점을 제거 할 수 있습니다. 그것은 분명해야하지만 분명히 그렇지 않습니다. 그래서 여기 있습니다. 프로그래머 인 당신은 코드에 대한 특정 유스 케이스와 코드 사용 방법 및 코드에 대한 적절한 유스 케이스를 파악해야합니다.

여전히 명확하지 않으므로 유형 힌 더 블 (type-hintable)이고 특정 메소드 나 변수가 존재할 것으로 예상되면 나쁜 프로그래밍을하고 있다고 가정 해 보겠습니다. 찾고있는 반환 유형이있는 계약을 구현하고 일반 형식이 아닌이를 전달해야합니다. 루핑과 같은 일반적인 작업 만 수행하려는 경우 iterable 유형이 사용됩니다. 힌트는 다음과 같습니다. 반복하십시오.

+0

을, 희망 https://wiki.php.net/rfc/union_types 언젠가 그것을 만드는 (안 분명히 주조 관련,하지만 영업 이익의 질문에). 순회 가능한 iterface는 주어진 객체가 ArrayAccess를 구현한다는 것을 의미하지는 않습니다 (예 : 항목이 키를 통해 액세스 될 수 있음). 코드에서 추가 유형 검사를 수행해야합니다. – mancze

+0

질문은 : 네, 그렇게 수 '배열 또는 ArrayAccess 구현하는 객체 수를 제공합니다. 네, 반복 가능한 의사 유형의 키를 통해 액세스 할 수 있습니다. Iterator의 멤버는를 통해 액세스 할 수 있습니다. 키. 그것은 정의의 : http://php.net/manual/en/class.iterator.php 힌트 : 그것은'key'라는 하나입니다. –

+0

1) 이런 식으로 질문을 해석하면 타입 선언이없는 답이됩니다 ('array' 또는'ArrayAccess'가 가능합니다). 그러나 그 이상을 허용하기 때문에 분명히 의도 한 대답이 아닙니다. iterable도 마찬가지다. 2)주의 - iterable 타입 힌트는'Iterator'가 아니라'array' 또는'Traversable'을 의미합니다. 예를 들어'Generator'는'Traversable'이지만 키를 통해 값에 접근 할 수 없습니다. 그리고 예제를 살펴보면 configs에 대한 타입 선언을 지정합니다. 여기서 key를 통한 액세스는 아마도 주어진 파라미터의 예상 된 능력 일 것입니다. – mancze