객체에 관련된 정보 – 2.Serialize/Unserialize

객체 직렬화(object serialization)

  • 관련 함수 : string serialize(mixed value)

PHP4 스크립트부터 객체를 serialize() 함수를 이용하여 다른 매체에 저장할 수 있는 문자열로 직렬화(serialize)시킬 수 있습니다. PHP3에서도 객체의 멤버변수까지는 직렬화할 수 있었지만 메소드까지는 지원되지 않았는데 PHP4부터는 메소드까지 지원하기 시작한 것이지요.

여러분이 잘 알고 계시는 세션함수가 내부적으로 바로 serialize()를 이용하여 등록된 세션변수값을 파일로 저장할 수 있도록 직렬화하는 것입니다. 그런데 이 serialize() 함수가 객체를 다룰 때 멤버변수만 다루지 메소드는 무시해 버립니다. 정확하게 이야기 하면 메소드 정의를 포함하고 있는 클래스명만 기록하며 클래스에 포함된 메소드 정의 부분은 다루지 않습니다.

앞장 “클래스와 인스턴스”를 주의깊게 읽어 보셨다면 serialize() 함수가 왜 메소드 정의를 다루지 않는 지를 이해할 수 있을 것입니다. serialize() 함수는 객체를 다루는 함수이지 클래스를 다루는 함수는 아닙니다. 객체에는 메소드가 포함되어 있지 않습니다. 따라서 객체를 직렬화한다고 해도 클래스에 포함되어 있는 메소드 정의 부분을 직렬화한다는 것은 올바르지 않지요. 메소드는 같은 클래스에서 생성된 모든 객체가 공유해야 할 정보이지 특정 객체에만 편입된 정보가 아니기 때문에 특정 객체를 직렬화 한다고 해서 직렬화된 정보에 메소드 정의 정보가 포함될 수 없는 것입니다.

이젠 제가 왜 serialize()/unserialize() 함수를 설명하기 전에 “클래스와 인스턴스”라는 주제를 앞 장에 삽입하여 장황하게 설명했는지 이해하실 것 입니다. 클래스와 인스턴스 개념을 이해하고 있지 못하면 왜 serialize() 함수가 메소드 정의 부분을 포함하여 직렬화 시키지 않았는지를 이해할 수가 없습니다.

예를 들어 아래와 같이 session_register() 함수를 이용하여 객체 변수 $obj를 등록시키겠습니다.

이와 같이 세션 등록을 하면 스크립트가 종료되는 순간에 객체를 serialize() 함수를 이용하여 직렬화한 후 서버의 /tmp 디렉토리에 sess_xxxxxxxxxxx 파일명으로 직렬화된 문자열을 저장하게 되는데 그 내용이 아래와 같습니다.

obj|O:4:”test”:1:{s:1:”a”;s:8:”1234ASDF”;}

여기서 obj는 객체변수명, “test”는 클래스명, “a”는 멤버변수명, “1234ASDF”는 멤버변수값을 나타냅니다. 메소드에 관한 정보는 모두 빠져 있는 것을 볼 수 있습니다. 만약 PHP3에서 serialize() 함수를 이용하여 객체를 직렬화 하였다면 멤버변수는 멤버변수명과 멤버변수값이 모두 정상적으로 기록되지만 메소드는 메소드명만 기록되지 메소드 정의 부분이 기록하지 않습니다. 이것이 PHP4에 와서는 메소드명까지 기록하지 않게 되었습니다. 대신에 클래스명이 기록되지요.

객체 역직렬화(object deserialization)

  • 관련 함수 : mixed unserialize(string str)

unserialize() 함수는 serialize() 함수를 이용하여 객체로부터 직렬화된 문자열을 다시 객체로 복원시켜 줍니다. serialize() 함수를 설명할 때 언급한 것처럼 직렬화할 때 객체의 메소드의 정보가 기록되지 않기 때문에 unserialize() 함수로 다시 객체화하더라도 우선 멤버변수만 접근할 수 있지 메소드는 접근할 수 없습니다.

위의 예제에서 5번째줄 $obj->output()는 객체의 메소드를 실행하여야 하는데 객체의 메소드는 복원할 수 없으므로 아래와 같은 에러가 발생합니다.

Fatal error: Call to undefined function: output() in /서버의 디렉토리/test2.php on line 5

따라서 세션함수에 의해 복원된 객체를 가지고 메소드를 실행하기 위해서는 복원된 페이지 내에서 원래의 클래스의 정의를 아래와 같이 명시적으로 포함시켜야 합니다. 즉, 메소드 정의는 별도로 복원시켜주어야 하는 것이지요.

PHP4 에서 객체의 serialize() 함수가 멤버변수와 메소드를 모두 지원한다 하더라도 메소드 정의 부분은 포함되지 않으므로 unserialize() 함수로 복원된 객체를 온전히 사용하기 위해서는 메소드 정의를 별도로 포함시켜야 한다는 것에 주의하여야 합니다.

답글 남기기