phpsource/데이터베이스2000. 11. 21. 17:44
DB Layer는 여러 가지의 데이터베이스(MySQL, Oracle, SyBASE, MSQL, PostgreSQL, ...... )를 동일한 방법으로 다룰 수 있도록 애플리케이션과 데이터베이스 중간에 놓여지게 됩니다. 이러한 DB Layer로써 동작하도록 제작된 Mini DB를 공개합니다. 기존에 공개되고 있는 유명한 DB Layer에 대하여 궁금하면 하단에 있는 웹사이트를 방문해 보세요.
ver 0.2.0부터는 복수의 데이터베이스를 동시에 다룰 수 있도록 수정하였습니다. DB Layer로도 계속 사용할 수 있으며 양 쪽을 혼합하여 사용할 수도 있습니다.
DB Layer의 필요성
만약 사용자가 MySQL과 같은 특정 데이터베이스만 다루게 된다면 DB Layer와 같은 DB를 위한 중간계층은 필요 없을 것입니다. 그러나 여러분이 프로로 활동하고 있다면 언제 어떤 데이터베이스를 다룰지는 모르는 일입니다. 나중에 데이터베이스를 바꾸게 되었을 때 기존에 특정 데이터베이스에 맞게 작성된 코드를 새로운 데이터베이스에 맞게 바꾼다고 생각해 보세요. 간단한 소스라면 별문제 없겠지만 조금만 복잡한 코드라면 아마 고생 꽤나 해야 할 것입니다. 새로운 데이터베이스를 구동시키는 함수를 배우기도 쉽지 않겠지요. 새로운 데이터베이스에 대한 함수를 배우는 게 별거 아니라고요? 사실 데이터베이스에 관련된 PHP 함수를 보면 서로 비슷비슷한 것도 많이 있기도 해요. 그러나 오라클 함수와 MySQL 함수를 비교해 보세요. MySQL 데이터베이스만 다루던 사람이 오라클 함수를 대하게 되면 아마 머리가 흔들흔들할 것입니다. 이럴 때 PHPLIB 또는 phpDB와 같은 layer가 있으면 너무나 간단히 해결되지요. 원하는 데이터베이스로 작성된 클래스 파일로 교체해 주면 되거든요. 이와 같이 여러 개의 데이터베이스를 다루어야 하는 경우에 꼭 필요한 것이 "DB layer"입니다.
DB Layer를 사용하지 않을 때
< DB Layer를 사용하지 않을 때 >
DB Layer를 사용하지 않고 각 데이터베이스를 애플리케이션에서 사용하기 위해서는 각 데이터베이스에 맞는 PHP 함수를 사용하여야 합니다. 따라서 동일한 기능을 수행하는 애플리케이션이라 하더라도 데이터베이스가 변경되면 애플리케이션의 소스코드도 이에 따라 변경되어야 합니다.
DB Layer를 사용했을 때
< DB Layer를 사용했을 때 >
그러나 데이터베이스와 애플리케이션 사이에 DB Layer를 사용하게 되면 각 데이터베이스에 따라서 다르게 코딩해야 하는 부분을 DB Layer가 흡수해 버리기 때문에 애플리케이션에서는 데이터베이스와 관계없이 독립적으로 코딩을 할 수 있게 됩니다. 중, 대형 프로젝트를 수행할 때는 꼭 필요한 기능이라고 할 수 있지요.

Posted by 방글24
phpsource/회원인증2000. 11. 21. 14:16

