본문 바로가기

프로그래밍/PHP

PHP 4버전과 그 이상의 버전에서의 STATIC 정적 변수


PHP는 서버사이드 언어로서 실행되는 곳은 서버PC 쪽에서 PHP 파일을 실시간으로 컴파일하여 그 결과물을 HTML 웹페이지로 생성시켜주는 인터프리터 입니다.

PHP는 객체 개념이 도입되고 지원된지 얼마 되지 않았습니다. 몇년전까지만 해도 접근제어자가 없었으니까요.

PHP4.X 버전에서는 접근제어자라는 개념이 PHP에 존재하지 않았습니다. 한마디로 데이터 은닉이 이루어 지지 않고 있었다는 뜻입니다. 모든 클래스의 멤버변수는 구조체와 동일하게 모두 public 제어자로 생성이 되게 됩니다.

지금도 몇몇 사이트에서는 업그레이드를 하지 않고 PHP4.X 버전을 그대로 사용하고 있지요.
현재는 접근제어자도 제공되고 namespace 는 물론 interface 까지 지원됩니다.

버전은 PHP 7.X 까지도 나왔구요. 7버전에서 4버전이 작동되지 않는다면 이전버전 사용자들은 모두 떠날 것 입니다. 또한 유지보수에 비용이 발생하지요. 따라서 호환성을 유지할 필요가 있었습니다.

PHP 인터프리터 중에서도 실시간 컴파일을 담당하는 부분을 Zend Engine 이라고 불리웁니다.
이러한 Zend 부분을 담당하는 개발자분들이 호환성을 위해 4.X 버전에서 멤버변수를 상위버전에서는 기본 public 접근 제어자로 인식하도록 호환성을 유지시켰습니다.
지금이야 클래스 작성 방식이 자바와 유사하지만 옛날 4.X 버전은 아래와 같았습니다.

소스코드 원문보기
  1. <?php 
  2. class ABC 
  3.     var $a = 0; 
  4.     var $b = 0; 
  5.     function ABC() { 
  6.           print "생성자"
  7.     } 
  8. $abc = new ABC(); 
  9. $abc->a = 10; 
  10. print $abc->a; 

위와 같이 접근제어자라는 개념이 없이 멤버변수를 var 라는 키워드로 선언한 것을 보실수 있을 것 입니다. 거의 javascript 의 변수 생성과 유사하다 볼 수 있지요. 그때 당시만 해도 javascript 를 주로 썻고 유명한 인터프리터형 언어가 javascript 밖에 없으니 이를 벤치마킹 하였을수도 있겠지요. 이건 제 생각입니다.ㅎ

다시 본론으로 들어가서 PHP 버전이 5버전이 되면서 접근제어자가 생기면서 생성자와 파괴자 함수가 별도로 생겨 나게 되었습니다.

static 이라는 개념은 옛날부터 존재해 왔습니다.
C언어나 java 라는 언어또한 클래스 내부에서 static 형태로 선언된 정적멤버변수는 $this 포인터 변수로는 접근을 할 수 없습니다.

이에는 이유가 존재합니다.
$this 포인터로 접근하는 변수는 클래스 멤버변수이며 이러한 멤버변수는 클래스를 생성할 경우 메모리에 별도의 공간에 생성이 됩니다.

하지만 정적멤버변수(static) 변수의 경우에는 정적변수를 생성하는 별도의 메모리 공간에 따로 생성됩니다. 때문에 클래스의 시작 위치를 가리키는 $this 포인터 변수로는 클래스 메모리 공간에 관리되는 멤버변수와는 다른 영역의 메모리 공간에서 관리되는 static 형태의 정적멤버변수에 접근을 할 수 없는 것 입니다. 때문에 아래와 같은 방식을 통해 직접 접근을 하게 됩니다.

소스코드 원문보기
  1. <?php 
  2. class ABC 
  3.      public static $a = 0; 
  4.      function ABC() { 
  5.             print "생성자"
  6.      } 
  7. $abc = new ABC(); 
  8. print $abc->a; // 이는 에러를 발생시킵니다 -> 이는 static 멤버변수이기 때문이며 이유는 위의 설명과 동일합니다. 
  9. print ABC::$a; // 이러한 형태로 static 멤버변수에 접근합니다. 

우선 위의 코드에서 $abc->a 와 같이 static 으로 선언된 정적 멤버변수의 -> 연산자로의 접근에 대해 PHP는 새로운 오류 상태인 E_STRICT라는 상수형으로 오류를 발생시킵니다.

이는 이전의 이유와 동일한 이유로 발생시키게 되며, PHP는 이 오류에 대해 `경고` 수준으로 발생시키므로 해당 오류가 발생된 코드 아래 코드는 여전히 실행 되게 됩니다.

때문에 static 으로 선언된 정적 멤버 변수의 경우 값의 클래스 내부에서의 접근에 대해 self, parent 키워드를 사용하도록 하고 있습니다. self 키워드의 경우 $this 와 동일한 의미를 static 에서 지니게 되며 parent 의 경우 상속받은 클래스에서 부모의 멤버나 함수에 접근시 사용되게 됩니다.


'프로그래밍 > PHP' 카테고리의 다른 글

default -> FTP 기능 구현중 - SeLinux 와의 한판승부  (0) 2010.01.14