배열에서 특정 키들만 빼내야 할 때가 있다. 보통 개발자들은 반복문을 돌려서 foreach로 하나씩 담거나, 더 복잡한 경우 정규표현식을 섞어가며 처리한다. 다만 PHP에서 제공하는 array_keys() 함수의 정확한 동작과 검색 필터링 옵션을 모르는 경우가 많다. 이번에는 array_keys()의 기본 사용법부터 검색 값 필터링, 엄격한 타입 비교까지 완벽하게 정리해서 소개하겠다.
array_keys()는 배열의 모든 키를 새로운 배열로 반환하는 함수다. 단순하게 들리지만, 선택적 매개변수로 특정 값을 가진 키만 필터링할 수 있다.
함수 선언은 다음과 같다.
array_keys(array $array, mixed $filter = null, bool $strict = false): array
매개변수를 설명하면 첫 번째는 대상 배열, 두 번째는 선택적 검색 값, 세 번째는 타입 엄격 비교 여부다.
$user = array(
'id' => 1,
'name' => 'John',
'email' => 'john@example.com',
'status' => 'active'
);
$keys = array_keys($user);
print_r($keys);
// 출력: Array ( [0] => id [1] => name [2] => email [3] => status )
모든 키가 새 배열로 반환되고, 원본 배열의 타입(연관 배열)과 관계없이 항상 0부터 시작하는 인덱스 배열로 반환된다.
두 번째 매개변수에 값을 지정하면, 그 값을 가진 키들만 반환된다.
$roles = array(
'admin' => 'active',
'editor' => 'active',
'viewer' => 'inactive',
'guest' => 'inactive'
);
$active_roles = array_keys($roles, 'active');
print_r($active_roles);
// 출력: Array ( [0] => admin [1] => editor )
이렇게 하면 'active' 값을 가진 키들(admin, editor)만 추출된다. 반복문으로 하나하나 확인하는 것보다 훨씬 간결하다.
숫자를 다룰 때는 타입 자동 변환으로 예상 밖의 결과가 나올 수 있다.
✗ 잘못된 방식 (타입 변환으로 오류)
$scores = array(
'player1' => 100,
'player2' => '100',
'player3' => 50,
'player4' => true
);
$result = array_keys($scores, 100);
print_r($result);
// 출력: Array ( [0] => player1 [1] => player2 [2] => player4 )
// player2(문자 '100')와 player4(true)까지 매칭됨. 왜? PHP에서 100 == '100' == true이기 때문
이 문제를 해결하려면 세 번째 매개변수 $strict를 true로 설정해야 한다.
✓ 올바른 방식 (엄격한 타입 비교)
$scores = array(
'player1' => 100,
'player2' => '100',
'player3' => 50,
'player4' => true
);
$result = array_keys($scores, 100, true);
print_r($result);
// 출력: Array ( [0] => player1 )
// player1만 정확히 int 100과 일치
세 번째 인자를 true로 주면 === 연산자로 비교하므로, 타입과 값이 완벽히 일치해야만 필터링된다.
$config = array(
'database_enabled' => true,
'cache_enabled' => false,
'logging_enabled' => true,
'email_enabled' => false,
'api_enabled' => true
);
// 활성화된 기능들의 키만 필요할 때
$enabled_features = array_keys($config, true);
echo implode(', ', $enabled_features);
// 출력: database_enabled, logging_enabled, api_enabled
// 이를 이용해 활성화된 모듈만 로드
foreach ($enabled_features as $feature) {
load_module($feature);
}
설정 배열에서 true 값을 가진 기능들만 추출해서 초기화 로직에 사용한다. 반복문 없이도 필요한 키만 간단히 뽑아낼 수 있다.
$orders = array(
'order_001' => 'completed',
'order_002' => 'pending',
'order_003' => 'completed',
'order_004' => 'cancelled',
'order_005' => 'pending',
'order_006' => 'completed'
);
// 상태별로 주문 번호 분류
$completed = array_keys($orders, 'completed');
$pending = array_keys($orders, 'pending');
$cancelled = array_keys($orders, 'cancelled');
echo "완료: " . count($completed) . "건\n";
echo "대기: " . count($pending) . "건\n";
echo "취소: " . count($cancelled) . "건\n";
// 출력:
// 완료: 3건
// 대기: 2건
// 취소: 1건
대량의 배열 데이터를 상태별로 분류할 때 매우 유용하다. 데이터베이스 쿼리 결과나 API 응답을 빠르게 그룹화할 수 있다.
✗ 잘못된 처리
$status = array(
'user_1' => 'online',
'user_2' => 'offline',
'user_3' => 'online'
);
$sleeping = array_keys($status, 'sleeping');
echo count($sleeping); // 출력: 0
// 이 후 코드에서 $sleeping[0]에 접근하면 Notice 발생
echo $sleeping[0]; // PHP Warning: Undefined array key 0
검색 값이 배열에 없으면 빈 배열이 반환된다. 후속 처리에서 결과 배열을 바로 접근하면 오류가 난다.
✓ 올바른 처리
$status = array(
'user_1' => 'online',
'user_2' => 'offline',
'user_3' => 'online'
);
$sleeping = array_keys($status, 'sleeping');
if (empty($sleeping)) {
echo "해당 상태의 사용자가 없습니다.";
} else {
foreach ($sleeping as $user_id) {
notify_user($user_id);
}
}
항상 결과 배열이 비어있을 가능성을 고려해서 empty() 체크를 먼저 하자.
✗ 잘못된 사용
$mixed = array(
1 => 'apple',
'1' => 'orange', // 동일한 키로 덮어씌워짐
2 => 'banana'
);
$keys = array_keys($mixed);
print_r($keys);
// 출력: Array ( [0] => 1 [1] => 2 )
// 실제로는 문자 '1'은 정수 1로 변환되어 오버라이드됨
PHP는 숫자 문자열을 자동으로 정수로 변환한다. 의도하지 않은 키 중복이 발생할 수 있다.
✓ 올바른 방식
$mixed = array(
1 => 'apple',
'first' => 'orange', // 문자 키로 명확히 구분
2 => 'banana'
);
$keys = array_keys($mixed);
print_r($keys);
// 출력: Array ( [0] => 1 [1] => first [2] => 2 )
키를 명확하게 문자열로 작성해서 혼동을 피하자.
$users = array(
'admin' => array('name' => 'Alice', 'role' => 'admin'),
'editor' => array('name' => 'Bob', 'role' => 'editor'),
'viewer' => array('name' => 'Charlie', 'role' => 'viewer')
);
$keys = array_keys($users);
print_r($keys);
// 출력: Array ( [0] => admin [1] => editor [2] => viewer )
// 중첩 배열 내부의 키는 추출 불가
array_keys()는 첫 번째 레벨의 키만 추출한다. 중첩 배열 내부의 키가 필요하면 재귀 함수로 별도 처리해야 한다.
array_keys()는 배열 키 추출이라는 단순한 역할을 넘어, 검색 값 필터링과 엄격한 타입 비교로 강력한 데이터 분류 도구가 된다. 상태별 주문 분류, 활성화된 설정 추출, 사용자 역할 필터링 같은 실무에서 자주 마주치는 작업들을 한 줄의 함수 호출로 처리할 수 있다는 점이 핵심이다. 세 번째 매개변수 $strict를 true로 설정하면 타입 강제 변환으로 인한 예상 밖의 매칭을 완벽히 차단할 수 있으니, 숫자나 boolean 값을 다룰 때는 반드시 기억해두자. 이 글의 '검색 값 필터링' 부분과 '엄격한 타입 비교' 코드를 참고해 현재 프로젝트의 배열 필터링 로직을 점검해보면, 불필요한 반복문을 제거하고 코드 가독성을 한 단계 끌어올릴 수 있을 것이다.