phpsource/템플릿2002. 1. 28. 11:19
written: Jan 28 2002
last modified: Sep 20 2006
URL 리디렉션(redirection)
URL 리디렉션의 필요성
사실 개발자가 템플릿을 이용하는 가장 큰 이유라면 당연히 웹디자인 부분과 PHP 코딩 부분을 분리하기 위해서 입니다. 이러한 이유로 템플릿은 웹디자이너가 나모 웹에디터와 같은 위지윅 웹에디터를 이용하여 작성하는데 불편함이 없어야 하며, 아울러 웹에디터에 나타나는 각 부분의 의미가 명확하여야 합니다. 이러한 관점에서 볼 때 현재까지 나와 있는 모든 템플릿툴에서 발견되는 문제라고 하면 템플릿에서 작성된 HTML 소스(자바 스크립트 소스 포함)에 포함된 URL(Uniform Resource Locator)이 PHP로 해석될 때는 설정된 템플릿 경로에 따라 전혀 다르게 표기된다는 것입니다.
이 문제를 해결하기 위해서는 템플릿과 PHP 문서를 동일한 디렉토리에 보관하든가, 아니면 템플릿에 있는 URL을 상대경로가 아닌 절대경로를 이용하든가 등등 해야 할 것입니다. 이것이 현실적으로 곤란하다면 템플릿에 있는 URL을 전부 PHP 문서 위치에 맞게 변경하는 수고를 해야겠지요.
후키템플릿에서는 이 문제를 해결하기 위해 제가 앞서 공개하였던 HTML 파서를 이용하게 되었습니다. define() 함수에 의해 읽어들인 템플릿 파일을 HTML 파서에 의해 태그 단위로 분석한 후 URL이 있는 부분들을 전부 찾아 내어 PHP 문서에 맞게 변경 시켜주게 됩니다.
URL 리디렉션 = 웹문서 리디렉션 + 리소스 리디렉션
나모와 같은 웹에디터를 이용하여 작성된 웹문서(여기서는 템플릿 파일을 의미함)에 포함된 각종 파일이 있는 위치를 PHP 문서의 위치에 맞게 적절히 변경해주는 "URL 자동 변경" 기능을 최초 버전부터 제공하여 왔었습니다만 이 기능이 그림과 같은 리소스를 처리하는데는 적절하였으나 하이퍼링크로 연결된 HTML 문서의 위치를 처리하는데는 문제가 많이 있었습니다.
따라서 1.0.0 버전부터는 그림과 같은 웹문서의 위치 변경과 웹문서가 아닌 나머지 모든 리소스(그림, 동영상 등)의 위치 변경에 대한 기능을 구분하여 제공합니다. 이 문서에서는 하이퍼링크로 연결된 HTML 문서의 위치 변경을 "웹문서 리디렉션", 그림 또는 동영상과 같은 나머지 리소스의 위치 변경을 그냥 "리소스 리디렉션"이라는 용어로 부르겠으니 혼동없기를 바랍니다. 즉, "리소스 리디렉션"이라고 했을 때는 웹문서를 제외한 파일에 대한 리디렉션을 의미합니다. 만약 웹문서를 포함한 모든 리소스에 대한 리디렉션을 지정할 때는 웹문서 또는 리소스라는 접두어없이 "리디렉션" 또는 "URL 리디렉션"이라고 부르겠습니다.
사실 태그의 속성으로 지정되는 각종 URL이 그림, 동영상, 웹문서를 모두 지원하는 경우가 많으므로 양쪽 기능을 설명하는데 있어서 명확히 구분되지 않는 부분도 많이 있을 것입니다.
URL 리디렉션이 적용되는 URL 형식
URL이 절대 경로로 지정되었다면 리디렉션이 필요없을 것입니다. 따라서 "./" 또는 "../"로 시작되는 URL이나 파일명과 쿼리문만으로 구성된 URL일 경우에만 리디렉션 기능이 적용됩니다. 만약 URL이 템플릿 변수로 지정되었다면 이 URL은 PHP 소스에서 자신의 위치에 맞게 정확하게 지정할 것이기 때문에 역시 리디렉션을 하지 않습니다.
URL 리디렉션이 가능한 태그 속성들
아래는 리디렉션 해주는 태그 속성 및 스타일 속성입니다.
태그명     속성명
------ ------
IMG src, lowsrc
EMBED src
INPUT src
FRAME src
IFRAME src
SCRIPT src
BODY background
TABLE background
TR background
TH background
TD background
LINK href
BASE href
A href
Q cite
BLOCKQUOTE cite
INS cite
DEL cite
OBJECT data
FORM action
PARAM value

스타일
------
<태그명 style="background-image:url(URL)">
<STYLE>
@import url(URL);
background-image: url(URL);
background: #fcf url(URL) 50%;
list-style-image: url(URL);
list-style: lower-roman inside url(URL);
</STYLE>
1.0.0 이전 버전에서는 <PARAM> 태그에 포함된 URL에 대한 리디렉션 기능을 제공하지 못했습니다.
1.0.0 버전부터는 <PARAM> 태그의 'value' 속성이 URL일 경우에도 리디렉션 기능을 수행하도록 개선하였습니다.
혹시 리디렉션이 필요한 태그가 더 있다면 게시판을 통해 알려주시기 바랍니다.
자바 스크립트에 포함된 URL 리디렉션
자바 스크립트에 있는 URL의 리디렉션까지 지원한다는 것은 그 구현이 무척이나 어려운 것 같습니다. 그래서 완벽한 지원이라기 보다는 한가지 약속을 통하여 이를 해결하고자 합니다.
자바 스크립트에서 URL을 리디렉션하고 싶은 경로가 있다면 이 부분은 아래와 같이 별도로 관리하여 주시기 바랍니다.
[code html;gutter:false] <SCRIPT language="javascript" tpl="URL"> <!-- OpenMail = "./../mail.php"; OpenHelp = "./../help_search.php"; //--> </SCRIPT> <SCRIPT language="javascript"> <!-- function openMail(to) { pos = ',left='+(screen.width-240)/2+',top='+(screen.height-240)/2; popup = window.open('', 'mail_window', 'scrollbars=no,width=240,height=240' + pos); popup.location.href = OpenMail + '?to=' + to; popup.focus(); } //--> </SCRIPT> <INPUT type=button value='도움말' name=help onClick='openWindow(500, 400, OpenHelp)'> [/code]
OpenMail과 OpenHelp가 바로 리디렉션하고 싶은 URL이 저장되어 있는 자바 스크립트 변수입니다. 이 예처럼 URL을 변경하고 싶은 자바 스크립트 변수명들은 한 곳에 묶어서 따로(다른 SCRIPT 문장과 분리하여) 관리하세요. 이 때 태그 SCRIPT의 사용자 정의 속성 'tpl'을 'URL'라고 지정하여 주셔야 합니다. 그리고 나서 다른 자바 스크립트 문장에서는 이 변수를 이용하시면 됩니다. 이것만 지켜주신다면 자바스크립트에 포함된 URL을 자동 변경하는데 별 문제가 없을 것입니다.
버전 0.0.2 이전 버전에서는 사용자 정의 속성 'tpl' 대신에 'name'를 사용하였으나 이 속성명 'name'은 실제로 태그에서 사용하는 속성이다보니 충돌이 일어나는 경우가 발생하여 0.0.2 버전부터는 'name' 속성을 지원하지 않습니다.
< URL 자동 변경을 위한 속성 지정 <
버전 속성명 속성값 향후 호환성
0.0.1 name URL4TPL 호환성 없음
0.0.2 name URL4TPL "
tpl URL 호환성 있음
'7.7.복수 템플릿 파일의 용법'에서 자세히 언급하겠지만 속성 'tpl'에 설정할 수 있는 또 다른 값 'TMP'가 있습니다. 'TMP' 용법에 대한 자세한 것은 뒷 장 '7.7.복수 템플릿파일의 용법'을 참조바랍니다. 만약 'URL', 'TMP' 값 모두를 설정하려면 아래와 같이 콤마로 구분하여 속성값을 지정하면 됩니다. 순서는 관계없습니다.
[code html;gutter:false] <SCRIPT language="javascript" tpl="URL,TMP"> <!-- OpenMail = "./../mail.php"; OpenHelp = "./../help_search.php"; //--> </SCRIPT> [/code]
이제는 URL 리디렉션 문제로 웹디자이너와 프로그래머가 만날 일이 별로 없을 것입니다.
내장 필터함수 url()을 이용한 URL 리디렉션
1.2.0 버전부터는 자바 스크립트에 포함된 URL의 리디렉션을 tpl 속성을 사용하지 않더라도 내장 필터함수인 url() 함수를 이용하여 아래와 같이 쉽게 구현할 수 있습니다.
[code html;gutter:false] <SCRIPT language="javascript"> <!-- function openMail(to) { pos = ',left='+(screen.width-240)/2+',top='+(screen.height-240)/2; popup = window.open('', 'mail_window', 'scrollbars=no,width=240,height=240' + pos); popup.location.href = "{=>url('./../mail.php')}" + '?to=' + to; popup.focus(); } //--> </SCRIPT> <INPUT type=button value='도움말' name=help onClick='openWindow(500, 400, "{=>url('./../help_search.php')}")'> [/code]
내장 필터함수를 이용하는 방법에 대하여는 '8.7.내장 필터함수'를 참조바랍니다.
자바 스크립트 이벤트 핸들러에 의해 실행되는 함수
[code html;gutter:false] <A href="index.html" onMouseOver="test('arg1', 'arg2', 'images/test.gif', true);"> test </A> [/code]
위의 예와 같이 각종 태그 내에 지정된 이벤트 핸들러에 의해 실행되는 함수로 전달되는 인수 중에 있는 URL을 리디렉션해 줍니다.
해당되는 이벤트 핸들러에는 'onAbort', 'onBlur', 'onChange', 'onClick', 'onError', 'onFocus', 'onLoad', 'onMouseOut', 'onMouseOver', 'onReset', 'onSelect', 'onSubmit', 'onUnload'가 있습니다.
이 기능은 1.0.0 버전부터 지원됩니다.
URL 리디렉션에서의 문제점
PHP 스크립트로 HTML 태그를 분석하는 일은 많은 시간이 소요되는 일입니다. 그러나 뒷장에서 언급하고 있는 '템플릿 캐시'을 이용하면 URL 리디렉션을 할 때와 하지 않을 때의 차이가 거의 없습니다. 템플릿의 변경을 즉시 반영하여 페이지를 생성하기 때문에 여러분은 캐시를 사용하는지 하지 않는지 조차 전혀 눈치챌 수 없습니다. 이 기술은 이전에 공개했던 유닛테이블에서 써 먹던 것이었는데 여기서 다시 써 먹게 되네요.

