본문 바로가기

비개발자의 개발 일지

현장 팀장에서 수출 ERP까지 — AI와 함께 시스템을 만든 기록

시리즈 보기
php

PHP array_shift() — 배열 앞 요소 제거 · 큐 패턴 · array_pop()과 비교 완전 정리

by 왕진 2026. 7. 9.
반응형

 

 

Web Development · PHP 배열 조작

PHP array_shift() — 배열 앞 요소 제거 · 큐 패턴 · array_pop()과 비교 완전 정리

배열의 첫 번째 요소를 제거하면서 반환 — 제거 후 남은 요소들의 인덱스가 0부터 재정렬되는 차이를 이해하는 것이 핵심
시작 오늘 분석할 코드

array_shift()는 배열의 첫 번째(앞) 요소를 제거하고 그 값을 반환한다. 제거 후 남은 요소들은 인덱스가 0부터 다시 번호가 매겨진다(재정렬). 이 인덱스 재정렬이 array_pop()과 가장 큰 차이다.

<?php $data = array("사과", "귤", "감"); $apple = array_shift($data); // 첫 번째 요소 제거 + 반환 print $apple; // 사과 print "<PRE>"; print_r($data); print "</PRE>"; ?>
제거 전 $data
Array
(
  [0] => 사과
  [1] => 귤
  [2] => 감
)
array_shift() 후 — 인덱스 재정렬!
Array
(
  [0] => 귤  ← 기존 [1]
  [1] => 감  ← 기존 [2]
)

$apple = "사과"
"사과"(인덱스 0)가 제거되고 귤·감이 0,1로 재정렬됨
용어 핵심 용어 정리
array_shift()배열 첫 번째 요소를 제거하고 반환 — 빈 배열이면 NULL
인덱스 재정렬제거 후 남은 모든 요소의 숫자 인덱스가 0부터 재배치 — 문자열 키는 유지
FIFO 큐push(뒤추가) + shift(앞제거) = First In First Out — 먼저 넣은 것이 먼저 나옴
array_pop() 차이pop = 뒤에서 제거(인덱스 그대로) / shift = 앞에서 제거(인덱스 재정렬)
array_unshift() 짝unshift(앞추가) + shift(앞제거) = 앞에서 넣고 앞에서 꺼내는 조작
성능 주의배열이 클수록 인덱스 재정렬 비용 증가 — pop은 O(1), shift는 O(n)

1 array_pop() vs array_shift() — 인덱스 차이
array_pop() — 뒤 제거, 인덱스 유지
$data = ["사과","귤","감"];
$last = array_pop($data);
// $last = "감"
// $data = {0:"사과", 1:"귤"} (그대로)
array_shift() — 앞 제거, 인덱스 재정렬
$data = ["사과","귤","감"];
$first = array_shift($data);
// $first = "사과"
// $data = {0:"귤", 1:"감"} (재정렬)

2 FIFO 큐 패턴 — 작업 대기열

array_push()로 대기열 뒤에 작업을 추가하고, array_shift()로 앞에서 꺼내 처리하면 FIFO(선입선출) 큐가 된다. 먼저 등록된 요청이 먼저 처리되는 패턴이다.

$queue = []; array_push($queue, "요청A"); // [요청A] array_push($queue, "요청B"); // [요청A, 요청B] array_push($queue, "요청C"); // [요청A, 요청B, 요청C] // 선입선출로 처리 while (!empty($queue)) { $job = array_shift($queue); print "처리: $job<br>"; } // 처리: 요청A (먼저 등록된 것 먼저) // 처리: 요청B // 처리: 요청C

3 연관 배열에서의 array_shift() — 문자열 키 유지, 숫자 키만 재정렬

array_shift()는 숫자 인덱스만 재정렬한다. 문자열 키(연관 배열 키)는 재정렬되지 않고 그대로 유지된다.

$assoc = ["apple"=>"사과", "orange"=>"귤", "kaki"=>"감"]; $first = array_shift($assoc); // $first = "사과" print_r($assoc); // Array ( [orange] => 귤 [kaki] => 감 ) // 문자열 키(orange, kaki)는 그대로 유지됨
※ 인덱스 재정렬은 숫자 인덱스에만 적용된다. 연관 배열의 문자열 키는 array_shift() 후에도 변하지 않는다.

 

반응형

 

4 배열 앞에서 N개 제거 — array_splice() 조합

array_shift()는 한 번에 1개만 제거한다. 앞에서 N개를 한 번에 제거하려면 array_splice()를 사용한다. 작은 배열에서는 shift를 여러 번 호출해도 무방하다.

$data = ["A", "B", "C", "D", "E"]; // 앞에서 1개 제거 (array_shift) $first = array_shift($data); // "A" 제거 // 앞에서 2개 한 번에 제거 (array_splice) $removed = array_splice($data, 0, 2); // ["B","C"] 제거 // $data 남은 것: ["D","E"] // 앞에서 N개 건너뛰고 나머지만 (array_slice) $rest = array_slice($data, 2); // 인덱스 2부터 끝까지

5 배열 조작 함수 4종 — shift 위치 확인
함수 위치 동작 반환값 인덱스 재정렬
array_push() 추가 배열 길이 없음
array_pop() 제거 제거된 값 없음
array_unshift() 추가 배열 길이 있음 (기존 요소 뒤로)
array_shift() 제거 제거된 값 있음 (0부터 재번호)

