다차원 배열에서 특정 열만 추출해야 할 때 대부분의 개발자는 foreach 루프를 돌거나 array_map을 쓴다. 다만 코드가 길어지고 가독성이 떨어지는 경우가 많다. 이번에는 array_column() 함수로 이 문제를 어떻게 깔끔하게 해결하는지, 실제 사용 사례와 함께 완벽하게 정리해서 소개하겠다.

 

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: 반환 배열의 키로 사용할 열 (선택사항)

 

실전 예제 1: 사용자 이름만 추출하기

✗ 잘못된 방법(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] => 박민준 )

한 줄이면 끝난다. 훨씬 간결하고 명확하다.

 

실전 예제 2: 사용자 ID를 키로 하고 이메일을 값으로 추출

✗ 잘못된 방법

$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 응답 매핑할 때 매우 유용한 패턴이다.

 

실전 예제 3: 객체 배열에서 속성 추출

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 응답 배열, 객체 컬렉션을 다룰 때 이 함수를 기본으로 삼으면 코드 가독성이 크게 올라간다. 이 글의 세 가지 예제 패턴(단순 열 추출, 키 지정, 객체 배열)을 참고해 실무에서 바로 적용하면, 배열 처리 코드를 훨씬 깔끔하게 정리할 수 있을 것이다.