Posted by 방글24
phpsource/파일분석2001. 7. 24. 20:16
2002.7.20 - 0.0.2
2002.3.21 - 0.0.1 패치1
2001.7.24 - 0.0.1

Posted by 방글24
phpsource/파일분석2001. 7. 24. 17:43
다차원 배열 구조
앞 장의 예제에서 보았듯이 파서 배열 구조는 다차원 배열(multi-dimensional array)로 구성되어 있습니다.
배열 구조를 보기 위해 사용하였던 var_dump() 함수 대신에 다차원배열 상태 그대로 보게 되면 아래와 같습니다.
$vals[0][tag]=""
$vals[0][type]="cdata"
$vals[0][value]="<!--HTML_PARSER 0.0.1-->"

$vals[1][tag]="HTML"
$vals[1][type]="open"
$vals[1][value]=" "

$vals[2][tag]="HEAD"
$vals[2][type]="open"
$vals[2][value]=" "

$vals[3][tag]="SCRIPT"
$vals[3][type]="open"
$vals[3][attributes][language]="JavaScript"
$vals[3][value]=" <!-- document.write("abc"); --> "

$vals[4][tag]="SCRIPT"
$vals[4][type]="close"
$vals[4][value]=" "

$vals[5][tag]="STYLE"
$vals[5][type]="open"
$vals[5][value]=" table td { font-size:.7em; } "

$vals[6][tag]="STYLE"
$vals[6][type]="close"
$vals[6][value]=" "

$vals[7][tag]="HEAD"
$vals[7][type]="close"
$vals[7][value]=" "

$vals[8][tag]="BODY"
$vals[8][type]="open"
$vals[8][attributes][bgcolor]="#ffffff"
$vals[8][attributes][marginwidth]="25"
$vals[8][attributes][marginheight]="0"
$vals[8][attributes][topmargin]="0"
$vals[8][attributes][leftmargin]="25"
$vals[8][value]=" "

$vals[9][tag]="TABLE"
$vals[9][type]="open"
$vals[9][attributes][bgcolor]="#FFFFFF"
$vals[9][attributes][border]="0"
$vals[9][attributes][cellpadding]="0"
$vals[9][attributes][cellspacing]="0"
$vals[9][attributes][width]="100%"
$vals[9][attributes][title]="<<<테이블 속성>>>"
$vals[9][value]=" "

$vals[10][tag]="TR"
$vals[10][type]="open"
$vals[10][value]=" "

$vals[11][tag]="TD"
$vals[11][type]="open"
$vals[11][value]=" < HTML 파서 >를 이용한 HTML 문서 분석 "

$vals[12][tag]="TD"
$vals[12][type]="close"
$vals[12][value]=" "

$vals[13][tag]="TR"
$vals[13][type]="close"
$vals[13][value]=" "

$vals[14][tag]="TABLE"
$vals[14][type]="close"
$vals[14][value]=" "

$vals[15][tag]="BODY"
$vals[15][type]="close"
$vals[15][value]=" "

