변수가 배열인지 확인하는 방법은 무엇입니까?…


90

foreach변수가 있는 루프 를 사용하고 싶지만이 변수는 NULL예를 들어 다양한 유형이 될 수 있습니다 .

그래서 foreach테스트 하기 전에 :

if(is_array($var)){
  foreach($var as ...

하지만 Iterator인터페이스 를 구현하는 클래스가 될 수도 있다는 것을 깨달았습니다 . 어쩌면 나는 장님이지만 클래스가 인터페이스를 구현하는지 확인하는 방법은 무엇입니까? is_a함수 나 inherits연산자 와 같은 것이 있습니까? 을 찾았습니다 class_implements. 사용할 수 있지만 더 간단한 것이 있습니까?

두 번째로 더 중요한 것은이 함수가 존재한다고 가정합니다. 변수 is_array또는 " Iterator인터페이스 구현 "인지 확인하기에 충분 할까요? 아니면 더 많은 것을 테스트해야할까요?


2
if ($ var instanceof ArrayIterator)
Alexey

예, 설명서를 보지 않은 경우에도 작동하지 않을 것이라고 확신했습니다 ...
Voitcus 2013 년

답변:


80

foreach함수 내부에서 사용 중이고 배열 또는 Traversable 객체 가 예상되는 경우 해당 함수에 힌트를 입력 할 수 있습니다.

function myFunction(array $a)
function myFunction(Traversable)

foreach함수 내에서 사용하지 않거나 둘 다 예상 하는 경우이 구문사용 하여 변수를 반복 할 수 있는지 확인하면됩니다.

if (is_array($a) or ($a instanceof Traversable))

감사. 충분하기를 바라며 반복 할 수있는 다른 언어 구조가 없을 것입니다.
Voitcus 2013 년

나는 is_array비싸다 는 것을 알았다 . 계산 비용은 배열의 크기에 따라 증가하는 것 같았습니다 (배열인지 확인하는 것이므로 의미가 없습니다). 그러나 그것은 도서관에서 충격적으로 일어났습니다. 연결된 질문에서 내 의견 을 참조하십시오 . 윌 instanceof Traversable배열 작업? 성능을 테스트 할 기회가 없었습니다.
ADTC

@ADTC AFAIR 배열은 예의 인스턴스입니다 Traversable.
Shoe

1
@Shoe 나는 여기에서 그것을 시도했다 . 로 $var = array(1,2,3);결과입니다 : is_array($var) = true$var instanceof Traversable = false.
ADTC

@ADTC 예, 방금 확인했습니다. 배열은 구현되지 Iterator않으므로 Traversable.
Shoe

15

foreach배열과 객체를 처리 할 수 ​​있습니다. 다음과 같이 확인할 수 있습니다.

$can_foreach = is_array($var) || is_object($var);
if ($can_foreach) {
    foreach ($var as ...
}

Traversable모든 배열과 마찬가지로 모든 객체가 PHP에서 순회 가능하기 때문에 다른 사람들이 답변에서 암시 했으므로 특별히 확인할 필요가 없습니다 .

더 기술적으로 :

foreach모든 종류의 순회 가능, 즉 배열, 일반 개체 (액세스 가능한 속성이 순회되는 경우) 및 Traversable개체 (또는 내부 get_iterator처리기 를 정의하는 개체 )와 함께 작동 합니다 .

( 출처 )

일반적인 PHP 프로그래밍에서 간단히 말하면 변수가

  • 배열
  • 객체

그리고 아니다

  • 없는
  • 자원
  • 스칼라

당신은 foreach그것에 사용할 수 있습니다 .


5

Traversable간단한 기능으로 인스턴스를 확인할 수 있습니다 . 이 모든이 작동 것 Iterator때문에Iterator extends Traversable

function canLoop($mixed) {
    return is_array($mixed) || $mixed instanceof Traversable ? true : false;
}

"? true : false"부분이 중복됩니다. instanceof는 결과적으로 이미 bool 값을 제공합니다.
Linas

2
<?php
$var = new ArrayIterator();

var_dump(is_array($var), ($var instanceof ArrayIterator));

반환 bool(false)또는bool(true)


0

기능

<?php

/**
 * Is Array?
 * @param mixed $x
 * @return bool
 */
function isArray($x) : bool {
  return !isAssociative($x);
}

/**
 * Is Associative Array?
 * @param mixed $x
 * @return bool
 */
function isAssociative($x) : bool {
  if (!is_array($array)) {
    return false;
  }
  $i = count($array);
  while ($i > 0) {
    if (!isset($array[--$i])) {
      return true;
    }
  }
  return false;
}

<?php

$arr = [ 'foo', 'bar' ];
$obj = [ 'foo' => 'bar' ];

var_dump(isAssociative($arr));
# bool(false)

var_dump(isAssociative($obj));
# bool(true)

var_dump(isArray($obj));
# bool(false)

var_dump(isArray($arr));
# bool(true)

0

PHP 7.1부터는 iterable정확히이 목적을위한 의사 유형 이 있습니다. 유형 힌트 iterable는 모든 배열과 Traversable인터페이스 구현을 허용합니다 . PHP 7.1도이 기능을 도입했습니다 is_iterable(). 이전 버전의 경우 새로운 기본 제공 기능없이 동등한 유형 적용을 수행하려면 여기에서 다른 답변을 참조하십시오.

공정한 플레이 : BlackHole이 지적했듯이이 질문은 Iterable 객체와 배열 유형 힌팅 의 중복으로 보입니다 . 그리고 자신의 대답은 나보다 더 세부로 들어갑니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.