다차원 배열에서 특정 열만 추출해야 할 때 대부분의 개발자는 foreach 루프를 돌거나 array_map을 쓴다. 다만 코드가 길어지고 가독성이 떨어지는 경우가 많다. 이번에는 array_column() 함수로 이 문제를 어떻게 깔끔하게 해결하는지, 실제 사용 사례와 함께 완벽하게 정리해서 소개하겠다.
array_column()은 다차원 배열이나 객체 배열에서 특정 열(column)의 값들을 추출해 새로운 배열로 반환하는 PHP 내장 함수다. 데이터베이스 쿼리 결과에서 특정 컬럼만 뽑아낼 때나 API 응답 배열에서 필요한 필드만 수집할 때 매우 유용하다.
array_column(array $array, int|string|null $column_key, int|string|null $index_key = null): array
- $array: 대상이 되는 다차원 배열 또는 객체 배열
- $column_key: 추출할 열의 키 이름 또는 인덱스 (null이면 전체 배열 반환)
- $index_key: 반환 배열의 키로 사용할 열 (선택사항)
✗ 잘못된 방법(foreach 루프)
$users = [
['id' => 1, 'name' => '김철수', 'email' => 'kim@example.com'],
['id' => 2, 'name' => '이영희', 'email' => 'lee@example.com'],
['id' => 3, 'name' => '박민준', 'email' => 'park@example.com'],
];
$names = [];
foreach ($users as $user) {
$names[] = $user['name'];
}
print_r($names);
// Array ( [0] => 김철수 [1] => 이영희 [2] => 박민준 )
코드가 3줄이나 들어가고 임시 배열을 선언해야 한다. 간단한 작업치고 너무 번거롭다.
✓ 올바른 방법(array_column)
$users = [
['id' => 1, 'name' => '김철수', 'email' => 'kim@example.com'],
['id' => 2, 'name' => '이영희', 'email' => 'lee@example.com'],
['id' => 3, 'name' => '박민준', 'email' => 'park@example.com'],
];
$names = array_column($users, 'name');
print_r($names);
// Array ( [0] => 김철수 [1] => 이영희 [2] => 박민준 )
한 줄이면 끝난다. 훨씬 간결하고 명확하다.
✗ 잘못된 방법
$users = [
['id' => 1, 'name' => '김철수', 'email' => 'kim@example.com'],
['id' => 2, 'name' => '이영희', 'email' => 'lee@example.com'],
['id' => 3, 'name' => '박민준', 'email' => 'park@example.com'],
];
$emailMap = [];
foreach ($users as $user) {
$emailMap[$user['id']] = $user['email'];
}
print_r($emailMap);
// Array ( [1] => kim@example.com [2] => lee@example.com [3] => park@example.com )
✓ 올바른 방법
$users = [
['id' => 1, 'name' => '김철수', 'email' => 'kim@example.com'],
['id' => 2, 'name' => '이영희', 'email' => 'lee@example.com'],
['id' => 3, 'name' => '박민준', 'email' => 'park@example.com'],
];
$emailMap = array_column($users, 'email', 'id');
print_r($emailMap);
// Array ( [1] => kim@example.com [2] => lee@example.com [3] => park@example.com )
세 번째 파라미터 $index_key에 'id'를 넣으면 ID를 키로 하는 연결 배열이 완성된다. 데이터베이스 검색이나 API 응답 매핑할 때 매우 유용한 패턴이다.
array_column()은 배열뿐 아니라 객체 배열에서도 작동한다.
class User {
public $id;
public $name;
public $email;
public function __construct($id, $name, $email) {
$this->id = $id;
$this->name = $name;
$this->email = $email;
}
}
$users = [
new User(1, '김철수', 'kim@example.com'),
new User(2, '이영희', 'lee@example.com'),
new User(3, '박민준', 'park@example.com'),
];
$names = array_column($users, 'name');
print_r($names);
// Array ( [0] => 김철수 [1] => 이영희 [2] => 박민준 )
$emailMap = array_column($users, 'email', 'id');
print_r($emailMap);
// Array ( [1] => kim@example.com [2] => lee@example.com [3] => park@example.com )
ORM(예: Eloquent, Doctrine) 쿼리 결과가 객체 배열로 반환될 때 이 패턴이 특히 유용하다.
✗ 존재하지 않는 키로 접근할 때
$users = [
['id' => 1, 'name' => '김철수'],
['id' => 2, 'name' => '이영희'],
];
$emails = array_column($users, 'email'); // 'email' 키가 없음
print_r($emails);
// Array ( [0] => [1] => ) - 빈 값들로 채워짐
존재하지 않는 키를 요청하면 NULL 값으로 배열이 채워진다. 사전에 데이터 구조를 확인하자.
✓ 올바른 사용
$users = [
['id' => 1, 'name' => '김철수', 'email' => 'kim@example.com'],
['id' => 2, 'name' => '이영희', 'email' => 'lee@example.com'],
];
$emails = array_column($users, 'email');
print_r($emails);
// Array ( [0] => kim@example.com [1] => lee@example.com )
✗ 중첩된 배열 구조에서 깊은 키 접근 불가
$data = [
['user' => ['name' => '김철수', 'email' => 'kim@example.com']],
['user' => ['name' => '이영희', 'email' => 'lee@example.com']],
];
$names = array_column($data, 'user'); // 'user' 배열만 추출됨
print_r($names);
// Array ( [0] => Array ( [name] => 김철수 [email] => kim@example.com ) [1] => ... )
$names = array_column($data, 'user.name'); // 이건 작동 안 함
print_r($names);
// Array ( [0] => [1] => ) - 원하는 결과 아님
array_column()은 1단계 깊이만 지원한다. 더 깊은 구조는 array_map과 함수형 프로그래밍을 조합해야 한다.
PDO나 MySQLi로 가져온 결과 배열에서 특정 컬럼만 필요할 때가 자주 있다.
$pdo = new PDO('mysql:host=localhost;dbname=mydb', 'user', 'pass');
$stmt = $pdo->query('SELECT id, name, email FROM users WHERE active = 1');
$users = $stmt->fetchAll(PDO::FETCH_ASSOC);
// 모든 사용자 ID만 필요할 때
$userIds = array_column($users, 'id');
// [1, 2, 3, ...]
// ID별로 이메일을 맵핑해야 할 때
$emailMap = array_column($users, 'email', 'id');
// [1 => 'kim@example.com', 2 => 'lee@example.com', ...]
// API 응답용으로 이름만 배열로 줄 때
$names = array_column($users, 'name');
// ['김철수', '이영희', ...]
데이터베이스 쿼리 후 바로 array_column()을 써서 필요한 형태로 변환하면 코드가 간결해진다.
array_column()은 C 레벨에서 최적화되어 있어 foreach 루프보다 빠르다. 대용량 배열(수천 개 요소)도 빠르게 처리한다. 다만 조건부 필터링(WHERE 같은)이 필요하면 array_filter()와 함께 조합하자.
$users = [
['id' => 1, 'name' => '김철수', 'active' => 1],
['id' => 2, 'name' => '이영희', 'active' => 0],
['id' => 3, 'name' => '박민준', 'active' => 1],
];
// active=1인 사용자의 이름만 추출
$activeUsers = array_filter($users, fn($user) => $user['active'] == 1);
$activeNames = array_column($activeUsers, 'name');
print_r($activeNames);
// Array ( [0] => 김철수 [2] => 박민준 )
array_column()은 다차원 배열에서 특정 열을 추출할 때 가장 간결하고 빠른 방법이다. foreach 루프나 array_map의 복잡한 콜백 없이 한 줄로 원하는 데이터 형태를 만들 수 있다는 점이 강점이다. 데이터베이스 쿼리 결과, API 응답 배열, 객체 컬렉션을 다룰 때 이 함수를 기본으로 삼으면 코드 가독성이 크게 올라간다. 이 글의 세 가지 예제 패턴(단순 열 추출, 키 지정, 객체 배열)을 참고해 실무에서 바로 적용하면, 배열 처리 코드를 훨씬 깔끔하게 정리할 수 있을 것이다.