$vals[16][tag]="HTML"
$vals[16][type]="close"
$vals[16][value]=""
제1첨자를 기준으로 보면 총 17개의 부분배열요소가 있다는 것을 알 수 있습니다. 배열 요소 수량은 HTML 문서 내에 있는 태그의 수량에 따라 결정됩니다. 보통은 태그 수량 + 1 의 배열 요소가 생성됩니다.
위에서 17개의 부분배열요소 중에서 첫번째 부분배열요소는 원래의 HTML 문서에는 없던 것으로 추가되어 있는 것을 알 수 있습니다. 만약 HTML 문서상에 나타나는 첫번째 태그 이전에 태그가 아닌 문자가 있다면 첫번째 부분배열요소의 value 첨자의 값의 뒤쪽에 기록됩니다.
[code html;gutter:false] 1234567890
<HTML> [/code]
예를 들어 위와 같은 HTML 문서를 분석하면 아래와 같은 배열을 얻을 수 있습니다. 아래 결과에서 "<!--HTML_PARSER 0.0.1-->"는 html_parse_into_struct 함수에서 강제로 붙이게 되는 문자열로 파서 함수의 버전을 나타냅니다.
$vals[0][tag]=""
$vals[0][type]="cdata"
$vals[0][value]="<!--HTML_PARSER 0.0.1--> 1234567890"
제2첨자 tag, type, attributes, value
제1첨자의 각 부분배열요소를 구성하는 제2첨자를 보면 총 4가지가 존재하게 됩니다.
tag
HTML 태그명을 가리킵니다. 원래의 소스에 관계없이 항상 대문자로 기록됩니다. 만약 태그명이 아닌 경우에는 널문자열("")이 기록됩니다. 예를 들어, <TD> 또는 </TD> 인 경우에는 tag 첨자의 요소값에는 TD가 기록됩니다.
type
type에 기록되는 값에는 open, close, cdata 입니다. open은 태그가 시작태그라는 것을 알려주며, close는 종료태그라는 것을 알려줍니다. cdata는 태그가 아닌 순수한 일반 문자(complete data ???)로 구성되어 있는 배열요소임을 알려줍니다.
예를 들어, <TD> 인 경우에는 type 첨자의 요소값으로 open이 기록되고, </TD> 인 경우에는 close가 기록됩니다.
attributes
attributes는 해당 태그의 속성을 기록하고 있습니다. 이 첨자에 대한 요소값은 다른 것과는 달리 부분배열로 기록됩니다.
[code html;gutter:false] <TABLE BGCOLOR="#FFFFFF" BORDER="0" CELLPADDING="0" CELLspacing="0"
WIDth="100%" title="<<<테이블 속성>>>"> [/code]
예를 들어 위와 같은 HTML 문서를 분석하면 아래와 같은 배열을 얻을 수 있습니다.
$vals[1]["tag"]="TABLE"
$vals[1]["type"]="open"
$vals[1]["attributes"]["BGCOLOR"]="#FFFFFF"
$vals[1]["attributes"]["BORDER"]="0"
$vals[1]["attributes"]["CELLPADDING"]="0"
$vals[1]["attributes"]["CELLspacing"]="0"
$vals[1]["attributes"]["WIDth"]="100%"
$vals[1]["attributes"]["title"]="<<<테이블 속성>>>"
위의 결과에서 제1첨자 1는 HTML 문서상의 TABLE의 위치에 따라 변동될 수 있습니다. 그리고 속성명은 HTML 문서에서 기록된 그대로 반환됩니다. 0.0.1 초기버전에서는 태그명을 강제로 소문자로 변환하였으나 약간의 문제가 있어 수정하였습니다.
value
앞에서 설명한 tag, type, attributes는 태그에 관련된 배열요소인 반면에 value는 태그가 닫힌 후에 나오는 값이 기록됩니다. 여기서 태그가 닫혔다는 것은 종료태그를 의미하는 것이 아니라 태그의 끝은 의미하는 ">"문자가 나타났다는 것을 의미합니다.
[code html;gutter:false] <TD>
< HTML 파서 >를 이용한 HTML 문서 분석 [/code]
예를 들어 위와 같은 HTML 문서를 분석하면 아래와 같은 배열을 얻을 수 있습니다.
$vals[1][tag]="TD"
$vals[1][type]="open"
$vals[1][value]=" < HTML 파서 >를 이용한 HTML 문서 분석 "
앞 태그와 뒷 태그 사이에 아무런 값이 없다면 앞 태그의 value 배열에는 빈 문자열 또는 하나의 white space가 기록됩니다.
<!-- ... --> 및 <! ...>의 처리
<!-- ... -->
원래 HTML 문서상에 있던 주석(<!-- ... -->)은 html_parse_into_struct 함수를 실행하는 중에 모두 삭제됩니다.
<! ...>
이러한 코드의 예로는 <!DOCTYPE HTML PUBLIC -//W3C//DTD HTML 4.0//EN> 가 있습니다. 이와 같이 <! 로 시작하는 태그는 다른 태그와는 달리 html_parse_into_struct 함수에서 태그로 처리하지 않고 일반 문자열로 처리합니다.
[code html;gutter:false] <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<HTML> [/code]
예를 들어 위와 같은 HTML 문서를 분석하면 아래와 같은 배열을 얻을 수 있습니다.
$vals[0][tag]=""
$vals[0][type]="cdata"
$vals[0][value]="<!--HTML_PARSER 0.0.1-->"

$vals[1][tag]=""
$vals[1][type]="cdata"
$vals[1][value]="<!DOCTYPE HTML PUBLIC -//W3C//DTD HTML 4.0//EN> "

$vals[2][tag]="HTML"
$vals[2][type]="open"
$vals[2][value]=" "

'phpsource > 파일분석' 카테고리의 다른 글

{TAR 파일}1.개요  (0) 2002.09.09
{HTML 파서}5.다운로드  (0) 2001.07.24
{HTML 파서}3.배열 구조를 보여주는 예제  (0) 2001.07.24
{HTML 파서}2.파서 관련 함수  (1) 2001.07.24
{HTML 파서}1.개요  (0) 2001.07.24
Posted by 방글24
phpsource/파일분석2001. 7. 24. 17:41
배열구조를 보여주는 예제
HTML 문서
우선 아래와 같은 HTML 문서(파일명:sample.html)가 있다고 하지요.
[code html;gutter:false] <HTML>
<HEAD>
<SCRIPT language="JavaScript">
<!--
document.write("abc");
-->
</SCRIPT>
<style>
table td { font-size:.7em; }
</style>
</HEAD>
<BODY>
<TABLE>
<TR>
<TD>
< HTML 파서 >를 이용한 HTML 문서 분석
</TD>
</TR>
</TABLE>
</BODY>
</HTML> [/code]
HTML 문서를 분석하는 예제
아래는 위에 있는 HTML 문서를 이 함수에 의해 분석하여 생성된 배열구조를 보여주는 예제(파일명:test.php)입니다.
[code php;gutter:false] <?php

$file = "./sample.html";
$data = implode("", file($file));

include("./class.htmlparser.php"); // HTML 파서 클래스

$parser = new HtmlParser;

$parser->html_parse_into_struct($data, $vals);

var_dump($vals);

?> [/code]
예제 실행 결과
위의 코드를 실행하면 아래와 같은 결과를 얻을 수 있습니다.
array(17) {
   [0]=>
   array(3) {
     ["tag"]=>
     string(0) ""
     ["type"]=>
     string(5) "cdata"
     ["value"]=>
     string(24) "<!--HTML_PARSER 0.0.1-->"
   }
   [1]=>
   array(4) {
     ["tag"]=>
     string(4) "HTML"
     ["type"]=>
     string(4) "open"
     ["attributes"]=>
     array(0) {
     }
     ["value"]=>
     string(1) "
     "
   }
   [2]=>
   array(4) {
     ["tag"]=>
     string(4) "HEAD"
     ["type"]=>
     string(4) "open"
     ["attributes"]=>
     array(0) {
     }
     ["value"]=>
     string(2) "
     "
   }
   [3]=>
   array(4) {
     ["tag"]=>
     string(6) "SCRIPT"
     ["type"]=>
     string(4) "open"
     ["attributes"]=>
     array(1) {
       ["language"]=>
       string(10) "JavaScript"
     }
     ["value"]=>
     string(37) "
   <!--
   document.write("abc");
   -->
   "
   }
   [4]=>
   array(3) {
     ["tag"]=>
     string(6) "SCRIPT"
     ["type"]=>
     string(5) "close"
     ["value"]=>
     string(2) "
     "
   }
   [5]=>
   array(4) {
     ["tag"]=>
     string(5) "STYLE"
     ["type"]=>
     string(4) "open"
     ["attributes"]=>
     array(0) {
     }
     ["value"]=>
     string(33) "
   table td { font-size:.7em; }
   "
   }
   [6]=>
   array(3) {
     ["tag"]=>
     string(5) "STYLE"
     ["type"]=>
     string(5) "close"
     ["value"]=>
     string(1) "
   "
   }
   [7]=>
   array(3) {
     ["tag"]=>
     string(4) "HEAD"
     ["type"]=>
     string(5) "close"
     ["value"]=>
     string(1) "
   "
   }
   [8]=>
   array(4) {
     ["tag"]=>
     string(4) "BODY"
     ["type"]=>
     string(4) "open"
     ["attributes"]=>
     array(0) {
     }
     ["value"]=>
     string(2) "
   "
   }
   [9]=>
   array(4) {
     ["tag"]=>
     string(5) "TABLE"
     ["type"]=>
     string(4) "open"
     ["attributes"]=>
     array(0) {
     }
     ["value"]=>
     string(3) "
   "
   }
   [10]=>
   array(4) {
     ["tag"]=>
     string(2) "TR"
     ["type"]=>
     string(4) "open"
     ["attributes"]=>
     array(0) {
     }
     ["value"]=>
     string(4) "
    "
   }
   [11]=>
   array(4) {
     ["tag"]=>
     string(2) "TD"
     ["type"]=>
     string(4) "open"
     ["attributes"]=>
     array(0) {
     }
     ["value"]=>
     string(46) "
   < HTML 파서 >를 이용한 HTML 문서 분석
   "
   }
   [12]=>
   array(3) {
     ["tag"]=>
     string(2) "TD"
     ["type"]=>
     string(5) "close"
     ["value"]=>
     string(3) "
   "
   }
   [13]=>
   array(3) {
     ["tag"]=>
     string(2) "TR"
     ["type"]=>
     string(5) "close"
     ["value"]=>
     string(2) "
   "
   }
   [14]=>
   array(3) {
     ["tag"]=>
     string(5) "TABLE"
     ["type"]=>
     string(5) "close"
     ["value"]=>
     string(1) "
   "
   }
   [15]=>
   array(3) {
     ["tag"]=>
     string(4) "BODY"
     ["type"]=>
     string(5) "close"
     ["value"]=>
     string(1) "
   "
   }
   [16]=>
   array(3) {
     ["tag"]=>
     string(4) "HTML"
     ["type"]=>
     string(5) "close"
     ["value"]=>
     string(0) ""
   }
}
위의 결과는 PHP4에서 실행한 결과입니다. PHP에서 제공하고 있는 var_dump() 함수의 결과가 버전에 따라 다소 다르게 나타나고 있으니 이를 염두에 두시기 바랍니다. PHP 버전 4.0 이상에서는 var_dump 함수 대신에 print_r 함수를 사용하면 좀더 보기 편할 것입니다.