5 reset() vs array_shift() — 첫 값 읽기 vs 제거

첫 번째 요소를 확인만 하고 제거하지 않으려면 reset()을 사용한다. array_shift()는 배열을 직접 수정하지만, reset()은 내부 포인터를 처음으로 이동해 첫 번째 값만 반환한다.

reset() — 읽기만 (배열 유지)
$data = ["사과","귤","감"];
$first = reset($data);
// $first = "사과"
// $data = ["사과","귤","감"] ← 그대로
array_shift() — 제거+반환 (배열 변경)
$data = ["사과","귤","감"];
$first = array_shift($data);
// $first = "사과"
// $data = ["귤","감"] ← 변경됨
※ 첫 요소를 확인만 하려면 reset() — 배열을 유지한 채 첫 값만 읽는다. 꺼내서 처리하려면 array_shift() — 제거되므로 백업 없이 복구 불가.

7 성능 — 왜 shift는 pop보다 느린가

array_pop()은 마지막 요소만 제거하면 끝이라 O(1) 상수 시간이다. 반면 array_shift()는 첫 요소를 제거한 뒤 나머지 모든 요소의 인덱스를 1씩 줄여야(재정렬) 하므로 O(n) 선형 시간이다. 배열이 크면 shift는 눈에 띄게 느리다. 작은 배열(수십 개 이하)에서는 체감 차이 없으므로 실무에서 shift를 피할 필요는 없다.

// 1만 개 배열에서 반복 제거 성능 비교 (개념) array_pop($arr) → 마지막 제거만 → O(1) array_shift($arr) → 앞 제거 + 전체 인덱스 재정렬 → O(n) // 반복 루프에서 shift 1만 번 vs pop 1만 번 // shift: 인덱스 재정렬이 누적 → 합산 O(n^2) 최악 // pop: 재정렬 없음 → 합산 O(n) // 대용량 큐가 필요하면 SplQueue(PHP SPL) 사용을 고려 $q = new SplQueue(); $q->enqueue("항목"); $q->dequeue(); // O(1) 큐 구조

6 자주 하는 실수
실수 증상 해결
shift 후 기존 인덱스로 접근 $data[1] 이 shift 전 "귤"이었으나 shift 후 "감"이 됨 shift 후 인덱스로 접근 자제 — 필요 시 재참조
빈 배열 shift → NULL 처리 안함 $v = null → 문자열 비교 오류 if (!empty($arr)) { $v = array_shift($arr); }
대용량 루프에 shift 반복 O(n) 재정렬 × 반복 횟수 = 성능 저하 큰 큐는 SplQueue 또는 인덱스 포인터 방식 사용
shift와 pop 방향 혼동 뒤에서 제거될 것이 앞에서 제거됨 shift = 앞(첫 번째) / pop = 뒤(마지막)
shift 반환값 무시 후 나중에 필요 제거된 값 복구 불가 $removed = array_shift($arr); 로 변수에 먼저 받기
NULL 반환값을 문자열과 직접 비교 빈 배열 shift → null == "" → 예상치 않은 true if ($v !== null && $v === "비교값") — 타입 엄격 비교

핵심 한 줄 요약

array_shift($arr)배열 첫 번째 요소 제거 + 반환 — 남은 요소 인덱스 0부터 재정렬
인덱스 재정렬shift 후 귤→[0], 감→[1] — array_pop()은 인덱스 변화 없음
FIFO 큐 쌍push(뒤추가) + shift(앞제거) = FIFO / push+pop = LIFO 스택
문자열 키 유지연관 배열에서 shift 후 문자열 키는 재정렬 없이 그대로 유지
O(n) 성능 주의배열 크면 shift는 전체 재정렬 비용 → 대용량 큐는 SplQueue 고려
NULL 방어if (!empty($arr)) { $v = array_shift($arr); } — 빈 배열 방지
연관배열 적용연관 배열 첫 요소 제거도 array_shift() 가능 — 문자열 키는 보존
4함수 선택뒤추가=push / 뒤제거=pop / 앞추가=unshift / 앞제거=shift
reset() 비교reset() = 첫 요소 읽기만 (배열 유지) / shift = 읽기+제거 (배열 변경)
반복 큐 처리while (!empty($q)) { $job = array_shift($q); ... } → FIFO 작업 대기열
SplQueue 대안대용량 FIFO 큐는 PHP SPL의 SplQueue — enqueue()/dequeue()로 O(1) 처리
연관 배열 키 보존문자열 키는 shift 후에도 재정렬 없이 그대로 — 숫자 인덱스만 재배치
N개 앞 제거shift는 1개씩 / 여러 개 한 번에 제거 = array_splice($arr, 0, N)
null vs 빈 배열 구분shift 반환 null = 빈 배열 / 빈 문자열 ""과 null은 다름 — 타입 비교 중요
while FIFO 처리while (!empty($q)) { $job = array_shift($q); } → 작업 대기열 순서 처리

Tags

#PHP #array_shift #배열앞제거 # #FIFO #array_pop #배열함수 #PHP함수 #PHP학습 #웹개발 #티스토리 #인덱스재정렬 #앞에서제거
▼ 티스토리 태그 입력란 복사용
PHP, array_shift, 배열앞제거, 큐, FIFO, array_pop, 배열함수, PHP함수, PHP학습, 인덱스재정렬

 

 

반응형

댓글