본문 바로가기

'.' Programs/PHP

PHP의 배열 [연관배열]

by 존 코그셸(John Coggeshall), 역 한빛 리포터 1기 이호재 이번 기사에서는 연관 배열(associative array)과 다차원 배열(multidimensional array)을 사용하는 방법에 대해 얘기하고자 한다. 지난번 기사에서는 PHP 배열의 기초적인 부분을 다루었다면 이번 기사에서는 고급 과정인 연관 배열과 다차원 배열에 대해서 소개하고자 한다. 연관 배열(Associative arrays) 지난번 기사에서 배열의 사용법과 integer 숫자(1,2,3)에 기반한 인덱스만을 사용할 수 있다고 배웠다. 이번 기사에서는 다른 종류의 배열인 연관 배열에 대해 알아보겠다. 연관 배열은 주요한 한 가지 차이점을 제외하고는 기존의 배열과 완전히 똑같다. 그 차이점은 바로 인덱스 값에 관한 것이다. 연관 배열에 있어서 인덱스 값은 간단한 정수뿐만 아니라 문자열도 될 수 있다. 예를 들면, 연관 배열에서는 "foo" 인덱스 에 "bar" 라는 값을 저장할 수 있다. 고맙게도 연관 배열을 선언하고 사용하는 방법은 기존의 배열과 완전히 동일하다. 다음 예를 살펴보자.


<?php
  $myarray_1 = array("foo"=>"bar");
  $myarray_2["foo"] = "bar";
?>
연관 배열을 사용하는 것은 인덱스를 정수로 쓰는 기존의 배열과 거의 동일하다. 그렇다면 연관 배열을 사용하면 어떤 장점이 있을까? 연관 배열의 유연성 때문에, 이름과 같은 문자열에 다른 문자열이나 데이터 타입(전화번호나 이메일 등)을 지정할 수 있다. 또한 다른 웹사이트에서 만드는 의미 없는 에러 메시지에 좀더 유용한 설명을 지정할 수도 있다. 이는 연관 배열의 유용함을 보여 주는 두 가지 예일 뿐이다. 이제 한 배열에 다른 배열을 포함하는 다차원 배열에 대해서 알아보자. 다차원 배열(Multidimensional arrays)위에서 말했던 것처럼 다차원 배열은 적어도 하나의 다른 배열을 인덱스의 값으로 갖고 있는 배열을 의미한다. 다차원 배열의 예로 인덱스 1부터 5까지를 가지고 있는 배열이 2번째 인덱스의 값으로 다른 배열을 갖는 $foo라는 배열을 들 수 있다. 다차원 배열을 생성하고 다루는 것에는 여러 가지 방법이 있다(이는 지난번 기사인 PHP의 배열-1에 소개되어 있다). 예를 들면, PHP의 배열-1 기사에서 우리는 다음과 같이 array 문을 이용해서 일차원 배열을 생성하는 것에 대해 알아보았다.

<?php
  $foo = array(0=>"abc",
               1=>"def",
               2=>"ghi");
?>
여기에서 인덱스 0,1,2는 각각 다른 문자열에 연결되어 있다. 다차원 배열에서는 간단히 위의 연결 중에 하나를 문자열이 아닌 배열을 가리키는 것에 연결하면 된다. 다음의 예를 보자.

<?php

  $emails = array("john"=>"john@coggeshall.org",
                  "dan"=>"dan@somewhere.com",
                  "rachel"=>"rachel@coggeshall.org");

  $foo = array(0=>"abc",
               1=>$emails,
               2=>"ghi");
?>
배열 $foo의 인덱스 1의 값을 역시 배열인 $emails로 대신했으며 이는 다차원 배열을 생성한 것이다. 또한 PHP의 배열-1에서 소개했듯이 $foo에 간단히 값을 추가할 수 있음을 주목하자.