'phpsource > 파일분석' 카테고리의 다른 글

{TAR 파일}1.개요  (0) 2002.09.09
{HTML 파서}5.다운로드  (0) 2001.07.24
{HTML 파서}4.배열 구조의 구성  (0) 2001.07.24
{HTML 파서}2.파서 관련 함수  (1) 2001.07.24
{HTML 파서}1.개요  (0) 2001.07.24
Posted by 방글24
phpsource/파일분석2001. 7. 24. 17:35
제공되는 함수
현재는 xml 파서 함수 중 xml_parse_into_struct 함수를 모델링한 html_parse_into_struct 함수만 제공됩니다.
함수 버전 기능 클래스명
html_parse_into_struct 0.0.1 HTML 데이터를 배열 구조로 분석 HtmlParser
int html_parse_into_struct (string data, array &values)
html_parse_into_struct 함수는 HTML 규약에 의해 작성된 문서를 배열 구조의 데이터로 분석합니다. 이 배열 구조는 xml 문서를 분석하기 위하여 작성된 xml_parse_into_struct와 입력 및 출력 인터페이스가 거의 유사합니다. 그러나 xlm_parse_into_struct와는 달리 배열 구조내에서의 각 태그의 위치를 나타내는 index값을 반환하지 않습니다.
두번째 매개변수인 values는 반드시 "passed by reference" 되어야 합니다. reference(참조) 대한 자세한 정보는 홈페이지 메뉴에서 "핍클래스홈>>참조(레퍼런스)"을 보시기 바랍니다.
객체 생성 및 함수 실행
html_parse_into_struct 함수는 HtmlParser라는 클래스의 멤버로 존재하는 메소드입니다. 이 클래스는 class.htmlparser.php라는 파일명에 정의되어 있습니다.
[code php;gutter:false] //
// HTML 파서 클래스
//
include("./class.htmlparser.php");

//
// 객체 생성
// PHP4에서는 아래 문장에서 사용한 객체복사 대신에 참조를 이용하세요.
// ($parser =& new HtmlParser // 객체참조)
//
$parser = new HtmlParser; // 객체생성 및 복사

//
// 함수 실행
//
$parser->html_parse_into_struct($html_source, $vals); [/code]
HTML 문서의 문제점(?) -> html_parse_into_struct()의 한계
html_parse_into_struct를 작성하면서 느낀 점이 있다면 웹브라우저가 잘못 작성된 html 문서를 너무 많이 허용하고 있다는 것입니다. 물론 C 언어를 이용하여 작성한다면야 별문제 없겠지만 PHP 스크립트를 이용하여 작성된 파서에서 웹브라우저에서 허용하는 만큼의 융통성을 위해 모든 문제를 검사한다는 것은 실행시간의 한계로 인해 다소 무리가 될 것 같습니다. 따라서 html_parse_into_struct() 함수는 미완성인 HTML 문서를 분석하기에는 역부족이고 이미 작성되어 웹서비스를 하고있는 홈페이지 문서에 대하여 분석하는 정도로, 또한 너무 복잡하지 않고 가능한한 단순한 문서를 분석하는 정도로 만족하여야 할 것 같습니다.
이 함수를 공개하기 전에 분석 및 활용의 적정성을 판단하기 위해 간단치 않는 실험을 수행하였습니다. 실험방법은 html_parse_into_struct() 함수를 통해 얻어진 데이터를 가지고 간단한 태그 유효성 검사 및 문제점 수정 단계를 거쳐 제가 이미 공개한 바 있는 유닛테이블 문서로 변환하는 실험이었습니다. 이를 단계별로 구분한다면 아래와 같은 3단계를 거치는 실험이었습니다.
HTML 문서 -> [HTML 파서 클래스] -> [태그 유효성 검사 및 수정 클래스]
-> [문서변환 클래스] -> 유닛테이블 문서
이번에 공개하는 것은 이 중에 첫단계인 "HTML 파서 클래스"입니다. "태그 유효성 검사 및 수정 클래스"에서 하는 일을 보면 모든 문제점을 검사/수정하는 것은 아니고 <TABLE>, <TR>, <TD> 태그의 시작태그와 종료태그의 짝을 맞추기 위한 기능이 거의 전부입니다. 이러한 과정을 요구하는 이유는 유닛테이블 문서로 변환하려면 테이블 관련 태그에 대해 매우 엄격히 작성되어야 하기 때문입니다. 그런데 실험을 통하여 알게된 사실이지만 인터넷 상의 많은 문서가 이에 대하여 매우 소홀히 다루고 있다는 것입니다. 물론 웹브라우저가 알아서(?) 잘 보여주기 때문에 이 문제에 대하여 소홀히 다루게 되는 것 같습니다만 이와같이 적당히 웹문서를 만드는 것은 별로 좋은 습관이 아닌 것 같습니다.
이 실험을 통해 인터넷 상에 있는 웹문서들을 유닛테이블 문서로 변환하는데 대부분 성공하게 되었습니다. 시간 제약상 많은 문서에 대하여 실험할 수는 없었고 약 20여가지의 문서에 대하여 실험하였습니다.
cafe4.daum.net, asp.net, dialpad.co.kr, editplus.co.kr, java.sun.com, javascript.co.kr, namo.co.kr 중 게시판 부분, phpschool.com, phpclass.com, shinbiro.com, simmani.com, www.freechal.com, linux.sarang.net, yahoo.co.kr ......
이 실험을 통해 얻은 또 다른 것이 있다면 유닛테이블로 만이 아니라 우리가 잘 알고 있는 FastTemplate 문서와 같은 다른 템플릿 문서로 변환하는 것도 그리 어렵지 않다는 것이지요. 현재 많이 활용되고 있는 템플릿 기술이 XML로 가는 과정에서의 중간단계 역할로 많은 한계를 가질 수 밖에 없겠지만(???) 아직 인터넷 상의 모든 문서가 XML로 가기까지는 다소 시간이 필요할 것 같으며(모든 웹문서가 향후 XML로 작성되어야 하는지에 대하여는 잘 모르겠음), 당장에 순수 HTML 문서의 한계성을 극복하는 한 방편으로서의 템플릿 기술은 당분간 필요하다는 생각이 듭니다.
HTML 파서 클래스를 활용하여 여러분이 한번 HTML 문서를 FastTemplate 문서로 변환하는 클래스를 한 번 작성해 보시지 않겠습니까?

'phpsource > 파일분석' 카테고리의 다른 글