특정 회원만 사용할 수 있는 인증페이지를 작성하는 방법에 대한 예제입니다.
이 예제는 이전의 "세션라이브러리 예제"와 동일한 예제로, 변경된 것은 세션 라이브러리 대신에 세셔너클래스를 사용하여 세션 관리를 합니다. 인터페이스는 거의 동일합니다. 소스 코드는 대폭적으로 수정하였습니다.
회원 정보 테이블의 구조(MySQL의 경우)
[code sql;gutter:false] CREATE TABLE Members ( userid varchar(20) not null PRIMARY KEY, password varchar(16) not null ); [/code]
회원 정보 테이블에 저장된 회원 정보(MySQL의 경우)
이전 버전에서 사용하던 회원 정보가 변경되었습니다. 각 회원 정보를 아래와 같이 다시 생성해 주십시요.
userid password
user1 test
user2 test
user3 test
[code sql;gutter:false] INSERT INTO Members VALUES('user1', 'test'); INSERT INTO Members VALUES('user2', 'test'); INSERT INTO Members VALUES('user3', 'test'); [/code]
웹사이트 구성도
< 웹사이트 구성도 >
홈페이지에서 로그인 정보(사용자 ID, 비밀번호)를 입력합니다. 로그인 정보를 전송받은 웹서버는 회원 정보 테이블에 저장된 회원 정보와 비교하여 회원임이 판명되면 회원인증ID를 발급하고, 회원이 아니라면 다시 로그인 정보를 입력하도록 요구합니다. 이 프로그램에서 $access_userid에 로그인 할 때 입력된 사용자 ID를 설정하는 것으로 회원인증ID를 발급합니다. 회원 전용 페이지(페이지 #1, #2, #3, #4)에서는 $access_userid를 확인함으로써 로그인 과정을 거친 회원임을 알 수 있으며 따라서 별도의 인증 과정없이 회원 전용 서비스를 제공하게 됩니다.
회원 전용 페이지 서두에는 현재 페이지의 퍼미션 등급과 퍼미션 회원ID를 아래와 같이 설정합니다.
[code php;gutter:false] $permission_user = "user1"; $permission_type = "owner"; [/code]
위와 같이 $permission_type에 "owner"을 설정하면 특정 회원에게만 제공되는 페이지로 이 때는 반드시 $permission_user에 회원ID를 지정하여야 합니다. 위와 같은 경우는 회원ID가 "user1"인 회원에게만 허용된 페이지입니다. 만약 로그인에 성공한 모든 회원에게 페이지 접급을 허용하려면 아래와 같이 $permission_type에 "login"을 설정하면 됩니다. 이 때는 $permission_user를 지정할 필요가 없습니다.
[code php;gutter:false] $permission_type = "login"; [/code]
페이지 구성 및 회원별 접근 제한
예제 프로그램에서는 페이지 #1, #2, #3는 퍼미션 등급이 "owner"으로 설정되어 있고, 페이지 #4는 "login"으로 설정되어 있습니다.
페이지 구성 접근이 허용된 회원
홈페이지
(로그인 정보 입력)
모든 방문자
페이지 #1 로그인한 "user1" 회원
페이지 #2 로그인한 "user2" 회원
페이지 #3 로그인한 "user3" 회원
페이지 #4 로그인한 모든 회원
예제 #1과 예제 #2
예제 #1은 로그인후에 오른쪽에 사용자목록이 나타나고 이 목록에서 사용자페이지를 선택할 수 있습니다. 반면 예제 #2는 사용자목록 없이 로그인 하면 바로 자신의 페이지로 넘어가도록 하였습니다. 예제 #2는 원하시는 분이 있어 추가하였습니다. 소스는 Tip&Tech&Download 게시판에 등록되어 있습니다.
버전 0.2.0에서는 세셔너함수 0.2.1을 이용하여 작성되었습니다. 세셔너함수를 인클루드하는 부분만 삭제하면 PHP4의 세션함수를 이용하여 동작합니다.

Posted by 방글24
클래스 구성
- class.string.php : 문자 처리 클래스
- class.htmltagext.php : HTML 태그 처리 클래스
- class.sessionclient.php : 서버 & 클라이언트 세션 관리 클래스
PUBLIC 멤버함수
클래스를 이용하여 작성되었으며 사용되는 멤버함수는 아래와 같습니다.
- ses_start()
- ses_register()
- ses_unregister()
- ses_destory()

- tagext_head()
- tagext_body()
- submit_anchor()
ses_start() 함수는 세션기능을 시작하는 함수로 클래스의 생성자로 자동 수행하므로 사용자가 임의로 수행할 필요는 없습니다.
ses_register() 함수는 서버 사이드 또는 클라이언트 사이드 또는 양쪽 모두에서 사용하기를 바라는 세션변수를 등록하기 위한 함수입니다.
ses_unregister() 함수는 더 이상 사용되지 않는 세션 변수를 삭제합니다.
ses_destory() 함수는 세션을 강제로 종료하기 위한 함수입니다.
세션 관련 함수는 이미 나온 PHP3용 세션 라이브러리 또는 PHP4 세션 함수의 기능과 거의 유사하니 이해하는데는 어려움이 없을 겁니다. 세션 관련 함수를 제외한 나머지 세 가지의 함수는 서버&클라이언트 세션 기능을 구현하기 위한 보조함수들로 필히 사용되어야 합니다. 각 함수별로 기능을 간단히 살펴보면,
tagext_head() 함수는 "<HEAD> ...... </HEAD>" 태그를 작성해 주는 함수로 이 함수 내에서 자바스크립트와 PHP 스크립트를 연결하는데 필요한 자바스크립트 함수 및 변수 처리 부분이 작성되어 있습니다.
tagext_body() 함수는 "<BODY> ...... </BODY>" 태그를 작성해 주는 함수로 이 함수 내에서 자바스크립트와 PHP 스크립트를 연결하는데 필요한 <FORM> 태그 및 <INPUT> 태그가 작성되어 있습니다.
submit_anchor() 함수는 <A> 태그를 대신하는 함수로 submit하기 전에 tagext_body()에서 작성된 <INPUT> 태그의 값을 설정하고 serialize하기 위한 자바스크립트 함수 goHref()를 호출하는 역할을 합니다. 자바스크립트 함수 goHref() 함수는 tagext_head() 함수 내에 작성되어 있습니다.
예제 파일 구성
아래의 예제는 실제 홈페이지에 적용할 수 있는 완성된 프로그램이 아니고, 단지 클라이언트 세션이 어떻게 이루어지는지를 보여주기 위한 실험적인 프로그램이니 참고만 하세요.
- common.php : 모든 페이지에서 공용으로 쓰이는 변수와 함수가 정의된 인클루드 파일
- sess.php : 세션 시작 페이지
- page1.php : 페이지 #1
- page2.php : 페이지 #2
- page3.php : 페이지 #3
- page4.php : 페이지 #4
- sess_end.php : 세션 종료 페이지
다운로드
(수정:2010.1.12) 관련 파일을 이곳에서 다운로드 받으세요.

Posted by 방글24
여기서 언급하는 클라이언트 세션이란 클라이언트 사이드 스크립트인 자바스크립트 변수의 사용범위를 현재페이지를 벗어나 모든 페이지에서 그 값을 유지할 수 있도록 하여, 홈페이지를 방문하는 사용자들에 대한 정보를 저장하는 수단이나, 서버 사이드 스크립트 변수와의 연동을 위해 사용하기 위한 기능입니다.
서버 세션 & 클라이언트 세션
세션관리는 어떤 기간동안 동일한 사용자로부터의 요청에 대한 상태를 유지하는 방법입니다. 세션이란 용어는 특정 웹사이트에 사용자가 머무르는 시간을 뜻합니다.

...... (중략) ......

세션관리는 웹페이지에 머무르는 한 사용자와 데이터를
묶는 방법을 뜻합니다.

...... (중략) ......

세션이란 용어가 한 사용자의 한번의 방문을 뜻합니다.

(출처: Session Handling with PHP 4, 저자:Tobias Ratschiller,
번역:김수희/ketchup@wowlinux.com)
위의 내용은 PHPSCHOOL.COM 강의실에 올라있는 김수희님의 번역물("Session Handling with PHP 4 번역판")에서 발췌한 내용입니다. 이 정의에서의 관점은 홈페이지에 접근한 사용자입니다. 홈페이지를 개발하는 프로그래머 관점에서 세션을 다르게 표현한다면, 세션 기능이란 서버 사이드 스크립트 변수의 사용범위(scope)를 현재 페이지에 한정하지 않고 여러 페이지로 확장시킨 것입니다. 즉 PHP의 전역변수의 사용범위가 현재 페이지 전체에 걸쳐 있지만 다른 페이지로 가면 현재의 전역변수의 내용은 없어집니다. 이러한 전역변수의 사용범위를 다른 중간 매체(데이터베이스 또는 파일 등)를 이용해 다른 페이지까지 확장시키는 것이지요.
그런데 지금까지 이러한 세션 기능이 서버 사이드 스크립트 측면(PHP 변수)에서만 전개되고 있는 것 같습니다. 관심을 클라이언트 쪽으로 돌려보지요. 클라이언트 사이드 스크립트 측면(보통 자바 스크립트 변수)에서 세션 기능을 구현하면 어떨까요?
클라이언트 사이드에서 홈페이지를 방문하는 사용자들에 대한 정보를 저장하는 수단으로 지금까지는 아마도 자바스크립트와 쿠키를 이용하였을 거라고 생각됩니다. 자바스크립트와 쿠키를 이용하는 방법은 "자바스크립트로 다이내믹 웹 페이지 디자인하기"라는 번역물 (권원상 역, 한빛미디어) P.139~160을 참조하세요.
여기서 구현한 "서버 & 클라이언트 세션 기능"은 서버 사이드 스크립트인 PHP를 이용하여 변수의 사용범위를 서버뿐만 아니라 클라이언트 사이드까지 (때에 따라서는 양쪽 모두) 확장시킨 것입니다.

Posted by 방글24
phpclass/클래스활용2000. 10. 19. 14:44
객체의 형변환(type casting)
스칼라값(integer, double, string)을 객체로 형변환하면, 그 값은 해당 객체의 'scalar'라는 멤버변수의 값이 된다.
[code php;gutter:false] $var = 'ciao';
$obj = (object) $var;
echo $obj->scalar; // 'ciao'를 출력 [/code]
객체를 스칼라값(integer, double)으로 형변환하면 의미없는 숫자 "1" 또는 "1.0"으로 되며, 문자열로 형변환하면 객체 내용에 관계없이 "Object"라는 문자열로 되며, 배열로 형변환하면 객체의 멤버변수명을 첨자로 하는 연관배열(associative array)로 됩니다.
[code php;gutter:false] <?php

class test {
var $a = 10;
var $b = 20;
function test() {
$this->c = 30;
}
}

$obj = new test;

$a = (int) $obj;
echo "object->integer : ".$a."\n";

$a = (double) $obj;
echo "object->double : ".$a."\n";

$a = (string) $obj;
echo "object->string : ".$a."\n";

$a = (array) $obj;
reset ($a);
while (list($k, $v) = each ($a))
echo "\$a[$k] = $v\n";

?> [/code]
< 예제 소스 >
object->integer : 1
object->double : 1
object->string : Object
$a[a] = 10
$a[b] = 20
$a[c] = 30
< 실행 결과 >
gettype(), settype(), is_object() 함수
print_r() 함수

Posted by 방글24
phpclass/클래스활용2000. 10. 19. 14:41
PHP3에서 메소드를 직렬화/객체화하기
PHP3 의 serialize()/unserialize() 함수에서 객체의 메소드를 다루면 에러가 발생하게 됩니다. 즉, PHP3의 serialize()/unserialize() 함수가 객체의 메소드를 지원하지 않기 때문입니다. 그래서 PHP3에서도 객체의 메소드를 직렬화/객체화할 수 있는 라이브러리를 작성하여 보았습니다. 이 라이브러리는 향후 세셔너를 업그레이드할 때 사용할 작정입니다. 그러면 PHP3에서도 모든 변수와 함께 객체에 대해서도 온전히 세션 관리할 수 있을 겁니다.
[code php;gutter:false] <?php

/*
filename : serialize.php (ver.0.0.1)
email : hwooky@phpclass.com
homepage : www.phpclass.com
author : hwooky
*/

/*
사용자 함수:
string serialize3(mixed value, string classname);
mixed unserialize3(string str);
*/

function prvExplodeGroup($str) {
$count = 0;
$prefix = $middle = $suffix = "";

do {
$pos_start = ($pos_start = strpos($str, "{")) ? $pos_start : "NOTHING";
$pos_end = ($pos_end = strpos($str, "}")) ? $pos_end : "NOTHING";

if ((string)$pos_start < (string)$pos_end) {
// "{"로 시작되는 부분
if (0 == $count) {
$prefix = substr($str, 0, $pos_start);
$str = substr($str, $pos_start+1);
} else {
$middle .= substr($str, 0, $pos_start)."{";
$str = substr($str, $pos_start+1);
}
$count++;
} else if ((string)$pos_start > (string)$pos_end) {
// "}"로 시작되는 부분
$middle .= substr($str, 0, $pos_end)."}";
$str = substr($str, $pos_end+1);
$count--;
}
} while ($count);

if ($middle) {
$middle = substr($middle, 0, -1);
$suffix = $str;
} else {
$prefix = $str;
}

return array($prefix, $middle, $suffix);
}

function prvSimplifyObjectString($str) {
$pos = strpos($str, "{");
$prefix = substr($str, 0, $pos);
$val = substr($str, $pos+1, -2);

$suffix = $val;
$str = "";
$count = 0;

do {
list($prefix, $middle, $suffix) = prvExplodeGroup($suffix);
if ($middle)
$str .= $prefix.$count++.";";
} while ($middle);

return $str.$prefix;
}

function serialize3(&$obj, $classname="") {
$str = serialize($obj);
return $classname.";".$str;
}

function unserialize3($str) {
$pos = strpos($str, ";");
$classname = substr($str, 0, $pos);
$val = substr($str, $pos+1);
$obj = unserialize($val);

if ($classname && function_exists($classname)) {
$tobj = new $classname;

$val = prvSimplifyObjectString($val);
$arg = explode(";", $val);

for ($i=0;$i<sizeof($arg);$i+=2) {
$sep = explode(":", $arg[$i]);
$name = substr($sep[2], 1, -1);

if ("user function" != gettype($tobj->$name))
$tobj->$name = $obj->$name;
}
return $tobj;
}
return $obj;
}

?> [/code]
serialize3() 함수를 보면 serialize() 함수에는 없는 두번째 인수를 지정하여야 합니다. 두번째 인수는 객체를 직렬화할 때만 사용되는 인수입니다. 객체 이외의 변수를 직렬화하는 방법은 serialize() 함수와 동일합니다. 객체를 직렬화하려면 첫번째 인수로는 직렬화하려는 객체명을 지정하고, 두번째 인수로는 객체를 생성할 때 필요한 클래스명을 지정합니다. 예를 들어,
[code php;gutter:false] $obj = new test; [/code]
위와 같이 생성된 객체를 직렬화하려면
[code php;gutter:false] serialize3($obj, "test"); [/code]
위와 같이 객체변수와 클래스명을 지정하여 줍니다. 앞 장에서 다루었던 예제를 여기서도 그대로 사용하여 보겠습니다. 앞 장과 다른 점은 serialize.php 라이브러리를 인클루드하는 부분이 추가되었고, seiralize()/unseiralize() 함수 대신에 라이브러리에 있는 seiralize3()/unseiralize3() 함수를 사용하였다는 것입니다. 실행 결과는 PHP4의 경우와 동일합니다.
[code php;gutter:false] <?php

// 파일명 : test1.php3

require("./serialize.php");

class test {
var $a;
var $b;

function output() {
return "나 함수";
}
}

$obj = new test;

$obj->a = 0;
$obj->b = "나 b";

echo "<p>".$obj->a."</p>";
echo "<p>".$obj->b."</p>";
echo "<p>".$obj->output()."</p>";

$ser = urlencode(serialize3($obj, "test"));

echo "<p><A href=test2.php3?ser=$ser>TEST2.PHP3</A></p>";

?> [/code]
[code php;gutter:false] <?php
// 파일명 : test2.php

require("./serialize.php");

class test {
var $a;
var $b;

function output() {
return "나 함수";
}
}

$obj = unserialize3(stripslashes($ser));

echo "<p>".$obj->a."</p>";
echo "<p>".$obj->b."</p>";
echo "<p>".$obj->output()."</p>";

?>

<p><A href=test1.php3>TEST1.PHP3</A></p> [/code]
serialize.php 라이브러리를 이용할 때도 PHP4 때와 마찬가지로 serialize3() -> unserialize3() 과정을 거친 객체가 정상적으로 복원되었다는 것을 알 수 있습니다.
test1.php3를 실행하였을 때:

0
나 b
나 함수

TEST2.PHP3

test2.php3를 실행하였을 때:

0
나 b
나 함수

TEST1.PHP3

Posted by 방글24
phpclass/클래스활용2000. 10. 19. 14:40
PHP4에서 메소드를 직렬화/객체화하기
예를 들어 아래와 같이 예제를 작성하여 PHP3와 PHP4 스크립트에 각각 실행하여 보면, test2.php를 실행하였을 때 PHP4에서는 정상적으로 메소드가 실행되지만 PHP3에서는 에러가 발생합니다.
[code php;gutter:true]<?php
// 파일명 : test1.php

class test {
  var $a;
  var $b;

  function output() {
    return "나 함수";
  }
}

$obj = new test;

$obj->a = 0;
$obj->b = "나 b";

echo "<p>".$obj->a."</p>";
echo "<p>".$obj->b."</p>";
echo "<p>".$obj->output()."</p>";

$ser = urlencode(serialize($obj));

echo "<p><A href=test2.php?ser=$ser>TEST2.PHP</A></p>";

?> [/code]
[code php;gutter:true] <?php
// 파일명 : test2.php

class test {
  var $a;
  var $b;

  function output() {
    return "나 함수";
  }
}

$obj = unserialize(stripslashes($ser));

echo "<p>".$obj->a."</p>";
echo "<p>".$obj->b."</p>";
echo "<p>".$obj->output()."</p>";

?>

<p><A href=test1.php>TEST1.PHP</A></p> [/code]
아래는 PHP3에서 실행한 결과입니다. PHP3에서는 serialize()/unserialize()가 객체의 메소드를 지원하지 않기 때문에 test2.php를 실행할 때에 17번 라인에서 에러가 발생합니다.
test1.php를 실행하였을 때:

0
나 b
나 함수

TEST2.PHP

test2.php를 실행하였을 때:

0
나 b

Fatal error: Function call to a non-function (output)
in /home/httpd/homepage/phpclass/exam2/simple/test2.php on line 17
아래는 PHP4에서 실행한 결과입니다. PHP4에서는 serialize() -> unserialize() 과정을 거친 객체가 정상적으로 복원되었다는 것을 알 수 있습니다. 앞장에서 설명하였지만 메소드 정의는 별도로 포함시켜야 하는 것을 잊어서는 안됩니다. 메소드 정의를 생략한다면 역시 에러를 만나게 될 것입니다.
test1.php를 실행하였을 때:

0
나 b
나 함수

TEST2.PHP

test2.php를 실행하였을 때:

0
나 b
나 함수

TEST1.PHP

Posted by 방글24
phpclass/클래스활용2000. 10. 19. 14:39
serialize() 함수
형식 : string serialize(mixed value)
PHP4 스크립트부터 객체를 serialize() 함수를 이용하여 다른 매체에 저장할 수 있는 문자열로 직렬화(serialize)시킬 수 있습니다. PHP3에서도 객체의 멤버변수까지는 직렬화할 수 있었지만 메소드까지는 지원되지 않았는데 PHP4부터는 메소드까지 지원하기 시작한 것이지요. 여러분이 잘 알고 계시는 세션함수가 내부적으로 바로 serialize()를 이용하여 등록된 세션변수값을 파일로 저장할 수 있도록 직렬화하는 것입니다. 그런데 이 serialize() 함수가 객체를 다룰 때 멤버변수만 다루지 메소드는 무시해 버립니다. 정확하게 이야기 하면 메소드 정의를 포함하고 있는 클래스명만 기록하며 클래스에 포함된 메소드 정의 부분은 다루지 않습니다. 앞장 "클래스와 인스턴스"를 주의깊게 읽어 보셨다면 serialize() 함수가 왜 메소드 정의를 다루지 않는 지를 이해할 수 있을 것입니다. serialize() 함수는 객체를 다루는 함수이지 클래스를 다루는 함수는 아닙니다. 객체에는 메소드가 포함되어 있지 않습니다. 따라서 객체를 직렬화한다고 해도 클래스에 포함되어 있는 메소드 정의 부분을 직렬화한다는 것은 올바르지 않지요. 메소드는 같은 클래스에서 생성된 모든 객체가 공유해야 할 정보이지 특정 객체에만 편입된 정보가 아니기 때문에 특정 객체를 직렬화 한다고 해서 직렬화된 정보에 메소드 정의 정보가 포함될 수 없는 것입니다. 이젠 제가 왜 serialize()/unserialize() 함수를 설명하기 전에 "클래스와 인스턴스"라는 주제를 앞 장에 삽입하여 장황하게 설명했는지 이해하실 것 입니다. 클래스와 인스턴스 개념을 이해하고 있지 못하면 왜 serialize() 함수가 메소드 정의 부분을 포함하여 직렬화 시키지 않았는지를 이해할 수가 없습니다.
예를 들어 아래와 같이 session_register() 함수를 이용하여 객체 변수 $obj를 등록시키겠습니다.
[code php;gutter:true]<?php
// 파일명 : test1.php

class test {
  var $a = "1234ASDF";
 
  function test() {}
 
  function output() {
    echo($this->a);
  }
}
 
session_register("obj");
$obj = new test();
$obj->output();
?>

<p><A href=test2.php>TEST2.PHP</A></p> [/code]
이와 같이 세션 등록을 하면 스크립트가 종료되는 순간에 객체를 serialize() 함수를 이용하여 직렬화한 후 서버의 /tmp 디렉토리에 sess_xxxxxxxxxxx 파일명으로 직렬화된 문자열을 저장하게 되는데 그 내용이 아래와 같습니다.
obj|O:4:"test":1:{s:1:"a";s:8:"1234ASDF";}
여기서 obj는 객체변수명, "test"는 클래스명, "a"는 멤버변수명, "1234ASDF"는 멤버변수값을 나타냅니다. 메소드에 관한 정보는 모두 빠져 있는 것을 볼 수 있습니다. 만약 PHP3에서 serialize() 함수를 이용하여 객체를 직렬화 하였다면 멤버변수는 멤버변수명과 멤버변수값이 모두 정상적으로 기록되지만 메소드는 메소드명만 기록되지 메소드 정의 부분이 기록하지 않습니다. 이것이 PHP4에 와서는 메소드명까지 기록하지 않게 되었습니다. 대신에 클래스명이 기록되지요.
unserialize() 함수
형식 : mixed serialize(string str)
unserialize() 함수는 serialize() 함수를 이용하여 객체로부터 직렬화된 문자열을 다시 객체로 복원시켜 줍니다. serialize() 함수를 설명할 때 언급한 것처럼 직렬화할 때 객체의 메소드의 정보가 기록되지 않기 때문에 unserialize() 함수로 다시 객체화하더라도 우선 멤버변수만 접근할 수 있지 메소드는 접근할 수 없습니다.
[code php;gutter:true]<?php
// 파일명 : test2.php
 
session_register("obj");
$obj->output();
?>
 
<p><A href=test1.php>TEST1.PHP</A></p> [/code]
위의 예제에서 5번째줄 $obj->output()는 객체의 메소드를 실행하여야 하는데 객체의 메소드는 복원할 수 없으므로 아래와 같은 에러가 발생합니다.
Fatal error: Call to undefined function: output()
in /서버의 디렉토리/test2.php on line 5
따라서 세션함수에 의해 복원된 객체를 가지고 메소드를 실행하기 위해서는 복원된 페이지 내에서 원래의 클래스의 정의를 아래와 같이 명시적으로 포함시켜야 합니다. 즉, 메소드 정의는 별도로 복원시켜주어야 하는 것이지요.
[code php;gutter:true]<?php
// 파일명 : test2.php
 
class test {
  function output() {
    echo($this->a);
  }
}
session_register("obj");
$obj->output();
?>
 
<p><A href=test1.php>TEST1.PHP</A></p> [/code]
PHP4 에서 객체의 serialize() 함수가 멤버변수와 메소드를 모두 지원한다 하더라도 메소드 정의 부분은 포함되지 않으므로 unserialize() 함수로 복원된 객체를 온전히 사용하기 위해서는 메소드 정의를 별도로 포함시켜야 한다는 것에 주의하여야 합니다.

Posted by 방글24
phpclass/클래스활용2000. 10. 17. 14:37
클래스와 객체에 관련된 정보에 대하여 알아봅니다.
객체의 모델링
객 체지향 프로그래밍에서는 여러 개의 객체를 모아 하나의 전체 프로그램을 구성하게 됩니다. 프로그램에서 객체를 모델링, 즉 객체를 표현하기 위해서는 물리적 특성(객체의 속성)과 동적 특성(객체의 동작)을 규명하여야 합니다. 예를 들어 자동차라는 객체가 가지고 있는 각 특성을 살펴보면 아래와 같이 될 수 있습니다.
자동차의 물리적 특성 :
- 자동차 중량
- 자동차 색상
- 배기량

자동차의 동적 특성 :
- 출발
- 방향전환
- 정지
이러한 자동차의 특성에 따라 "둘리", "밍키", "후키"이라는 사람이 소유하고 있는 자동차를 모델링하면 다음과 같습니다.
항목 둘리 밍키 후키
물리적
특성
중량 1800kg 2600kg 4500kg
색상 은색 흑색 흰색
배기량 2000CC 3000CC 5000CC
동적
특성
출발 엔진에 연료를 공급한다
동력을 바퀴에 전달한다
바퀴를 움직인다
엔진에 연료를 공급한다
동력을 바퀴에 전달한다
바퀴를 움직인다
엔진에 연료를 공급한다
동력을 바퀴에 전달한다
바퀴를 움직인다
방향
전환
조향핸들을 조작한다 조향핸들을 조작한다 조향핸들을 조작한다
정지 엔진에 연료 공급을 중단한다
바퀴에 전달하는 동력을 차단한다
바퀴를 정지시킨다
엔진에 연료 공급을 중단한다
바퀴에 전달하는 동력을 차단한다
바퀴를 정지시킨다
엔진에 연료 공급을 중단한다
바퀴에 전달하는 동력을 차단한다
바퀴를 정지시킨다
클래스의 필요성
위 의 예에서 3개의 자동차가 각각 서로 다른 객체이기 때문에 각각의 자동차가 가지는 물리적 특성을 서로 다를 수 있습니다. 그러나 이러한 3개의 객체는 모두 자동차라는 공통점을 가지고 있기 때문에 각각의 자동차가 다른 물리적 특성을 가지고 있더라도 그 구조는 모두 동일합니다. 즉, 각각의 자동차는 서로 다른 색상을 가질 수 있지만, 모든 자동차는 색상이라는 특성을 가지고 있다는 공통점을 가지고 있습니다. 결국 모든 자동차들은 동일한 구조로 표현된다고 할 수 있습니다.
각각의 자동차가 서로 다른 물리적 특성을 가질 수 있는 것과 달리, 모든 자동차는 동일한 방법으로 동작하게 됩니다. 즉, 모든 자동차는 동일한 동적 특성을 가지게 됩니다.
이 와 같이 자동차라는 공통점을 가지고 있는 각각의 객체는 서로 다른 물리적 특성을 가질 수 있지만, 각각의 객체에 데이터(물리적 특성)를 저장하는 구조(자료구조)와 각각의 객체에서 수행하는 동적 특징은 공유하게 됩니다. 이와 같이 각각의 객체에서 공유하게 되는 정보를 표현하기 위하여 객체지향 프로그래밍에서는 클래스(Class)라는 개념을 사용하게 됩니다. 이와 같이 클래스는 "둘리", "밍키", "후키"가 소유한 차, 즉 객체가 가지는 물리적 특성의 구조(자료구조)와 동적 특성을 표현하게 됩니다.
인스턴스(instance)
인 스턴스란 클래스에 속하는 하나의 객체로써, 클래스에 정의된 특성을 가지게 되는 객체를 말합니다. 이에 따라 인스턴스는 자신이 소속된 클래스에서 정의한 구조(자료구조)에 따라 정보를 가질 뿐만 아니라, 자신이 가지고 있는 정보를 조작하기 위하여 클래스에 정의되어 있는 동적 특성을 사용합니다.
클래스와 인스턴스 개념을 이용한 객체의 모델링
< 클래스와 인스턴스 개념을 이용한 객체의 모델링 >
위의 그림에서 보면 동적 특성(함수)이 클래스에 속하여 있으며, 인스턴스에서는 단지 필요에 따라 클래스에 정의되어 있는 이러한 동적 특성을 이용하게 됩니다.
여기에 기술된 내용은 10년 전에 제가 보던 C++ 책의 내용을 기반으로 작성된 것이라 이미 책에서 보신 기억이 나시는 분도 있으리라 생각되네요.

Posted by 방글24
세셔너 0.2.5p1
  • prvSetSaveHandler() 함수 수정
    이것은 미니디비 0.2.2p1와의 충돌을 방지하기 위한 사전 작업입니다.
  • prvDecode() 함수 수정
    세셔너에서는 세션변수값이 빈문자열이면 자동으로 세션등록을 취소시켰는데 이것이 PHP4 세션함수와 다르게 동작합니다. PHP4와 동일하게 세션변수값을 unregister하지 않는 이상 어떠한 값이 있더라도 세션변수를 계속 유지되도록 수정하였습니다.
세셔너 0.2.5
  • session_set_cookie_param() 함수 관련 패치
세셔너 0.2.4
  • session_set_cookie_param() 함수 수정
  • session_save_path() 함수 수정
  • session_name() 함수 수정
세셔너 0.2.3
  • session_set_save_handler(), session_module_name(), session_encoding(), session_decoding() 함수 추가
  • 세셔너함수 0.2.2와 세셔너클래스 0.0.3 통합 => 세셔너 0.2.3
  • 세션함수와 세션핸들러의 분리
  • PHP3와 PHP4 공용 세셔너핸들러의 외장모듈 별도 제공(파일시스템용, 데이터베이스용, DBM/DMA용)
  • PHP3와 PHP4 공용 세셔너핸들러 함수 제공 - session_handler(), session_guests(), session_guest_list(), session_guest_data(), session_guest_decode(), session_event_path()
  • PHP3와 PHP4 공용 이벤트 핸들러 OnStart 및 OnEnd 제공
  • 세션명, 세션파일명 디폴트값을 PHP4 세션과 동일하게 변경(PHPSESSID, sess_......)
세셔너 0.2.2
  • session_get_cookie_params(), session_set_cookie_params(), session_cache_limiter() 함수 추가
세셔너 0.2.1
  • 세션변수의 인코딩/디코딩 부분에 버그가 있어 수정합니다
세셔너 0.2.0
이번 버전에서는 PHP 4.0.3을 참조하여 인터페이스를 결정하였습니다.
  • 세션변수의 인코딩/디코딩 부분 버그 수정
  • 보안 강화를 위해 세션ID와 함께 Client의 IP 주소 확인
  • session_register() 함수의 입력 인자의 변수형으로 배열 추가
  • session_name(), session_save_path(), session_id(), session_unset(), session_is_registered() 함수 추가
  • 내부 함수를 클래스/객체를 이용하여 호출하도록 소스코드 수정
  • $HTTP_SESSION_VARS[] 배열 제공
세셔너 0.0.3
  • Garbage Collection 기능의 버그 수정
  • $prvSessionGarbage 대신 기존의 $prvSessionInterval 에 지정된 시간에 따라 Garbage Collection 수행
  • fileatime() 함수와 PHPSES3LASTUSED 세션변수 대신 filemtime() 함수 사용
세셔너 0.0.2
  • Garbage Collection 기능 추가
  • session_destroy() 함수가 PHP4 세션함수와 다르게 동작하던 것을 수정
세셔너 0.0.1(최초 공개 버전) - 2000.10.24
  • session_start(), session_destroy(), session_register(), session_unregister() 함수 제공

'phpsource > 캐시&세션&쿠키' 카테고리의 다른 글

{클라이언트 세션}2.클래스 구성  (0) 2000.11.21
{클라이언트 세션}1.개요  (0) 2000.11.21
{PHP3용 세션}3.사용방법  (0) 2000.10.14
{PHP3용 세션}2.세셔너함수  (0) 2000.10.14
{PHP3용 세션}1.개요  (0) 2000.10.14
Posted by 방글24