<?php	$foo[] = $emails; ?>
위와 같이 쓴다면 인덱스 3을 자동으로 생성하고 그 값을 $email 배열로 할 것이다. 이러한 연결을 우리가 생성했다면, 다음과 같은 문법으로 $foo에 포함된 배열인 $email에 새로운 인덱스를 추가할 수 있다.

<?php $foo[3]['steve'] = "steve@somewhere.com";
 
$foo의 3번째 인덱스가 배열이기 때문에, $foo 변수에 []를 추가적으로 붙여 그 배열에 접근할 수 있다. 위의 예는 $foo 배열의 3번째 인덱스에 위치한 배열에 4번째 항목을 추가하는 것을 보여주는데, 인덱스에 steve를, 그리고 그 값에 "steve@somewhere.com"를 할당한다. 다소 혼동스럽지만, 실제로 사용할 때에는 $foo[3]와 $foo_3(일반적인 변수 이름)가 거의 같다는 점만 이해하면 된다. 배열의 인덱스를 바로 참조할 때엔 나머지 컨텐츠는 별로 중요하지 않으므로, 복잡한 다차원 배열을 시각화할 땐 무시해 버리는 게 낫다. 배열로 작업하기와 데이터 얻기 배열을 사용하는 데 도움을 주는 몇몇 함수에 대해 간단히 알아보고(앞으로의 기사에서 이러한 함수를 살펴 볼 것이다), PHP에서 배열의 강력함을 증가시킬 수 있는 새로운 컨트롤 구조인 foreach를 소개하겠다. 이미 언급했듯이 PHP에는 배열을 조작하고 분석하고 이용할 수 있는 미리 프로그램된 함수들(built-in)이 많이 있다. 이러한 함수들의 완벽한 리스트를 얻으려면 PHP 웹 매뉴얼 레퍼런스의 arrays 부분을 참조하기 바란다. 환경만 적절하게 설정해 주면 이러한 함수는 매우 유용하다. 여기에서는 PHP에서 배열을 사용하는 데 반드시 필요한 것들만 알아보겠다. 이 함수는 is_array()와 in_array()와 count()이다. 유용한 배열 함수 여기에 배열을 다루는 데 필요한 유용한 함수들이 있다.
  • is_array($val) - 변수가 배열인지 여부를 조사. 배열이면 true를 리턴, 배열이 아니면 false를 리턴함.
  • in_array($needle, $haystack, $strict) - 배열 $haystack에 $needle의 값이 있는지를 조사. 세 번째 매개 변수인 $strict가 true로 설정되면 $needle의 값이 $haystack에 있는지를 조사하는데 type도 일치해야 함. $strict의 기본값은 false임.
  • count($val) - 배열에 포함된 요소의 수를 리턴. $val의 값이 유효한 PHP 변수가 아니라면 에러를 발생하는 대신 0을 리턴. 정확한 리턴값을 보장하려면 count()를 부르기 전에 is_array()를 부르는 것을 추천.
이 함수의 완벽한 문서와 사용 예를 원한다면, PHP 매뉴얼을 참조하자. 새로운 컨트롤 구조 : foreach PHP에서 개발자들이 사용 가능한 모든 컨트롤 구조 중에서 foreach는 배열에 사용 가능한 유일한 함수이다. 기능은 for 문장과 매우 비슷하지만, 문법은 그렇지 않다. 이 함수는 개발자에게 배열(정수 인덱스를 사용하는 일반 배열과 연관 배열)의 내용을 탐색하고 배열 내의 각 요소를 이용할 수 있는 빠르고 쉬운 방법을 제공한다. 예를 들면, 배열 요소의 크기를 모르는 인덱스(index)로 정수를 사용하는 배열이 있고 각 요소의 값을 출력하고자 한다고 하자. 이는 물론 아래처럼 for 문과 count() 문을 이용하면 된다.

<?php
  for($i = 0; $i < count($myarray); $i++) {
    echo $myarray[$i];
  }