{TAR 파일}1.개요  (0) 2002.09.09
{HTML 파서}5.다운로드  (0) 2001.07.24
{HTML 파서}4.배열 구조의 구성  (0) 2001.07.24
{HTML 파서}3.배열 구조를 보여주는 예제  (0) 2001.07.24
{HTML 파서}1.개요  (0) 2001.07.24
Posted by 방글24
phpsource/파일분석2001. 7. 24. 17:32
HTML 규약에 의해 작성된 문서를 분석하는 함수입니다.
0.0.1p2에서는 아래의 예와 같이 0.0.1p1에서 속성값에 인용부호가 나타날 때 생기는 문제점을 일부 해결하기 위해 약간 수정하였습니다.
[code html;gutter:false] <A href=javascript:openMail("xxx@xxxxx.com")>xxx@xxxxx.com</A> [/code]
위와 같이 바깥쪽 인용부호를 생략한 채 xxx@xxxxx.com을 이중 인용부호로 둘러싸는 경우 에러가 발생합니다. 해결하자니 소스가 너무 복잡해 지네요. 그러니 이러한 경우 HTML 문서를 작성할 때 아래와 같이 수정하시기 바랍니다. 그래야 에러가 발생하지 않습니다.
[code html;gutter:false] <A href=javascript:openMail('xxx@xxxxx.com')>xxx@xxxxx.com</A> [/code]
또는,
[code html;gutter:false] <A href="javascript:openMail('xxx@xxxxx.com')">xxx@xxxxx.com</A> [/code]
또는,
[code html;gutter:false] <A href='javascript:openMail("xxx@xxxxx.com")'>xxx@xxxxx.com</A> [/code]
와 같이 수정하시면 됩니다. 이 중에 두 번째 또는 세 번째와 같이 바깥쪽으로도 인용부호로 둘러싸는 습관을 들이시기 바랍니다. 나모 웹에디터에서 작업할 때는 이와 같은 경우 나모에서 자동으로 바깥쪽 인용부호를 붙여줍니다만 일반 텍스트 편집기를 이용하여 직접 소스를 작성할 때는 습관상 생략하는 경우도 있을 것입니다.

'phpsource > 파일분석' 카테고리의 다른 글

{TAR 파일}1.개요  (0) 2002.09.09
{HTML 파서}5.다운로드  (0) 2001.07.24
{HTML 파서}4.배열 구조의 구성  (0) 2001.07.24
{HTML 파서}3.배열 구조를 보여주는 예제  (0) 2001.07.24
{HTML 파서}2.파서 관련 함수  (1) 2001.07.24
Posted by 방글24
phpsource/클래스&객체2001. 4. 12. 10:45
인풀링 클래스는 인스턴스 풀링(Instance Pooling)을 흉내내기 위해 작성된 클래스입니다.
인스턴스 풀링이란 자주 사용하는 객체를 메모리에 상주시키고, 보다 빠르게 객체를 사용할 수 있도록 하는 것입니다. 동시에 많은 사용자가 접속했을 때 이미 메모리에 올라온 인스턴스가 있으면 그것을 사용하고, 올라온 내용이 없을 때는 인스턴스를 하나 더 만듭니다.
이러한 인스턴스 풀링은 PHP에서 내장하여 지원하여야만 효과적으로 사용할 수 있을 것입니다. 그러나 지원되지 않으니 좀 미숙하더라도 편리하게 사용될 것 같아 인풀링 클래스를 작성하여 공개합니다.
이것은 Q&A 게시판에 채명신 님이 질의하신 내용에 대한 결과로 얻어진 것입니다.
아래는 채명신 님의 질문 내용의 요약입니다.
[채명신 님의 질문 내용]
생성한 클래스를 다른 사람이 참조할수 있는 방법은요?
자바에서의 풀링 기법과 비슷하다고나 할까??
그러니까 한번 생성된 클래스는 (특히 복잡한 계산에의해 생성된 클래스를) 클라이언트의 요청시마다 독립적인 각각의 클래스를 새로 만들어서 자신이 만든 클래스만을 참조 하는것이 아니라, 기존에 만들어진 클래스가 있다면 그것을 참조 하는 것이죠. 그니까 제일 처음에 로그인함 사람이 만들면 컴이 꺼진기전에 다른 사람은 만든 글래스를 그냥 공유 해서 쓰는 것이죠.
[답장 내용]
개체 또는 인스턴스 풀링(instance pooling)을 원하시는 것 같네요. PHP에서는 영구접속 방법을 통한 데이터베이스 풀링이 지원되기는 하지만 인스턴스 풀링까지는 지원되지 않는 것 같습니다. 하지만 마음만 먹는다면 흉내는 얼마든지 낼 수 있겠지요. 좀 복잡해 지겠지만 이것도 함수 또는 클래스로 미리 작성해 놓고 사용하면 쓸만하겠네요. 인스턴스 풀링을 흉내내기 위해 필요한 것을 살펴보지요.
1. 모든 방문자가 공유하는 영역 만들기
이것은 제가 공개한 애플리케이셔너를 참조하시든지 아니면 세션파일과 같이 /tmp 에 모든 방문자가 공유할 파일을 생성시키면 되겠지요. 인스턴스 풀링처럼 필요한 정보를 메모리에 상주시키려면 공유메모리를 이용하면 되겠지요. 이러한 공유영역에는 복수의 방문자가 공유할 생성된 클래스 정의와  객체가 저장되겠지요.
2. 메소드 및 프로퍼티의 직렬화/객체화하기
객체 멤버를 다른 페이지로 넘기기 위해서는 PHP4에서 지원하는 serialize() 함수와
unserialize() 함수를 이용하셔야 합니다. 이에 대한 자세한 정보는 제 홈페이지 "핍클래스홈 >> 객체에 관련된 정보 >> Serialize/Unserialize 또는 메소드 다루기(PHP4)"를 참조하세요. 추가적으로 말씀드린다면 serialize/unserialize 함수에서는 객체멤버를 다루기는 하지만 클래스를 다루어 주지 않거든요. 사실 Serialize/Unserialize 정보를 공개하면서도 클래스 정의 부분을 포함시킬까 말까하고 고민을 하였었는데 복잡해 질 것 같아 생략했었지요.
아무튼 위 두가지에 대한 지식만 가지고 계시다면 님도 원하시는 인스턴스 풀링 기능을 흉내낼 수 있는 함수를 작성할 수 있으리라 봅니다. 위에서도 이야기했지만 다른 것보다도 클래스 정의 부분을 공유하는 것만 주의한다면 별 어려움은 없을 것입니다.
함수로 만들어 놓으면 상당히 유용한 기능이 될 것 같네요. 앞으로 시간이 허락되면 작성하여 공개하고 싶군요.
[채명신 님의 재질의 내용]
그니까  말씀 하신 방법중에 "인스턴스 풀링처럼 필요한 정보를 메모리에 상주시키려면 공유메모리를 " 이용하면 되겠지요. 이러한 공유영역에는 복수의 방문자가 공유할 생성된 클래스 정의와  객체가 저장되겠지요......................ㅠ.ㅠ"
이 메모리는 어커 &#50080;야 하는지요  ㅠ.ㅠ ??????
관련 소스나 참고 알고리즘이 있으시면 도움을 바랍니다. 13 일 까지 해결 해야 하는데........ 내가 이해나 할수 있을까.  흑흑
 초보자인 저는 더욱 난해 하네요.. 다시한번 답변은 정말 감사 합니다  그러나. 공유 메모리...ㅠㅠ 그놈의 메모리는 .... 지금은 시간이 없는 관계로 없는 실력으로 자바로 써볼려고 합니다 ..
