본문 바로가기

비개발자의 개발 일지

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

시리즈 보기
php

PHP static 변수 — 호출 사이에 값을 기억시키는 누적 카운터 완전 정리

by 왕진 2026. 6. 14.
반응형

 

 

Web Development · PHP static

PHP static 변수 —
호출 사이에 값을 기억하는 카운터

한 줄 차이로 0,0,0,0,0 → 0,1,2,3,4 가 되는 이유
시작 오늘 분석할 코드

앞서 본 static1.php와 거의 같은데 딱 한 단어가 다르다 — $data = 0 앞에 static이 붙었다. 이 한 줄로 카운터가 0부터 4까지 정상 누적된다.

<?php counter(); counter(); counter(); counter(); counter(); function counter(){ static $data = 0; // $data에 저장되어 변경된 값이 계속 누적되어 전달됨 print $data ++; print "<BR>"; } ?>
실제 출력 결과
0
1
2
3
4

의도대로 0, 1, 2, 3, 4가 차례로 출력된다.

용어 용어 정리
static호출 사이에 값을 유지시키는 키워드
정적 변수static 키워드로 선언된 함수 내 변수
한 번만 초기화최초 호출 시에만 = 0이 실행됨
다음 호출이전에 변경된 값으로 시작
함수 격리바깥에선 안 보임 — 함수 내부에만
vs global상태 유지는 같지만 노출 범위가 다름
vs 클래스 static같은 단어지만 의미 다름 (객체에서)
$data++현재 값 사용 후 +1

1 static의 효과 한 문장
"이 변수는 처음 호출 때만 초기화하고, 그 다음부터는 이전 값을 기억해서 다시 쓰라"

그게 전부다. 그러나 이 한 줄이 함수의 동작을 근본적으로 바꾼다.


2 무엇이 다른가 — static1과 static2 비교
static 없음 (static1)
$data = 0;
매 호출마다 0으로 리셋
결과: 0,0,0,0,0
static 있음 (이 코드)
static $data = 0;
최초만 0, 이후 누적
결과: 0,1,2,3,4

3 5번 호출 단계별 추적
1
1번째 counter()최초 호출 → static $data = 0 실행 → print 0 → $data = 1로 보존
2
2번째 counter()"= 0"은 다시 실행 안 함 → 직전 $data=1 사용 → print 1 → $data = 2 보존
3
3번째 counter()$data=2 사용 → print 2 → $data = 3 보존
4
4번째 counter()$data=3 사용 → print 3 → $data = 4 보존
5
5번째 counter()$data=4 사용 → print 4 → $data = 5 보존 (사용은 안 됨)
핵심: static $data = 0;최초 한 번만 초기화로 작동하고, 그 다음부터는 "이미 있으니 그냥 통과"한다.

 

반응형

 

4 static의 메모리 모델

일반 지역 변수는 스택(stack)에 잠깐 만들어졌다 사라진다. static 변수는 별도의 영속 영역에 보관되어 함수 호출이 끝나도 사라지지 않는다.

[일반 지역 변수] [static 변수] 함수 호출 → 메모리 할당 함수 호출 → 기존 값 그대로 사용 함수 종료 → 메모리 해제 함수 종료 → 메모리 그대로 보존 다음 호출 → 새로 할당 다음 호출 → 같은 메모리 재사용

5 static과 global의 차이
비교 static global
값 유지 호출 사이 유지 전역에 늘 살아있음
접근 범위 해당 함수 안에서만 전역 + global 선언한 함수
외부 노출 안 됨 (함수 내부 비밀) 완전 노출
이름 충돌 같은 이름 다른 함수에 따로 보존 전역 이름 충돌 가능
적합한 용도 함수의 내부 카운터·캐시 여러 함수가 공유하는 값
즉 static은 "함수에게만 비밀 공책을 하나 줘서 거기에 적게 하는" 모델이다. 다른 함수나 외부 코드는 그 공책에 접근할 수 없다.

6 실용 예 — 캐시(memoization)

static의 가장 흔한 실무 활용은 한 번 계산한 결과를 보관해서 다음 호출에 재사용하는 패턴.

function getConfig() { static $cache = null; if ($cache === null) { $cache = json_decode(file_get_contents('config.json'), true); // 무거운 작업 (파일 읽기) → 한 번만 } return $cache; // 이후 호출은 메모리에서 즉시 반환 }
※ static 캐시 패턴의 장점
  • 비싼 연산(파일·DB·네트워크)을 한 번만
  • 같은 함수를 여러 번 호출해도 빠름
  • 함수 외부에 캐시 변수를 노출하지 않음
  • 함수가 자기 책임으로 캐시 관리

7 자주 하는 실수
실수 증상 해결
static 빼먹음 매번 0으로 리셋 (static1 결과) 변수 선언 앞에 static 추가
static $x = expensive() 최초 1번이라도 호출 초기값은 상수만 가능 (PHP 8.1까진)
static $x; (= 없이) null로 시작 의도가 null이면 OK, 아니면 명시
static 변수가 다른 호출에서 보일 거라 기대 같은 함수 안에서만 보임 외부 공유 필요 시 클래스 속성
스레드/병렬 환경에서 static 의존 경합 조건 (PHP-FPM은 보통 OK) 요청 단위로만 의존

8 객체지향에선? — 클래스 속성

객체지향 코드에서는 static 변수 대신 클래스 속성을 쓰는 게 자연스럽다.

class Counter { private $data = 0; // 인스턴스 속성 public function next() { return $this->data++; } } $c = new Counter(); echo $c->next(); // 0 echo $c->next(); // 1 echo $c->next(); // 2
클래스 속성은 static 변수의 자연스러운 발전 형태. 동시에 여러 카운터(객체 인스턴스)를 만들 수 있다는 추가 이점이 있다.

9 static의 의의

static은 "함수가 자기 상태를 갖되, 외부에 노출하지 않는다"는 절충안이다. 전역 변수의 단점(노출, 충돌)과 지역 변수의 단점(기억 못함)을 동시에 해결한다.

※ static을 쓸 때
  • 호출 횟수, 호출별 ID 부여
  • 한 번만 계산해 캐시 (memoization)
  • 지연 초기화 (lazy initialization)
  • 이전 호출의 결과를 비교해야 할 때

핵심 한 줄 요약

static호출 사이에 값을 유지하는 함수 내 변수
초기화최초 호출 시 한 번만, 이후엔 이전 값 사용
출력 0,1,2,3,4한 줄 차이로 카운터 정상 누적
vs global함수 내부 비밀 변수 — 외부 노출 없음
메모리스택이 아닌 별도 영속 영역에 보관
실무 활용카운터·캐시·지연 초기화
객체지향클래스 속성으로 자연스럽게 대체 가능
반응형

댓글