?>
 
물론 이러한 방법에 잘못된 점은 하나도 없다. 그러나 배열이 정수 인덱스를 사용하는 게 아니라 연관 배열이라면 어떨까? 이러한 상황에서는 적어도 두 개 이상의 함수와 결합된 복잡한 while 문으로 같은 결과를 가져올 수 있지만 더 좋은 방법이 있다. 바로foreach 문이다. foreach의 문법은 아래와 같다.

foreach($array_val as [$key_val =>] $value) {
	...
}
또한 for() endfor;와 문법이 비슷하다.

foreach($array_val as [$key_val =>] $value):
   ...
endforeach;
$array_val는 배열, $key_val은 현재 인덱스를 저장하기 위한 변수, $value는 인덱스에 연결된 실제 값을 저장하는 변수. 어떻게 작동하는가 다음 두 가지 foreach 예문을 살펴보자.

<?php
  $myarray = array("foo"=>"bar",
                       0=>5,
              "mynumber"=>12e3);
  foreach($myarray as $value) {
    echo "The value is $value<br />";
  }
  echo "<br />";
  foreach($myarray as $key=>$value) {
    echo "The value of index $key is $value<br />";
  }
?>
위의 코드에서 세 개의 값을 갖고 있는 $myarray를 생성하였다. 첫 번째 요소는 문자열 "foo"를 인덱스로 그 값으로 "bar"를 갖고 있고, 두 번째 요소는 정수 인덱스 0을 그 값으로 5를, 마지막으로 세 번째 요소는 문자열 "mynumber"를 인덱스로 값으로 12e3(=12000)을 갖고 있다. 이 배열에 foreach 문의 두 가지 문법을 모두 적용해 보았다. 결과는 다음과 같다.

The value is bar
The value is 5
The value is 12000
The value of index foo is bar
The value of index 0 is 5
The value of index mynumber is 12000
두개의 foreach 문의 결과를 비교해 보면, 두 가지 문법이 전체 배열을 모두 탐색했고 각 인덱스에 저장된 값을 $value 변수에 저장했음을 알 수 있다. 하지만 두 번째 foreach 문에선 인덱스에 저장된 값뿐만 아니라, 인덱스 자체의 값을 저장할 변수를 지정하였다. 그 결과는 우리가 배열의 값만을 탐색하는 것뿐만 아니라, 인덱스와 그 값 사이의 연관관계를 검색하고 유지할 수 있다는 것을 의미한다. 이는 배열의 인덱스가 어떤 형식인지 상관없이 배열 내의 요소를 빠르고 쉽게 조작할 수 있게 하므로, 배열을 다룰 때 매우 강력하고 유용한 툴이다. 배열 탐색을 사용하는 곳에서는 for 반복문 대신 foreach 문을 사용할 것을 강력히 추천한다. 주의 : 이번 foreach 문의 예에서 $key와 $value를 사용했지만, 그 변수 이름은 PHP에서 유효한 어떤 변수 이름이라도 올 수 있다(물론 그 변수가 스크립트 내의 다른 곳에서 쓰이지 않아야 한다). 존 코그셸(John Coggeshall)은 10년 이상 프리랜서로 웹 컨설턴트와 그래픽 디자인 일을 해 왔으며, PHP를 사용한 지는 5년 남짓 되었다. 이호재님은 한빛 리포터 1기로 활동 중입니다. 카드코리아 개발 실장으로 근무한 경험이 있으며, 지금은 서울대 지구환경시스템공학부(컴퓨터 공학)에 다니고 있습니다. 컴퓨터에 관련된 모든 분야에 두루 관심이 많으며, 요즈음엔 파이썬, MPI, PHP 등에 관심이 많습니다. 지난 번 기사에 관심을 보여 주신 한빛 독자 여러분에게 감사의 말씀을 전한다고 합니다.


출처 : http://www.hanb.co.kr/network/view.html?bi_id=156