언제가  만들어지면  이용 해야겠네요 ^^ 또 이런 비슷한 일이 생기면 ........... 도움을 많이 받아 갑니다.. 헤헤 ^ ^
그럼 시간이 되시면 부탁 드립니다 . 감사 감사
[재답장 내용]
우선 급한대로 인스턴스 풀링을 구현하는 클래스를 조잡하게나마 작성하여 Tip&Tech&Download 게시판에 올렸습니다. 자세한 사용법까지 설명할 수는 없고 테스트용 샘플도 포함시켰으니 살펴보세요.
(수정:2010.1.12) 홈페이지 이동으로 여기에서 다운로드 받으세요.
모든 방문자가 공유할 클래스 정의는 이벤트 파일에 변수로서 저장하게 됩니다. 물론 일반 텍스트 파일로도 작성할 수도 있으며 이렇게 하여야 될 것 같으나 시간이 더 걸릴 것 같아 급한대로 변수에 저장시켰습니다.
인풀링 클래스(인스턴스 풀링을 흉내내기 위해 작성된 클래스) 사용상의 주의점
1. 위에서도 언급했듯이 급하게 만들다보니 버그가 상존하지 않을까 걱정됩니다.
2. 공유메모리와 세마포어를 이용하여 작성되었습니다. 그러나 공유메모리용 함수가 PHP 4.0.4부터 성능이 대폭 개선된 함수를 새로이 제공되고 있으나 여기에서는 기존의 공유메모리 함수인 shm_...()함수를 사용하였습니다. 그러니 PHP 4.0.4를 사용하시는 분은 개선된 공유메모리 함수인 shmop_...() 함수를 사용하세요.
3. 모든 방문자가 공유할 클래스 정의는 이벤트 파일에 변수로서 저장하도록 하였습니다. 이부분을 좀 더 개선한다면 일반 텍스트 파일로 작성하는 것이 바람직할 것입니다. 아래는 파일에 첨부된 이벤트 파일 내용입니다. 이 이벤트 파일에 있는 pooling_onStart() 함수는 최초의 방문자가 방문할 때만 실행하게 됩니다. 이 함수에서 돌려주는 $class에 클래스 정의가 담겨지며 되돌려진 $class의 내용은 인풀링 클래스 내에서 객체로 생성한 후 공유메모리에 클래스 정의와 객체가 함께 저장하여 다음 방문자들이 공유할 수 있도록 합니다.
[code php;gutter:false] function pooling_onStart() {
$class = "
class test {
var \$a = 1000;
var \$b = "\\\$b값";

function output() {
return "나 함수";
}
}
";
return $class;
} [/code]
클래스 정의를 $class와 같은 변수에 담을 것이 아니라 아래와 같이 텍스트 파일에 저장한 후 인풀링 클래스에서 읽어들이는 것이 좋을 것입니다.
[code php;gutter:false] class test {
var $a = 1000;
var $b = "\$b값";

function output() {
return "나 함수";
}
} [/code]
이렇게 하니까 가독성이 훨씬 좋지 않습니까? 이것을 구현하는 것을 여러분이 해보시지 않겠습니까? 제가 해도 되겠지만...
4. 아래는 인풀링 클래스를 테스트하는 프로그램 test.php입니다. 이 파일도 첨부되어 있습니다.
[code php;gutter:false] <?php
require("./class.poolshm.php");

$ip =& new inPooling;
if ("delete" == $exec)
$ip->delete();
$obj =& $ip->read();

echo $obj->a."\n";
echo $obj->b."\n";
echo $obj->output()."\n";

$obj->b = $exec;
$ip->write($obj);
$ip->close();
?> [/code]
아래와 같은 방법으로 서로 다른 컴퓨터에서 아니면 다른 브라우저로 실험해 보세요.
http://....../inpooling/test.php
http://....../inpooling/test.php?exec=delete
http://....../inpooling/test.php?exec=연습
화면에는 아래와 같이 나타날 것입니다. 여기서 두번째 줄의 내용을 URL의 exec파라미터의 값에 따라 계속 변할 것이고 exec값이 "delete"이면 현재의 공유메모리의 내용이 지워집니다.
1000
$b값
나 함수
5. 인풀링 클래스는 PHP 4 버전에서만 사용할 수 있습니다. PHP 3.x.x에서는 지원하지 않는 레퍼런스(참조)를 사용하였습니다. 참조에 대한 자세한 설명은 제 홈페이지 "class & object>> 참조(레퍼런스)"를 보세요.

Posted by 방글24
phpsource/회원인증2001. 2. 22. 15:06
제공되는 메소드
메소드 버전 기능
생성자 0.0.1 쿠커의 객체화, 초기값 설정
check 0.0.1 인증회원에게 현재페이지의 접근을 허용할 것인가를 확인
name 0.0.1 사용자명 및 암호를 저장하는 쿠키명을 획득/설정
logout 0.0.1 로그아웃. 모든 사용자 정보를 삭제
메소드 사용법
생성자 permCook([, string err [, bool path]])
[code php;gutter:false] $perm = new permCook("회원전용 서비스를 받으시려면 먼저 회원으로 가입하세요."); [/code]
생성자에서는 허용되지 않은 방문자가 접근하였을 때 보여주는 에러메시지 err와 인증창에서 디렉토리 인증을 수행하였을 때 필요한 path 매개변수를 지정합니다.
허용되지 않은 방문자가 접근하면 check() 함수를 실행할 때 아래와 같은 에러 양식이 나타납니다. 이 에러 양식에 나타낼 문자열이 첫번째 매개변수 err입니다.
< 에러 출력 화면 >
두번째 파리미터는 쿠키인증 클래스에서와 마찬가지로 디렉토리별로 인증을 수행할 수 있도록 해줍니다. 이 매개변수는 쿠키인증 클래스에서 지정된 값과 동일한 값으로 지정하여야 합니다.
[code php;gutter:false] $perm = new permCook("회원전용 서비스를 받으시려면 먼저 회원으로 가입하세요." , true); [/code]
생성자의 첫번째 매개변수는 또 다른 중요한 기능을 가지고 있습니다. 이를 지정하면 에러 화면에 나타날 문자열이 되지만 이를 생략하거나 널문자를 넘기게 되면 check() 함수를 수행할 때 에러화면이 나타나지 않습니다. 에러 화면은 생성자의 첫번째 매개변수에 널문자가 아닌 문자를 지정하였을 때만 나타나게 되어 있습니다. 이를 지정하지 않으면 어떠한 에러화면도 나타나지 않습니다.
첫번째 매개변수를 지정하게 되면 check() 함수를 실행하는 중에 에러가 발생하면 이에 상당하는 각종 에러 화면을 알아서 보여주지만 대신에 제어권을 사용자에게 넘기지 않습니다. 즉 에러 화면을 보여주는 즉시 실행을 중지합니다. 그러나 지정하지 않게 되면 에러 화면을 보여주지 않지만 대신에 실행을 중지하지 않고 제어권을 사용자에게 넘겨줍니다. 제어권을 사용자에게 넘기면서 현재 상태를 리턴값으로 되돌려 줍니다. 따라서 사용자는 이 값을 확인하여 적절한 처리를 해 주어야 인증 처리에 문제가 발생하지 않습니다. 적절히 처리하지 못하면 문제가 발생하지요. check() 함수에서 되돌려 주는 상태값에 대하여는 check() 함수를 참조바랍니다.
int check([string permission_type, string permission_user])
반환되는 상태를 보면 다음과 같습니다.
상태값 설명
0 현재 페이지에 대하여 접근을 허용함
1 사용자 정보가 없음. 현재 페이지에 접근하기 위해서는 먼저 로그인을 할 것
2 특정회원에게만 허용된 페이지에 호용되지 않은 회원이 접근하려고 함
3 정의되지 않은 퍼미션 등급을 지정하였음
아래는 생성자의 첫번째 매개변수를 지정하였을 때의 예입니다.
[code php;gutter:false] <?php require "./cooker/class.cooker.php"; // 쿠커 require "./authcook/class.permcook.php"; // 쿠키퍼미션 클래스 $perm = new permCook("회원전용 서비스를 받으시려면 먼저 회원으로 가입하세요."); $permission_user = "user1"; $permission_type = "owner"; $perm->check($permission_type, $permission_user); // // 페이지 퍼미션을 통과하였음 // . . . ?> [/code]
아래는 생성자의 첫번째 매개변수를 지정하지 않았을 때의 예입니다.
[code php;gutter:false] <?php require "./cooker/class.cooker.php"; // 쿠커 require "./authcook/class.permcook.php"; // 쿠키퍼미션 클래스 $perm = new permCook; $permission_user = "user1"; $permission_type = "owner"; $status = $perm->check($permission_type, $permission_user); if ($status) { switch ($status) { case 1: // 사용자 정보가 없음 echo "먼저 로그인을 하세요.\n"; break; case 2: // 특정 회원 전용 페이지 echo "회원님은 이 페이지를 이용할 수 없습니다.\n"; break; case 3: // 정의되지 않은 퍼미션 등급 echo "정의되지 않은 퍼미션 등급을 지정하였습니다. 소스코드를 확인하세요.\n"; break; } exit; } // // 페이지 퍼미션을 통과하였음 // . . . ?> [/code]
위에서와 같이 $permission_type 을 "owner"으로 설정하고, $permission_user에 특정회원ID를 설정한 후 $perm->check($permission_type, $permission_user) 함수로 확인하게 되면 쿠키에 기록된 회원ID와 $permission_user가 동일한 경우에만 페이지 접근을 허용하게 됩니다. 회원인증을 통과한 모든 회원이 볼 수 있도록 하려면 $permission_type와 $permission_user를 지정하지 않아도 되며 $perm->check() 함수를 인수없이 실행하면 로그인 과정에서 인증을 통과한 방문자는 모두 현재 페이지를 볼 수 있습니다.
string name([string newname])
쿠커에서 사용되는 쿠키명(cookie name)을 얻거나 새로운 쿠키명으로 설정할 때 사용할 수 있습니다. 새로운 쿠키명을 설정할 때는 반드시 start() 함수보다 앞서 수행하여야 합니다. 쿠커는 기본적으로 쿠키명을 "PHP_AUTH_DATA"로 설정되어 있습니다. 보안을 위해 주기적으로 변경해주는 것이 바람직합니다.
[code php;gutter:false] $auth = new authCook("회원 확인 영역"); $auth->name("NEW_COOKIE_NAME"); $status = $auth->start(); // 인증창을 띄운다. echo "현재 설정되어 있는 쿠키명은 ".$auth->name()."입니다.\n"; [/code]
void logout(void)
쿠커에 저장된 모든 사용자 정보를 삭제합니다. 아울러 쿠키파일도 삭제합니다. 이 함수는 자바스크립트로 구현되어 있으므로 어느 위치에서나 사용할 수 있습니다.
[code php;gutter:false] <?php require "./cooker/class.cooker.php"; // 쿠커 require "./authcook/class.permcook.php"; // 쿠키퍼미션 클래스 $perm = new permCook("회원전용 서비스를 받으시려면 먼저 회원으로 가입하세요."); $perm->check(); // // 페이지 퍼미션을 통과하였음 // $perm->logout(); echo "<A href=login.php3>로그인</A>"; ?> [/code]

Posted by 방글24
phpsource/회원인증2001. 2. 22. 15:00
제공되는 메소드
메소드 버전 기능
생성자 0.0.1 쿠커의 객체화, 초기값 설정
start 0.0.1 사용자명 및 암호를 입력받아 처리함
name 0.0.1 사용자명 및 암호를 저장하는 쿠키명을 획득/설정
gc_maxlifetime 0.0.1 서버상에서 확인하는 쿠키의 생존시간 획득/설정
메소드 사용법
생성자 authCook([string realm [, string err [, bool path]]])
[code php;gutter:false] $auth = new authCook("회원 확인", "회원전용 서비스를 받으시려면 먼저 회원으로 가입하세요."); [/code]
위에서와 같이 클래스 authCook을 객체화하게 되면 start() 함수를 실행할 때 아래와 같이 사용자명 및 암호를 입력받을 수 있는 양식이 나타납니다. 이 화면에서 영역이라고 표시되는 부분에 나타날 문자열이 첫번째 매개변수인 realm입니다.
< 인증창 >
위의 입력양식에서 세번 연속하여 사용자명과 암호를 모두 입력하지 않고 서브밋하면 아래와 같은 에러 양식이 나타납니다. 이 에러 양식에 나타낼 문자열이 두번째 매개변수인 err입니다.
< 에러 출력 화면 >
세번째 파리미터는 "HTTP 인증"에서는 생소한 부분입니다. "HTTP 인증"에서는 한 번 인증하면 모든 디렉토리에서 통용되지요. 이는 반대로 말한다면 디렉토리별로 인증이 어렵다는 것입니다. 그래서 많은 분들이 웹서버 아파치를 통해(.htaccess 파일을 통해) 디렉토리 별로 인증을 수행하는 것을 볼 수 있습니다. 세번째 매개변수가 이와 같이 디렉토리별로 인증을 수행할 수 있도록 쿠키인증 클래스의 쿠키 매개변수 path를 지정하는 역할을 합니다. 생략하면(기본값으로 false로 설정되어 있음) "HTTP 인증"과 마찬가지로 모든 디렉토리에 대하여 한번만 인증을 수행하게 됩니다. 디렉토리별로 인증하고 싶으면 세번째 매개변수의 값을 true라고 지정하시기 바랍니다.
[code php;gutter:false] $auth = new authCook("회원 확인 영역", "회원전용 서비스를 받으시려면 먼저 회원으로 가입하세요.", true); [/code]
생성자의 두번째 매개변수는 또 다른 중요한 기능을 가지고 있습니다. 이를 지정하면 에러 화면에 나타날 문자열이 되지만 이를 생략하거나 널문자를 넘기게 되면 start() 함수를 수행할 때 에러화면이 나타나지 않습니다. 인증창에서 사용자 정보를 입력하는 과정에서는 위에서와 같은 에러 화면말고도 여러가지 에러 화면이 존재합니다. 이미 사용자 정보를 입력하였는데 다시 입력을 요구할 때 발생하는 에러 메시지, 브라우저에 쿠키를 사용할 수 없도록 설정되어 있다는 에러 메시지 등을 위한 에러 화면이 있습니다. 그러나 이러한 에러 화면은 생성자의 두번째 매개변수에 널문자가 아닌 문자를 지정하였을 때만 나타나게 되어 있습니다. 이를 지정하지 않으면 어떠한 에러화면도 나타나지 않습니다.
생성자의 두번째 매개변수를 다른 관점에서 살펴보면, 이를 지정하게 되면 start() 함수를 실행하는 중에 에러가 발생하면 이에 상당하는 각종 에러 화면을 알아서 보여주지만 대신에 제어권을 사용자에게 넘기지 않습니다. 즉 에러 화면을 보여주는 즉시 실행을 중지합니다. 그러나 지정하지 않게 되면 에러 화면을 보여주지 않지만 대신에 실행을 중지하지 않고 제어권을 사용자에게 넘겨줍니다. 제어권을 사용자에게 넘기면서 현재 상태를 리턴값으로 되돌려 줍니다. 따라서 사용자는 이 값을 확인하여 적절한 처리를 해 주어야 인증 처리에 문제가 발생하지 않습니다. 적절히 처리하지 못하면 문제가 발생하지요. start() 함수에서 되돌려 주는 상태값에 대하여는 start() 함수를 참조바랍니다.
int start(void)
사용자 정보를 입력받는 인증창은 별도의 화면에 나타냅니다.
반환되는 상태를 보면 다음과 같습니다.
상태값 설명
0 인증창에서 사용자 이름 및 암호를 정상적으로 입력함
1 웹브라우저의 쿠키 설정이 OFF로 되어 있어 쿠키를 사용할 수 없음
2 인증창에서 사용자 이름 및 암호를 3번 이상 틀리게 입력함
3 이미 로그인 중임. 다른 ID로 인증하려면 먼저 로그아웃하기 바람.
4 인증창이 나타나 있으므로 인증창을 통해 사용자 이름 및 암호를 입력하기 바람
[code php;gutter:false] $auth = new authCook("회원 확인 영역"); $status = $auth->start(); // 인증창을 띄운다. if ($status) { switch ($status) { case 1: // 쿠키 설정이 안됨 echo "웹브라우저에 쿠키를 사용할 수 있도록 설정하세요.\n"; break; case 2: // 회원정보 입력을 3번 이상 틀림 echo "회원전용 서비스를 받으시려면 먼저 회원으로 가입하세요.\n"; break; case 3: // 이미 로그인중 echo "님은 이미 로그인중입니다." ." 다른 ID로 로그인하려면 먼저 로그아웃을 하세요.\n"; break; case 4: // 로그인창 출력중 echo "먼저 로그인창에서 회원정보를 입력하세요.\n"; break; } exit; } // // 쿠키 인증창 통과하였음 // 회원정보테이블과 입력된 회원정보를 비교하여야 함 // . . . [/code]
string name([string newname])
쿠커에서 사용되는 쿠키명(cookie name)을 얻거나 새로운 쿠키명으로 설정할 때 사용할 수 있습니다. 새로운 쿠키명을 설정할 때는 반드시 start() 함수보다 앞서 수행하여야 합니다. 쿠커는 기본적으로 쿠키명을 "PHP_AUTH_DATA"로 설정되어 있습니다. 보안을 위해 주기적으로 변경해주는 것이 바람직합니다.
[code php;gutter:false] $auth = new authCook("회원 확인 영역"); $auth->name("NEW_COOKIE_NAME"); $status = $auth->start(); // 인증창을 띄운다. echo "현재 설정되어 있는 쿠키명은 ".$auth->name()."입니다.\n"; [/code]
void gc_maxlifetime(int lifetime), int gc_maxlifetime(void)
gc_maxlifetime() 함수는 서버에서 쿠키의 유효기간을 확인할 수 있도록 그 시간을 설정하거나 획득하기 위한 함수입니다.
[code php;gutter:false] $auth->gc_maxlifetime(600); //서버에서의 쿠키지속시간(초단위/10분) $auth->start(); [/code]
쿠키가 생성된 후 10분이 지나면 서버에서 gc_maxlifetime(600)에 의해 쿠키정보를 임의로 삭제하게 됩니다. 이러한 기능은 시간에 의한 자동로그아웃을 구현할 때 유용하게 사용될 수 있을 것입니다. 또 한가지는 gc_maxlifetime() 함수로 유효기간을 설정하는 것은 쿠키를 처음 생성할 때 한번만 수행하면 됩니다. 이 함수는 실제로는 쿠커에서 모두 담당하기 때문에 로인한 후 페이지 퍼미션에서는 이 함수를 수행하지 않더라도 이미 쿠커에 의해 계속 유효하게 됩니다. 따라서 쿠키퍼미션 클래스에서는 이 함수가 제공되지 않습니다.
gc_maxlifetime() 함수에서 설정할 때는 start() 함수 전에 수행하여야 합니다.

Posted by 방글24
phpsource/회원인증2001. 2. 22. 14:55
"PHP를 이용한 HTTP 인증(HTTP authentication with PHP)"에 대한 것은 잘 알고 있으리라 생각합니다. 쿠키인증 클래스는 "PHP를 이용한 HTTP 인증"를 모델링하여 작성된 클래스입니다. "PHP를 이용한 HTTP 인증"에서 수행이 어려운 로그아웃 처리를 쉽게 수행할 수 있는 기능을 가지게 될 것입니다. 마지막 접속 후 지정된 시간(기본값은 24분)이 지나면 자동으로 로그아웃하는 기능도 가지게 될 것입니다.
쿠키에 대한 일반적인 정보는 상단메뉴의 "쿠커"정보를 참조바랍니다.
활용 예제의 구성
소스코드의 전체구성을 살펴보면 아래와 같습니다.
1. 쿠키 관리용 클래스
▶ 쿠커(class.cooker.php)
2. 쿠키인증클래스
▶ 쿠키인증 클래스(class.authcook.php)
▶ 쿠키퍼미션 클래스(class.permcook.php)
3. 회원정보 관리용 클래스
▶ 회원정보 클래스(class.member.php)
4. 실험용 예제
▶ 로그인 페이지(login.php3)
▶ 회원전용 홈페이지(home.php3)
▶ 회원#1 페이지(member1.php3)
▶ 회원#2 페이지(member2.php3)
▶ 회원#3 페이지(member3.php3)
▶ 로그아웃 페이지(logout.php3)
< 예제 구성 >
쿠커(class.cooker.php)
쿠커(Cooker) 및 쿠키 암호화 클래스에 대한 정보는 메뉴 "후키라이브러리 >> 쿠커"를 참조바랍니다.
쿠키인증 클래스(class.authcook.php)
쿠키인증 클래스는 "PHP를 이용한 HTTP 인증"를 모델링하여 작성된 클래스입니다. 쿠키인증 클래스에서 쿠키를 다루기 위해 앞서 공개된 쿠커(Cooker)와 쿠키 암호화 클래스를 이용하게 됩니다. 그러니 먼저 쿠커에 대한 자료를 참조하기 바랍니다. "PHP를 이용한 HTTP 인증"은 아래와 같이 작성되는 것이 보통입니다.
[code php;gutter:false] <?php function authentication() { Header("WWW-authenticate: basic realm=\"회원 확인\""); Header("HTTP/1.0 401 Unauthorized"); echo "회원전용 서비스를 받으시려면 먼저 회원으로 가입하세요."; exit; } if (!$PHP_AUTH_USER || !$PHP_AUTH_PW) { // // 인증창에 값을 입력하지 않은 경우 다시 인증창을 띄운다. // authentication(); exit; } // // 인증창 통과하였음 // 여기에서 회원 인증을 한다. // ...... 디비 등을 이용하여 회원 인증을 위한 소스 코드 삽입 ...... if (회원인증에 실패했으면?) { authentication(); // 다시 인증창을 띄운다. exit; } // // 회원인증에 성공함 // echo "<META http-equiv='Refresh' content='0; URL=home.php3'>"; ?> [/code]
쿠키인증 클래스를 이용하여 위와 동일한(?) 기능을 할 수 있도록 작성하면 다음과 같습니다.
[code php;gutter:false] <?php require "./cooker/class.cooker.php"; // 쿠커 require "./authcook/class.authcook.php"; // 쿠키인증 클래스 $auth = new authCook("회원 확인", "회원전용 서비스를 받으시려면 먼저 회원으로 가입하세요."); $auth->start(); // 인증창을 띄운다. // // 인증창 통과하였음 // 여기에서 회원 인증을 한다. // ...... 디비 등을 이용하여 회원 인증을 위한 소스 코드 삽입 ...... if (회원인증에 실패했으면?) { $auth->start(); // 다시 인증창을 띄운다. exit; } // // 회원인증에 성공함 // echo "<META http-equiv='Refresh' content='0; URL=home.php3'>"; ?> [/code]
쿠키퍼미션 클래스(class.permcook.php)
일단 회원인증에 성공하게 되면 쿠커(Cooker)에 의해 클라이언트 쿠키영역에 정해진 양식대로 회원정보가 기록되며, 각 회원 전용 페이지에서는 기록된 회원정보를 가지고 페이지 접근 허용 여부를 결정하게 됩니다. 이를 위해 작성된 클래스가 쿠키퍼미션 클래스입니다.
[code php;gutter:false] <?php require "./cooker/class.cooker.php"; // 쿠커 require "./authcook/class.permcook.php"; // 쿠키퍼미션 클래스 $perm = new permCook("회원전용 서비스를 받으시려면 먼저 회원으로 가입하세요."); $permission_user = "user1"; $permission_type = "owner"; $perm->check($permission_type, $permission_user); // // 페이지 퍼미션을 통과하였음 // . . . ?> [/code]
회원정보 클래스(class.member.php)
회원정보 클래스의 목적은 보통 데이터베이스에 기록되어 있는 회원정보와 로그인 과정에서 취득하게 되는 회원ID와 패스워드를 비교하여 방문자가 등록된 회원인가를 확인하는 것을 도와주기 위한 것입니다. 그러나 제가 공개한 본 클래스는 쿠키인증 클래스를 실험하기 위해 임시로 작성되어 있으며 여기서는 회원에 대한 정보를 데이터베이스가 아닌 일반 배열에 담았습니다. 따라서 이 클래스를 실전에서 사용하기 위해서는 소스 코드를 대폭 수정하여 데이터베이스를 이용하여 회원정보를 관리할 수 있도록 하여야 할 것입니다. 그러니 이 클래스는 쿠키인증 클래스의 실험용 이상의 의미를 두지 마시기 바랍니다.
페이지 구성 및 회원별 접근 제한
예제 프로그램에서는 페이지 #1, #2, #3는 퍼미션 등급이 "owner"으로 설정되어 있고, 홈페이지와 로그아웃 페이지는 퍼미션 등급이 설정되어 있지 않습니다.
페이지 구성 접근이 허용된 회원
로그인 페이지 모든 방문자
홈페이지 로그인한 모든 회원
페이지 #1 로그인한 "user1" 회원
페이지 #2 로그인한 "user2" 회원
페이지 #3 로그인한 "user3" 회원
로그아웃 페이지 로그인한 모든 회원
회원정보 클래스에 저장된 회원정보
위에서 언급한 바와 같이 회원정보가 배열의 형태로 저장되어 있습니다.
사용자 이름 암호
user1 test
user2 test
user3 test

Posted by 방글24