구슬이네 IT & Media / IT 와 미디어를 바라봅니다

ABAP 형변환

IT 개발/SAP-ABAP 2012. 4. 20. 16:17


원문 : http://www.abapschool.com/board/xboard/read.php?boardname=qna&list_num=773&offset=1155&PHPSESSID=509f1a872cc40ebdcacf32fa72f33320

 

형변환이 대한 것입니다. abap help 에 나와 있는 내용을 정리해 봤습니다.

generic type 이외에 predefined type (사전정의된유형) 에 대하여만 참고 바랍니다.

 

generic type 은 Assign 되는 source field 의 타입속성을 따르게 때문에 따로 정리할 수가 없을 것 같습니다.

 

Predefined type 에 대하여는 다음과 같습니다.

( 자세한 설명은 도움말을 참고하여 주시기 바랍니다.)

 

source field Type C => target field type C, D, F, I, B, S, N, P, STRING, T, X, XSTRING

source field Type D => target field type C, D, F, I, B, S, P, STRING, T, X, XSTRING

source field Type F => target field type C, D, F, I, B, S, N, P, STRING, T, X, XSTRING

source field Type I, B OR S => target field type C, D, F, I, B, S, N, P, STRING, T, X, XSTRING

source field Type N => target field type C, D, F, I, B, S, N, P, STRING, T, X, XSTRING

source field Type P => target field type C, D, F, I, B, S, N, P, STRING, T, X, XSTRING

source field Type STRING => target field type C, D, F, I, B, S, N, P, STRING, T, X, XSTRING

source field Type T => target field type C, D, F, I, B, S, N, P, STRING, T, X, XSTRING

source field Type X => target field type C, D, F, I, B, S, N, P, STRING, T, X, XSTRING

source field Type XSTRING => target field type C, D, F, I, B, S, N, P, STRING, T, X, XSTRING

 

보시면 아시겠지만 형변환이 별 차이가 없습니다.

 

[첫번째 질문]

 

DATA L_CHAR TYPE CHAR 10 VALUE '         0      '.

DATA L_INT      TYPE I.

 

* L_CHAR 의 문자가 숫자뿐이라면

IF L_CHAR CO '0123456789'.

    L_INT = L_CHAR.

ELSE.

* 숫자이외의 문자가 있으므로 변환불가입니다.

ENDIF.

 

이렇게만 해주시면 됩니다.

 

[두번째 질문]

아밥에서 NULL은 거의 사용을 하지 않습니다.

 

사전정의된 데이터 타입은 기본적으로 정의될때 기본값을 가지므로

NULL 에 대한 점검이 거의 없다고 보시면 됩니다.

 

궂이 NULL 을 갖는 값을 원하신다면

 

CLEAR field WITH NULL.

 

로 CLEAR 하셔야 합니다.

 

질문은 문자열 치환방법이나 공백제거 방법에 대하여 물어보신것으로 하고 답변드립니다.

(사용방법은 개인별로 방법이 다 달라서 제가 가끔 사용하는 방법위주로 말씀드리겠습니다)

문자열 치환 :

단일문자 치환

DATA L_STRING TYPE CHAR10 VALUE 'ABCDEFGHIJ'.

* L_STRING 을 모두 소문자로 변환한다면

TRANSLATE L_STRING TO LOWER CASE.

* 또는

TRANSLATE L_STRING USING 'AaBbCcDdEeFfGgHhIiJj'.

 

공백제거( 문자열에 대하여 )

DATA L_STRING TYPE CHAR10 VALUE '   BAS   '.

 

SHIFT L_STRING RIGHT DELETING TRAILING SPACE.

 

등등...

 

문자열에서 특정한 문자(공백같은) 에 대하여 NULL 값으로 주는 것은 힘들 것 같습니다.

 

수고하세요.

(*) 배열조작

IT 개발/PHP 2012. 3. 13. 08:45




출처 : http://blog.naver.com/palace0324/80040435883


 

1. list()

 

list($key, $value)

  - list() 함수는 배열로 받은 것을 키와 배열 값으로 나누어 준다.

 

 

2. each()

 

each($array)

  - each() 는 배열을 받아서 키와 값으로 되돌려 주는 역할을 한다.

  - 배열 값을 가지고 올 때 처음부터 가지고 오며, 그 다음이 불러지면 자동으로 다음 배열을 가지고 온다.

     따라서 while 문이 계속 돌아간다.

 

each()에서 받은 배열을 list에서 키와 배열 값으로 나누어 주는 것이다.

 

/* 예제 */

<?php

$colors = array("ext"=>"blue", "trim"=>"black", "fab"=>"yellow", "das"=>"hunter green");

reset($colors);

while (list($key, $value) = each($colors)) {

  print "$key: $value<BR>";

}

?>

 

/* 예제 설명 */

reset($colors);  → $colors 배열의 처음으로 포인터 이동.

list($key, $value);  → 배열의 key와 value 값을 부름. (여기서는 "ext"와 "blue"를 부름)

each($colors);  → $colors 배열을 선택. 다음에 불려질 때는 포인터가 하나 증가함.

list($key, $value) = each($colors);  → $color 배열의 값을 $vlaue에, 키 값을 $key에 할당한다.

 

 

2. foreach()

 

foreach ($array as $key => $val)

  - $array 배열의 키 값은 $key에, 배열 값은 $val에 나누어 할당한다.

  - foreach ($array as $value)는 배열 값만 $value에 할당한다.

  - $array 배열 값이 존재할 때까지 자동으로 루프를 돌게 된다.

  - list()에 비해 내부적으로 더 빠르다.

 

foreach() 예제 보기

 



홈페이지를 옮겨서 새주소 바로가기를 알려드립니다.


http://studium.tistory.com/165



'IT 개발 > PHP' 카테고리의 다른 글

PHP 모니터링용 소스  (0) 2012.05.16
(*) 배열조작  (0) 2012.03.13
쉘 스크립트로써의 PHP cli  (0) 2012.01.05
실시간 운영체제로의 영역 확장 PHP  (0) 2012.01.05
PHP 프로그램에서 구글 캘린더 사용하기  (0) 2012.01.05



펌의 펌

http://blog.naver.com/bidum1

프로그래머의 정년은 35세.. 7-8년 되면 회사에서 기획이나 영업 마인드를 요구.. 결국 관리자의 길을 선택.. 이것이 이바닥에서 경력 7-8년 된 프로그래머를 찾을 수 없는 이유라는.. 무척 동감이 가는 글입니다. 퍼왔습니다: 

[출처: ZDNet-Korea] 최근 IT 업계에서는 소프트웨어 개발자 구하는 게 하늘의 별 따기 보다 어렵다고 한다. 그나마 데리고 있던 개발자 조차도 대기업으로 이직하거나 직종을 바꾼다고 난리다. 심지어는 대기업과 벤처기업간에 인력 빼가기로 인하여 법정 소송까지 벌어지고 있는 실정이다. 

그 많던 개발자들이 갑자기 어디로 가 버린 건가? 올 하반기에 기업들은 내년 경기 호조의 기대 속에 그 동안 지연시켜왔던 많은 개발 프로젝트들을 동시에 진행하게 되었고, 또한 통신사들을 중심으로 대규모 프로젝트들이 시작되어 많은 인력을 필요로 하였기 때문일 가능성이 크다. 그러다 보니 프리랜서들까지 총 동원되어 프로젝트에 투입되고 있지만 여전히 부족하기는 마찬가지다. 특히 7년 차 이상 되는 중급 개발자 구하기는 정말 힘들다. 심지어는 중급 프리랜서 개발자 한 명에게 서너 군데 업체들이 동시에 연락을 해 마치 가격 경쟁이 이루지는 듯한 웃지 못할 사례들까지 벌어지고 있는 실정이다. 

결국 개발의 의뢰한 업체에서도 사람이 없어서 계획했던 일들을 제대로 진행하지 못하는 상황이고, 개발을 책임지고 있는 SI 업체들도 사람이 없어서 고객에게 납기일을 맞추지 못하고 있다. 결국 고객과 중간 단계 책임자인 SI 업체는 최종 개발자 또는 개발 업체에게 계획했던 금액보다 더 높아진 인건비를 지급하고서야 프로젝트에 사람을 투입할 수 있게 되었다. 

예견된 불행
하지만 인력난에 대한 문제는 이제 시작에 불과하다. 한국 소프트웨어 컴포넌트 컨소시엄의 예측에 따르면 올해 필요한 소프트웨어 분석 및 설계 기술 인력의 수는 1만5천명이지만 실제로는 50%인 7500명 밖에 안 된다고 한다. 2008년에는 1만 명 이상이 부족할 것으로 예상된다. IT 강국인 대한민국이 앞으로는 개발자 인력 부족으로 인하여 후발 국가들한테 그 자리를 위협받게 될 상황까지 올지도 모른다. 그러나 이러한 수급 불균형에 대한 문제들은 이미 예견되었던 사항이라 더 안타깝다. 

이미 소프트웨어 개발자들 사이에서는 3D 직종이라는 인식이 만연해 있다. 필자가 2002년 기재했던 컬럼의 댓 글로 올라온 글 중에 이러한 상황을 잘 표현한 개발자의 한계에 대한 글을 인용해 본다. 

1. 프로그램 하는 일이 즐거워서 개발자가 됩니다.
2. 처음에는 평생 개발자가 되고자 합니다.
3. 선배가 개발자 정년 35살 이라고 합니다.
4. 무슨 소리냐고 경력이 쌓일수록 좋은(?) 개발자가 될 수 있다고 빡빡 우깁니다.
5. 2-3년 개발자가 무엇인지를 이해하기 시작합니다.
6. 4-5년 되면 개발자의 한계(수명?)을 인식하게 되며, 주변의 비슷한 나이의 기획자 등의 동료와 사회에서의 위치(?)를 비교합니다.
7. 정년을 조금 더 연장하려고 기술 개발에 치중합니다.
8. 7-8년 되면 회사에서 기획이나 영업 마인드를 가지기를 원합니다.
9. 위 과정을 거치다가 개발을 계속할지 관리자가 될지를 고민하고, 대부분은 관리자의 길을 선택합니다. (개발자의 미래가 불확실하니까)


현재 많은 기업들이 7년 이상 되는 중급 개발자를 찾지 못하는 이유가 여기에 있다. 중급 개발자를 구할 수만 있다면 동종 업계 최고 대우를 해주겠다고 못을 박기도 한다. 하지만 이미 많은 중급 개발자는 중소기업 전산실 관리직으로 자리를 옮겼거나 업종을 바꿔서 IT 업계를 떠난 지 오래다. 최근에는 업종을 떠나는 시점이 더 당겨지고 있다. 정부에서는 IT386 정책이니 하면서 IT 강국을 만들겠다고 큰소리 치지만 정작 핵심 인력이라고 할 수 있는 SW 개발자는 점점 줄어들고 있는 것이 현실이다. 

개발자에게 비전을
저임금, 열악한 환경, 불확실한 비전 등이 가장 큰 문제인데 그 중에서도 가장 먼저 현실화 되어야 할 부분이 임금 부분이다. 한-미-일 3국의 중급 SW 개발자 임금을 비교하면 한국은 203만원, 미국은 653만원, 일본은 599만원으로 나타났다. 각국의 물가 수준이나 환율을 감안하더라도 한국에서 소프트웨어 개발자가 받고 있는 처우는 열악하기만 수준이다.

이러한 문제를 해결하려면 정부와 대기업들의 그 동안 인건비 산정에 대한 관행을 없애는 것이 가장 중요하다고 생각한다. 최소한 과기처 단가만이라도 지켜진다면 해당 프로젝트를 수행하는 중소 개발 업체들이 저임금과 열악한 환경 등은 개선될 수 있을 것이다. IT에 많은 예산이 배정되어 있지 않고 투자할 여력도 없다고 주장할 것이다. 하지만 지금 비용을 절약하고 있다고 믿고 있겠지만 결국 개발자 부족으로 인하여 향후 1~2년 뒤에는 지금 비용의 2배를 지불하고도 제대로 프로젝트를 진행하지 못할 날이 올 수도 있다. 

개발자들이 제대로 된 처우를 받게 된다면 열악한 환경은 자기 개발이나 투자라고 믿고 참을 수 있을 것이다. 충분한 대우를 받고 있는 직종이라고 판단이 되면 많은 사람들이 개발자가 되기 위해서 업종을 선택하고 투자를 할 것이다. 결국 사회에서 IT 개발자라는 업종에 대한 인식이 높아지고 환경이 개선되어야만 앞으로라도 개발자를 양성할 수 있을 것이다. 우리나라가 자랑하는 IT 강국이 되기 위해서 많은 중고등 학생들이 개발자의 꿈을 가질 수 있도록 노력해야 할 것이다. 

 


Ajax가 신기하다는 것을 뒤늦게 깨닿고 공부중입니다.

그런데 웹사이트를 Refresh하지 않고 데이터를 가져오는게 장점인데. 과연 어떻게 하는 것일까? XML 통신인것 같긴 한데 한번 분석해보자.

우선 패킷 캡쳐를 하기 위해서 와이어샤크 (이전에 이더리얼) 을 사용해서 캡쳐시작.

그리고 예제로 만든 웹주소 실행

http://easystudy.cafe24.com/hp41/test_ajax/ajax_basic1.htm

 

function getServerTime() {
    var myurl = 'ajax_basic1_telltimeXML.php';
    myRand = parseInt(Math.random() * 999999999999999);
    var modurl = myurl + "?rand=" + myRand;
    http.open("GET", modurl, true);
    http.onreadystatechange = useHttpResponse;
    http.send(null);
}

function useHttpResponse() {
    if (http.readyState == 4) {
        if(http.status == 200) {
            var timeValue = http.responseXML.getElementsByTagName("timenow")[0];
            document.getElementById('showtime').innerHTML = timeValue.childNodes[0].nodeValue;
        }
    } else {
        document.getElementById('showtime').innerHTML = '<img src="ajax_basic1_loader.gif">';
    }
}
 
ajax_basic1_telltimeXML.php

<?PHP
header('Content-Type: text/xml');
sleep(1); //화면에 바로 보이기 때문에 약간 딜레이 시킴.
echo "<?xml version=\"1.0\"?><clock1><timenow>".date('H:i:s')."</timenow></clock1>";
?>

분석해보니 추가적으로 데이터를 가져오는 부분도 다른 프로토콜이 아닌 
그냥 HTTP 프로토콜로 해당 페이지를 가져옴 (ajax_basic1_telltimeXML.php) 
하지만 웹브라우저는 그 부분만 알아서 읽고 화면전체를 refresh하지는 않는다. 
image
 

image

 

 

GET /hp41/test_ajax/ajax_basic1_telltimeXML.php?rand=692866095308821 HTTP/1.1

Accept: */*

Accept-Language: ko

Referer: http://easystudy.cafe24.com/hp41/test_ajax/ajax_basic1.htm

Accept-Encoding: gzip, deflate

User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; IPMS/C8280A0A-14F34993EAE-000000464331; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; InfoPath.3; Tablet PC 2.0)

Host: easystudy.cafe24.com

Connection: Keep-Alive

Cookie: PHPSESSID=f42f176f81df41ca367267e856b133e6; __utmc=210374218; ADMINHOSTINGID=b0dVLzPlD9aOiju6Xg%3D%3D; __utma=210374218.1550145776.1328834340.1328834340.1328847559.2; __utmz=210374218.1328834340.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); cafe24SaveId_chkBox=Y; cafe24SaveId=easystudy

 

HTTP/1.1 200 OK

Server: apache

Date: Fri, 10 Feb 2012 05:33:52 GMT

Content-Type: text/xml

Transfer-Encoding: chunked

Connection: keep-alive

P3P: CP='NOI CURa ADMa DEVa TAIa OUR DELa BUS IND PHY ONL UNI COM NAV INT DEM PRE'

X-Powered-By: PHP/5.2.9p2

 

41

<?xml version="1.0"?><clock1><timenow>14:33:52</timenow></clock1>

0

 

GET /hp41/test_ajax/ajax_basic1_loader.gif HTTP/1.1

Accept: */*

Referer: http://easystudy.cafe24.com/hp41/test_ajax/ajax_basic1.htm

Accept-Language: ko-KR

User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; IPMS/C8280A0A-14F34993EAE-000000464331; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; InfoPath.3; Tablet PC 2.0)

Accept-Encoding: gzip, deflate

If-Modified-Since: Fri, 10 Feb 2012 05:17:55 GMT

If-None-Match: "26449b-c88-4f34a883"

Host: easystudy.cafe24.com

Connection: Keep-Alive

Cookie: PHPSESSID=f42f176f81df41ca367267e856b133e6; __utmc=210374218; ADMINHOSTINGID=b0dVLzPlD9aOiju6Xg%3D%3D; __utma=210374218.1550145776.1328834340.1328834340.1328847559.2; __utmz=210374218.1328834340.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); cafe24SaveId_chkBox=Y; cafe24SaveId=easystudy

 

var timeValue = http.responseXML.getElementsByTagName("timenow")[0];

여기가 실행되면서

<?xml version="1.0"?><clock1><timenow>14:33:52</timenow></clock1>

여기의 <timenow> 태그 안의 값을 읽어와서 timeValue 변수에 입력

 

여기서 다른 참고글을 읽으면 이해가 간다

http://cafe.naver.com/neloi.cafe?iframe_url=/ArticleRead.nhn%3Farticleid=172&

즉 데이터를 요청하는건 똑같이 HTTP 방식이 맞는데 클라이언트인 웹브라우저에서 자바스크립트의 getXMLHTTPRequest 를 이용하면 웹사이트 전체를 refresh하지 않고 내부적으로 데이터를 가져올 수 있고 그 가져온 데이터를 div 태그와 innerHTML 를 이용해서 받은 값을 화면에 표시를 해준다.



출처 : 전자신문

http://www.ciobiz.co.kr/news/articleView.html?idxno=7736

전자신문 CIO BIZ+가 연초 기업 및 기관 최고정보책임자(CIO) 105명을 대상으로 실시한 설문조사에 따르면 전체 응답자 80% 이상이 데스크톱 가상화(VDI) 또는 모바일 오피스 등 일명 ‘스마트워크’ IT 전략을 추진하겠다고 밝혔다. 설문에 응답한 50% 이상 CIO는 모바일 업무 도입 의사를 나타냈다.

B2C 시장 스마트폰 붐이 B2B 시장 스마트워크 붐으로 확산되는 모양새다. 공공·금융·제조·서비스 등 업종 불문 기업이 ‘스마트’와 전쟁을 치르고 있다. 수억원을 투자해 단순 정보 확인만 가능하게 한 모바일 오피스도 ‘스마트’란 이름 하나로 명분을 얻는 시대다.

목적 없는 스마트워크에 회의론이 고개를 들고 있는 배경이다.

◇무엇을 똑똑하게…‘스마트’ 정의부터 다시=“스마트워크를 하고 난 후 화장실에서 스마트폰 카메라로 회의에 참여한 적도 있어요.”

스트레스가 만만치 않다는 국내 대기업 K 부장에게 스마트폰은 족쇄와 같다. 이렇듯 시·공간을 초월해 일할 수 있는 최신 업무 환경을 상징하는 데 그치는 것이 스마트워크의 현주소다.

스마트워크=IT 구축’이란 사고 때문이다. 국내 대표 스마트워크 추진 기업들은 주로 △스마트폰 기반 모바일 오피스 △공간 효율을 위한 변동 좌석제 △자료 공유를 위한 데스크톱 가상화 & 문서 중앙관리 △스마트워크 센터 기반 자율 출퇴근제 등을 도입한다. 지난해 세 가지 이상 모델을 모두 도입한 KT와 포스코 등이 대표적이다. 모바일 오피스를 포함, 네 가지 중 한두 모델만 도입한 기업이 대부분이다.

모바일 플랫폼과 클라우드를 비롯해 다양한 방법론이 결합된 새로운 IT 도입으로 결국 24시간 365일 일할 수 있는 것이 스마트워크인 셈이다. 일하는 시간을 늘리면 생산성도 높아질까. 스마트워크에 문제를 제기하고 무분별한 스마트워크 도입에 메스를 대고자 하는 시도가 일부 기업과 컨설팅가에서 나타나고 있다.

액센츄어 해외지사에서 외국계 기업 컨설팅을 담당했던 김상익 전무는 “지난 2년간 한국 기업이 도입한 스마트워크는 ‘하드웨어’에 집중해 사무실 공간 배치와 모바일 장비, 데스크톱PC 등 외양만 바꾼 것에 불과하다”고 지적했다. 기업마다 ‘스마트’ 정의도 다른데다 기업 내 담당자끼리도 다른 의미를 내세우는 경우가 많다는 것이다.

변동좌석제 도입 이후 여전히 같은 자리에 앉아서 일을 한다는 한 대기업 관계자는 “어차피 팀원들끼리 모여 앉아야 하다 보니 결국 ‘비공식’ 지정석이 생겼다”면서 “부장급 등은 창가 쪽에 위치한 자기 자리에 앉으면 은근히 눈치를 준다”고 말했다.

자리를 지정하는 시스템조차 무용지물이 돼 스마트워크 IT 투자 효과가 마이너스로 돌아선 셈이다. 사장과도 자유로운 토론이 가능할 만큼 문화 조성이 뒷받침되지 않으면 변동좌석제에 다른 자유로운 자리 배치가 무의미해진다.

◇유한킴벌리·KT 등 ‘성과 중심’으로 평가 바꿔=기술 중심 스마트워크 폐해를 줄이려면 일하는 시간보다 ‘성과’를 먼저 보는 정책·문화적 뒷받침이 필요하다.

올해부터 재택근무를 실시하는 유한킴벌리는 지난해 말 전사적으로 변동좌석제 기반 스마트워크를 도입하면서 인사 평가 기준 자체를 바꿨다.

유한킴벌리 관계자는 “모든 업무를 근무시간 체크 개념에서 ‘자율관리’ 체계로 바꿨다”며 “개인이 목표 달성 여부와 성과 측정을 중심으로 제도가 변경됐다”고 말했다. 인사 체계를 바꾸기 위해 스마트워크 설계 단계에서부터 인사팀이 가담했다.

개인이 명확한 목표를 수립하는 단계부터 객관화된 목표를 달성하는 과정, 이에 따른 결과물 도출이 가시화되도록 했다. 이 관계자는 “비록 일하는 시간이 줄더라도 목표를 달성하고 좋은 성과를 냈다면 좋은 평가를 받을 수 있다”고 강조했다. ‘일과 삶의 균형을 통한 가족친화’를 목표로 하고 있는 유한킴벌리 스마트워크는 개인의 업무 시간을 줄이면서도 성과 중심적으로 일할 수 있도록 유도하고 있는 것이다.

KT는 지난해 변동좌석제와 모바일 오피스 등 스마트워크를 확산하면서 업무 자체를 과제화한 후 개인별 해당 과제를 관리하고 평가하도록 전 임직원 평가 체계를 변경했다.

KT 관계자는 “개인이 추진해야 할 과제를 시스템에 등록하고 기한을 정한 후 과제가 끝나 시스템에 올리면 관리자가 이를 평가할 수 있도록 했다”고 설명했다. 실제로 이 부서 업무 70% 이상이 이미 과제를 등록하는 시스템으로 이뤄진다. 이 관계자는 “직원이 놀든 일하든 관계없이 부여된 과제를 평가받고 책임지는 문화로 바뀌었다”고 말했다.

◇‘눈도장’ 공공기관이 가장 문제=공공기관은 민간기업 대비 스마트워크 활성화가 더욱 느리다. ‘얼굴도장’에 의존하는 상사 문화 등이 팽배해 있어서다. 스마트워크 센터 사용이 활발하지 않아 순번제로 돌리는 경우도 나타난다. 올해 행안부 스마트워크센터 설립 규모가 지난해 계획보다 축소된 것도 이와 무관하지 않다.

한 공공기관 CIO는 “공공기관은 스마트워크가 ‘생산성’을 위한 것인지 ‘복지’를 위한 것인지를 판단해야 할 것”이라며 “생산성을 위해선 오히려 20~30분 더 걸려도 업무지로 출근하는 것이 더 나을 수 있으나 복지가 필요한 여직원들이나 건강상 필요한 직원들은 주변 스마트워크 센터로 출근할 수 있도록 해야 한다”고 말했다.

센터 설립 자체보다 활용 문화 개선이 시급하다는 평가가 나오는 이유다.

공공기관 모바일 오피스 공급업체 관계자는 “스마트워크에서 가장 중요한 것이 인사제도”라며 “비인간적인 면이 있더라도 철저히 성과로 평가하는 제도와 마인드가 갖춰져야 한다”고 조언했다.

유효정기자 hjyou@etnews.com

[표]스마트워크 도입 시 주요 도입 기술과 정책·문화적 보완 사항

기술적 측면
주요 정책·문화적 보완 사항

스마트폰 기반 모바일 오피스
- 기업별 스마트 워크 목표에 부합하는 스마트폰 업무 범위 선정
“일하는 시간과 절대량 대신 ‘성과’ 중심 업무 및 인사 평가체계 필요”

데스크톱 가상화 or 서버기반 컴퓨팅
- 정보의 분류와 공유, 활용을 위한 정책적 체계 선 마련

변동 좌석제
- 직급에 따른 상하 관계 대신 수평적 소통 문화 확산



http://www.ciobiz.co.kr/news/articleView.html?idxno=7711

 

#퇴사를 일주일 앞둔 K 부장은 외부에서 가상사설망(VPN)으로 문서에 접근해 최근 기획한 과제들에 대한 자료를 메일로 보내놓고 관련 기술 문서들을 일주일 동안 두 번 USB에 담았다.

#메신저로 동료와 이직 문제를 상의하던 H 과장은 문서관리시스템에서 접속해 본인이 등록되지 않은 타 부서 파일의 암호를 해제하고 문서를 프린트하는 일이 평소의 세 배로 잦아졌다.

기술 유출을 시도하는 직원들의 특정 행위들을 시나리오로 그려놓고 '잠재적 범죄자'를 선별해 내는 시스템 구축이 활기를 띠고 있다. 메신저-USB-프린터-메일 등 다수 시스템을 동시에 분석해 '블랙 리스트'를 집중 관리하는 것이 가장 큰 목표다.

24일 업계에 따르면 삼성전자, LG전자, 현대자동차, LG화학, GS칼텍스, GS건설 등이 최근 이같은 IT 통합관제 및 분석 시스템을 신규 혹은 재구축하고 가동에 돌입했다. 현대카드·현대캐피탈 등은 보안사고 발생 이후 시스템을 구축했으며 넥슨·삼성카드 등도 관련 시스템 도입을 검토하고 있다.

보안강화를 목표로 하는 이 기업의 통합 관제 시스템은 임직원이 여러 시스템에 접속하는 행위를 수집하고 특정 '패턴'과 일치하면 해당 직원을 자동추출 및 집중관리하는 기능을 제공한다. 전문 SW 도입으로 수작업 분석 업무를 시스템화해 실시간 대응력을 높였다.

퇴직 예정자 및 개인정보 취급 임직원, 핵심 기술 보유 직원 등이 주요 대상으로 사내 메신저부터 이메일, USB 저장장치, 프린터·복합기, 전자문서관리시스템(EDMS) 등 적게는 10개에서 많게는 20개 이상의 업무용 시스템의 로그 정보를 동시에 연계 분석한다.

디지털저작권관리(DRM) 시스템 등은 단일 채널에 대한 보안을 관리하지만 기술 유출 시도자들은 다양한 시스템에 걸쳐 이상 행위가 포착된다는 점에 착안한 것이다. 기업 당 보안 정책에 맞춰 200~500개의 보안 유출 시나리오를 보유, 패턴 유형도 급속히 진화하고 있다.

삼성전자는 핵심 시스템의 로그 정보를 빠르게 수집·분석할 수 있는 툴과 일부 시스템의 통합 관제를 위한 로그 수집 SW 등을 도입, 업그레이드 중이다. LG전자는 로그분석 및 시나리오 기반 통합관제 전문 SW를 도입해 본사 전 사업장에 시스템을 지난해 구축한 데 이어 올해 해외 사업장에 확산한다. 현대자동차와 LG화학도 올 상반기에 통합 관제 시스템 구축과 고도화를 각각 완료하고 적용을 시작한다.

임직원 수가 많은 대기업들은 로그 정보 데이터량만 해도 하루에 50~100GB에서 수 테라바이트(TB)에 달해 '빅데이터'를 위한 실시간 상관 분석도 핵심 관건으로 부상하고 있다. LG전자, 현대차 등은 시나리오별 보안 유출 가능성 자동 판단 기능이 탑재된 통합관제 SW를 도입해 데이터량을 줄이면서 대응력을 높인 경우다.

통합관제 업계 관계자는 “최근 개인정보보호법 등 대응을 위해 시스템을 개선하는 사례도 늘어나고 있다”면서 “금융뿐 아니라 대학가에서도 관심이 높아지고 있어 올해 시장이 작년 대비 약 30% 성장할 것으로 전망한다”고 말했다.

유효정기자 hjyou@etnews.com





출처 :http://www.dbguide.net/knowledge.db?cmd=view&boardUid=127563&boardConfigUid=20&boardStep=&categoryUid=574

실시간 운영체제로의 영역 확장
PHP

많은 오픈소스 프로젝트와 마찬가지로 웹 프로그래밍 언어로 시작한 PHP 역시 실시간 운영체제로 확장되는 등 점차 영역을 넓혀 나가고 있다. 이 글에서는 플랫폼을 뛰어 넘어 다양하게 활용되고 있는 PHP의 현재 모습을 살펴보고 앞으로 어떻게 나아갈지를 예상해 본다.

용영환 xenonix@gmail.com

1995년 태어난 PHP는 2000년에 PHP 4에 와서 전성기를 맞이하게 된다. 웹 프로그램 개발에 최적화되어 있는 PHP는 쉬운 문법과 다양하면서 강력한 기능, 그리고 우수한 성능으로 현재까지도 전 세계적으로 가장 많은 웹서버에서 사용되고 있는 인기 프로그래밍 언어이다.
하지만 PHP는 웹 프로그래밍 언어라는 인식으로 인해 자바, Python 등에 비해 다양한 분야에 활용되지 못하고, 단지 웹에만 주로 국한되어 쓰이는 게 오늘의 현실이다.

PHP의 현주소

PHP는 2002년에 공개한 버전 4.3.0에서 CLI(Command Line Interface)를 지원하게 됨으로써 웹서버 없이 리눅스의 쉘이나 윈도우의 Cmd 상에서 PHP 프로그램을 구동할 수 있게 됐다. 다시 말해 PHP가 웹서버를 벗어나 독립적인 응용프로그램을 만들 수 있게 된 것이다.

<그림1> PHP의 활용 분야

웹 프로그램

PHP는 웹2.0이라 불리는 지금의 웹 환경이 만들어지는 데 큰 영향을 미쳤다. 동적인 웹사이트를 구현하기 위해 사용되던 CGI를 PHP가 대체했고, 그로 인해 웹 사이트 개발에 드는 비용이 크게 줄었다. 특히 PHP는 무료이면서 오픈소스라는 특징 때문에 누구나 접할 수 있었고, 사용자들이 직접 또는 간접적으로 PHP 발전에 공헌함으로써 다른 웹 프로그래밍 언어에 비해 빠르게 성장할 수 있었다.

이처럼 PHP는 그 태생 목적이 웹이다 보니 웹서비스에서 만큼은 매우 우수한 성능을 보여준다. 하지만 대규모의 웹서비스를 위한 기반 기술이 부족하다 보니 금융과 같은 대규모의 트랜잭션이 필요한 웹서비스에서는 자바에 자리를 내주어야만 했다.

<화면1> PHP로 개발된 PHP.net 웹사이트

GUI 프로그램

PHP-GTK( http://gtk.php.net)는 GTK+라는 GUI (Graphic User Interface) 라이브러리를 사용해 PHP로 GUI 프로그램을 개발할 수 있게 하는 PHP 확장 모듈이다.

GTK+(http://www.gtk.org/)는 윈도우, 리눅스, MacOS 등의 다양한 운영체제에서 구동되므로 PHP-GTK 기반으로 개발된 PHP 프로그램은 운영체제에 상관없이 동일한 화면으로 구동할 수 있다. 비슷한 프로젝트로는 Python을 위한 PyGTK가 있다. <화면 2>는 PHP-GTK2로 개발된 프로그램을 실행한 모습이다.

<화면2> PHP-GTK2 데모 프로그램

아쉬운 점은 PHP-GTK 프로그램을 쉽게 개발할 수 있는 Visual IDE가 없는 탓에 개발 과정이 그다지 쉽지는 않다는 사실이다. 그럼에도 불구하고 PHP 코드를 이용해 GUI 프로그램을 개발할 수 있다는 것이 큰 특징이다. 더 자세한 내용은 다음의 링크를 참고하길 바란다.

- 위키백과 PHP-GTK : http://en.wikipedia.org/wiki/PHP-GTK
- PHP-GTK 커뮤니티 & 소스 코드 제공 : http://en.wikipedia.org/ wiki/PHP-GTK
- WinBinder : http://winbinder.org/

시스템 관리 스크립트

원활한 시스템 관리를 위해 쉘 스크립트나 Perl 등을 써서 자동화 스크립트를 작성한 후에 사용하게 되는데 여기에서도 PHP는 강점을 보이고 있다. 우선 PHP가 CLI를 지원함으로써 콘솔에서 바로 실행할 수 있게 된 데다, 익숙한 PHP 문법과 방대한 라이브러리를 사용해 원하는 프로그램을 빠르게 만들 수 있기 때문이다. Perl이나 Python의 장점은 방대한 라이브러리를 갖고 있다는 것. PHP 역시 오픈소스 프로젝트이다 보니 PEAR나 PECL, 그리고 인터넷을 통해 손쉽게 필요한 라이브러리를 구해 사용할 수 있으므로 원하는 기능을 구현하는 데에는 불편함이 없다. <그림 2>에서 보는 바와 같이 sh나 Perl 등과 마찬가지로 PHP를 CLI 상에서 스크립트 언어로 사용할 수 있다.

<그림2> CLI 상에서 스크립트 언어로 사용 가능

현재는 CentOS와 MacOS 등의 일부 운영체제에서만 CLI용 PHP가 기본으로 설치되고 있지만, 앞으로 PHP를 기본 탑재하는 운영체제가 늘어날 것으로 기대한다.

서버 프로그램

PHP로 서버 프로그램을 개발할 수 있다는 것이 다소 생소하게 들릴지도 모른다. PHP는 프로세스 관련 함수와 네트워크 관련 함수 등을 이용해 독립실행형(Standalone)으로 동작하는 서버 프로그램을 개발하는 데에도 사용되고 있다. 따라서 PHP를 서버 프로그램을 개발하는 데 사용한다면 플랫폼에 상관없이 PHP 인터프리터만 설치하는 것으로 충분하다. 이와 관련된 더 자세한 내용은 다음의 웹페이지를 참고하길 바란다.

- 웹 서버 : http://nanoweb.si.kz/
- FTP 서버 : http://nanoftpd.sourceforge.net/
- IRC 봇 : http://phpbots.org/

PHP 속의 자바와 COM

과거에 필자는 ‘Power Basic’이라는 프로그래밍 언어를 공부했다. 이는 사용자가 극히 드문 비주류의 언어였음에도 불구하고, 함께 공부하던 이들의 내공은 매우 높았다. 당시 한글 라이브러리가 없었던 터라 모임의 어느 한 개발자가 직접 어셈블리로 그것을 만들었고, 이를 계기로 그래픽 라이브러리, 통신 라이브러리 등 필요한 라이브러리를 모두 C 언어로 만들어 사용하게 되었다.

Power Basic에서 제공하지 않는 라이브러리를 만들어 사용할 수 있었던 것은 다른 언어를 호출해 사?처럼 제공하지 않거나 구현이 불가능한 요소를 다른 언어의 힘을 빌려 해결할 수 있는 것은 언어적 한계를 뛰어넘어 확장성을 극대화할 수 있게 한다.

<그림3> 자바와 COM으로 구현된 컴포넌트 객체의 사용

앞서 말한 Power Basic과 마찬가지로 PHP에서도 자바나 COM으로 구현된 컴포넌트 객체를 그대로 사용할 수 있다. <그림 3>은 그런 관계를 잘 보여준다.

RIA 플랫폼을 위한 PHP

어도비(Adobe)사는 Flex SDK를 공개하면서 http://www. adobe.com/devnet/flex/flex_php.html 페이지를 통해 PHP를 지원하고 있다.
또한 볼랜드사는 최근에 RAD 개발 툴인 Delphi for PHP 2.0을 공개했다. Delphi for PHP 는 Delphi for Win32처럼 드래그 앤 드롭(Drag & Drop) 방식으로 웹사이트를 개발할 수 있는 PHP 통합개발환경이다. 지난해 1.0을 발표하면서 차세대 PHP IDE로 관심을 모았는데 이번에 발표한 Delphi for PHP 2.0에서는 Ajax 기술과 다양한 컴포넌트를 추가함으로써 더 빠르게 최신 웹 기술을 구현할 수 있도록 했다. Delphi for PHP 2.0에 대한 더 자세한 설명은 다음의 링크를 참고하자.

- Delphi for PHP 2.0 Overview : http://www.codegear.com/ products/delphi/php

PHP 바이너리 컴파일러

앞서 살펴본 내용 가운데 PHP-GTK와 서버 프로그램 등은 독립실행형 프로그램이다. 이런 독립실행형 프로그램을 위해 PHP 컴파일러가 존재한다. PHP 컴파일러를 사용하면 윈도우인 경우에 exe 파일과 같은 바이너리 형태의 실행 파일로 만들 수 있다. 실행 파일 안에 PHP 인터프리터를 포함해서 바이너리 형태로 만들기 때문에 용량이 다소 클 수는 있으나 제작한 PHP 프로그램을 배포하거나 간편하게 실행하기 위해서는 괜찮은 방법이다. <화면 3>은 Bambalam PHP Compiler와 WinBinder로 만든 윈도우용 계산기의 예이다.

<화면3> PHP 계산기

다음의 링크에서 컴파일러와 관련된 더 자세한 내용을 확인할 수 있다.

- Bambalam PHP Compiler : http://www.bambalam.se/ bamcompile/
- PHP .Net Compiler : http://www.php-compiler.net/doku.php

PHP 컨버전스

지금까지 오늘에 이르는 PHP의 변화 과정을 살펴봤다. 앞서 설명한 바와 같이 PHP는 꾸준히 발전하면서 자신의 활용 분야를 넓혀온 것으로 이해할 수 있다. 하지만 다양한 형태의 프로그램을 개발할 수 있음에도 불구하고, 웹 프로그래밍을 제외한 분야에서는 활용이 저조한 실정이다.

가능성의 구현

PHP로 멀티미디어 파일 재생기나 텍스트 에디터, 이미지 뷰어, 게임 등을 개발할 수 있으면 얼마나 좋을까. 실제로 PHP-GTK와 COM 컴포넌트 객체를 사용해 간단한 MP3 플레이어를 구현한 경우도 있고 무선 랜 검사기, 바이러스 백신을 만든 경우도 있다. 그 실제적인 모습은 다음의 링크에서 확인할 수 있다.

- 호박도령님의 간단한 MP3 재생기 : http://blog.naver.com/cyberuls /110021582426
- 윈도우용 무선 랜 검사기 : http://sourceforge.net/projects/ vistawlanlister/
- PHP 바이러스 백신 : http://sourceforge.net/projects/phpantivirus/

PHP 6에 대한 기대

PHP는 우리가 생각했던 것보다 훨씬 강력한 언어이다. 오픈소스의 장점을 통해 계속 발전하고 있으며 그만큼 우리가 PHP를 통해 할 수 있는 일도 늘어나고 있다. 현재 개발 중인 PHP 6에서는 언어적 측면에서 많은 발전이 이뤄질 것으로 예상된다. 또한 PHP 확장 라이브러리들도 함께 발전하면서 PHP로 개발된 다양한 프로그램들이 나타나 줄 것이라 기대된다.

어떤 프로그래밍 언어를 공부할지를 고민하는 이가 있다면 필자는 PHP를 추천하고 싶다. 그리고 현재 PHP를 공부하고 있다면 이 글에서 살펴본 PHP의 가능성을 모두 실험해 보길 바란다. 그러면 PHP 하나로 어떤 프로그램이든 만들어 낼 수 있지 않을까 싶다.

제공 : DB포탈사이트 DBguide.net



http://www.dbguide.net/knowledge.db?cmd=view&boardUid=127741&boardConfigUid=20&boardStep=&categoryUid=209

 

PHP 프로그램에서 구글 캘린더 사용하기

PHP 응용 프로그램에서 구글 캘린더 정보를 가져와 통합하자

구글 캘린더는 웹 응용 프로그램 개발자에게 사용자가 입력한 내용과 이벤트 정보를 REST 기반 개발자 API로 가져오는 방법을 제공합니다. PHP의 SimpleXML 확장 기능과 젠드(Zend) 프레임워크의 GData 라이브러리는 구글 캘린더 API가 생성한 XML 피드를 처리해 PHP 응용 프로그램을 만들기에 이상적인 기술입니다. 이 기사에서는 1) 구글 캘린더 데이터 API를 소개하고, 2) 사용자가 만든 캘린더를 살펴보고, 3) 캘린더 이벤트를 추가/갱신하고, 4) 키워드로 캘린더를 검색해 봅니다.

소개

오랫 동안 내가 정기적으로 사용한 유일한 일정 관리 도구는 팜파일럿에 딸려나온 일정 관리 소프트웨어였다. 하지만 지난 몇 년에 걸쳐 나는 점차 구글 캘린더 애용자가 되었다. 웹-웨어(Web-ware)라는 사실 외에도 이벤트 소식을 공유하고, 초청장과 응답을 관리하고, 다양한 이벤트 유형을 처리하기가 편리한 덕분이다.

자주 쓰이는 약어 소개

API: Application Programming Interface
HTTP: Hypertext Transfer Protocol
PHP: PHP: Hypertext Preprocessor
REST: Representational state transfer
RSS: Really Simple Syndication
URL: Uniform Resource Locator
XML: Extensible Markup Language

개발자 입장에서도 구글 캘린더는 흥미를 자극한다. 구글 캘린더 데이터 API를 사용하면 공개 캘린더나 개인 캘린더에 있는 정보를 바탕으로 새로운 응용 프로그램을 제작하기가 아주 쉽다. 구글 캘린더 API는 REST 모델을 따르며, XML을 인식하는 개발 도구라면 어디서나 사용할 수 있다. 게다가 이미 많은 프로그래밍 언어에서 (내가 가장 좋아하는 PHP에서도) 클라이언트 라이브러리를 제공한다.

이 기사에서는 구글 캘린더 데이터 API를 소개하고, PHP 프로그램에서 캘린더 정보를 통합하고 사용하는 방법을 살펴본다. 구체적으로는 다음과 같은 내용을 다룬다.

  • 사용자 공개 노트북에서 이벤트를 가져오는 방법
  • 새 이벤트를 추가하는 방법
  • 기존 이벤트를 수정하고 삭제하는 방법
  • 키워드나 날짜 범위로 이벤트를 검색하는 방법

자, 이제 시작해 보자!!

구글 캘린더 데이터 API 이해하기

PHP 코드로 뛰어들기 전에 구글 캘린더 데이터 API부터 이해하자. 여느 REST 기반 서비스와 마찬가지로, 구글 캘린더 데이터 API 역시 (XML 형식으로 인수가 지정된) HTTP 요청을 받아 XML 형식으로 만들어진 응답을 반환한다. 클라이언트에서는 이 XML 응답을 분석한다. 구글 캘린더 데이터 API는 항상 요청한 정보를 포함한 Atom 피드나 RSS 피드로 응답을 보낸다.

구글 캘린더 API가 반환하는 피드는 흔히 (일반적인 응용 프로그램 입장에서 필요 이상으로) 상당히 많은 정보를 포함한다. 예를 들어, 구글 캘린더 계정으로 로그인한 후 캘린더 설정에서 비공개 주소를 찾는다. 이 주소는 다른 사람과 공유해서는 안 되며, 권한을 먼저 요청하지 않은 상태에서는 캘린더 피드에 읽기 전용 접근만 허용하며, http://www.google.com/calendar/feeds/userid/private-magicCookie/basic 형태다. 브라우저 주소란에 자신의 비공개 주소를 입력해보자(아니면 HTTP 클라이언트를 통해 피드를 GET 요청으로 보낸다). 그러면 Listing 1과 같은 피드가 표시된다.

Listing 1: 구글 캘린더 피드 예

<?xml version='1.0' encoding='UTF-8'?> http://www.google.com/calendar/feeds/user@gmail.com/ private-cookie/basic 2008-06-13T19:15:18.000Z Joe User Joe User Joe User user@gmail.com Google Calendar 4 1 25 http://www.google.com/calendar/feeds/user@gmail.com/ private-cookie/basic/xxxxxxxx 2008-06-12T08:49:38.000Z 2008-06-13T19:06:21.000Z Swim party When: Sat Jun 21, 2008 12pm to 3:30pm  IST
Event Status: confirmed When: Sat Jun 21, 2008 12pm to 3:30pm IST
Event Status: confirmed Dinner with the gang When: Wed Jun 11, 2008 7pm to 9:30pm  IST
Event Status: confirmed When: Wed Jun 11, 2008 7pm to 9:30pm IST
Event Status: confirmed Joe User user@gmail.com ...

모든 캘린더 피드는 <feed> 엘리먼트가 루트다. <feed> 엘리먼트는 여러 <link> 엘리먼트와 여러 <openSearch:> 엘리먼트를 포함한다. <link> 엘리먼트는 피드의 다른 버전 URL을 포함하며, <openSearch:> 엘리먼트는 요약 통계를 포함한다.

가장 바깥에 있는 <feed> 엘리먼트는 <entry> 엘리먼트를 한 개 이상 포함하며, 각 <entry> 엘리먼트는 좀 더 세부적인 캘린더 이벤트 정보를 포함한다. 이벤트 정보로는 제목, 설명, 작성일, 최종 수정일, 이벤트 피드 URL, 이벤트 작성자가 있다. 각각은 <title>, <summary>, <published>, <updated>, <link>, <author> 엘리먼트에 들어 있다.

SimpleXML로 이벤트 목록 가져오기

다음은 PHP를 사용하여 구글 캘린더 피드를 처리하는 예제다. Listing 2는 Listing 1 피드를 받아 SimpleXML로 필요한 정보를 추출한 후 형식에 맞춰 웹 페이지에 표시한다.

Listing 2: SimpleXML로 이벤트 목록 가져오기

<?php $userid = 'username%40googlemail.com'; $magicCookie = 'cookie'; // 피드 URL 생성 $feedURL = "http://www.google.com/calendar/feeds/$userid/private-$magicCookie/basic"; // 피드를 SimpleXML 객체로 읽음 $sxml = simplexml_load_file($feedURL); // 이벤트 개수 얻기 $counts = $sxml->children('http://a9.com/-/spec/opensearchrss/1.0/'); $total = $counts->totalResults; ?>

<?php echo $sxml->title; ?>

<?php echo $total; ?> event(s) found.
    <?php // 범주에 속한 항목 순회 // 각 항목 세부 내역 출력 foreach ($sxml->entry as $entry) { $title = stripslashes($entry->title); $summary = stripslashes($entry->summary); echo "
  1. \n"; echo "

    $title

    \n"; echo "$summary
    \n"; echo "
  2. \n"; } ?>

그림 1은 Listing 2로 얻은 결과다.

그림 1. SimpleXML로 가져온 캘린더 이벤트 목록

Listing 2 코드를 살펴보면, simplexml_load_file() 함수는 피드 URL로 요청을 보낸 후 결과를 SimpleXML 객체로 변환한다. 그런 다음, foreach() 루프를 돌면서 <entry>를 하나씩 찾은 후 그림 1과 같은 정보를 추출한다. <entry> 엘리먼트 아래 있는 노드는 SimpleXML 객체 속성으로 참조한다. 예를 들어, <title> 노드는 $entry->title로, <summary> 노드는 $entry->summary로 참조한다.

여기서 사용한 피드 URL은 사용자의 비공개 캘린더 피드를 참조한다. 사용자의 비공개 캘린더 피드는 사용자 전자편지 주소와 매직 쿠키(magic cookie)라는 문자열을 포함하는데, 인증 과정을 거치지 않고 캘린더 자료를 읽기 전용으로 가져오는 경우에 비공개 주소를 사용한다. 앞서 언급했듯이, 이 피드 URL을 얻으려면 사용자의 구글 캘린더 페이지로 로그인한 후 캘린더 설정에서 URL을 직접 복사해 PHP 스크립트에 추가해야 한다.

젠드 GData 클라이언트 라이브러리로 이벤트 목록 가져오기

매직 쿠키가 확실히 사용하기 편하지만, 일반 PHP 프로그램에서는 다음 두 가지 측면에서 실용적이지 못하다.

  • 캘린더 정보에 읽기 전용 접근만 가능하다.
  • (읽기 외에) 다른 캘린더 작업에는 사용하지 못한다.

캘린더 데이터 API로 (이벤트 수정, 삭제, 추가, 검색 등) 다양한 작업을 수행하려면 사용자 인증이 필요하다. 구글이 인정하는 인증 방법은 AuthSub과 ClientLogin 두 가지다.

사용자 인증 단계를 일일이 구현하기란 매우 번거롭다. 아주 전형적인 인증 단계라도 온갖 시나리오를 처리하려면 상당한 코드가 필요하다. 다행스럽게도 젠드 GData 클라이언트 라이브러리를 사용하면 개발자가 세세한 부분까지 신경쓸 필요가 없다. 젠드 GData 클라이언트 라이브러리는 PHP 응용 프로그램과 구글 데이터 API를 통합하는 과정에서 필요한 세부 사항을 모두 처리한다(라이브러리를 내려받는 링크는 참고자료에서 소개한다). 이 라이브러리는 구글 데이터 API와 연결하는 편리한 객체 지향 인터페이스를 제공하며, 사용자 인증 등 일반적인 작업을 거의 대부분 처리한다. 그러므로 개발자는 구글 데이터 API와 통신하는 방법을 신경쓸 필요 없이 응용 프로그램 자체에 집중할 수 있다.

Listing 3은 젠드 GData 클라이언트 라이브러리를 사용하여 Listing 2와 똑같은 기능을 구현한 코드다.

Listing 3: 젠드 라이브러리로 이벤트 리스트 가져오기

<?php // load library require_once 'Zend/Loader.php'; Zend_Loader::loadClass('Zend_Gdata'); Zend_Loader::loadClass('Zend_Gdata_ClientLogin'); Zend_Loader::loadClass('Zend_Gdata_Calendar'); Zend_Loader::loadClass('Zend_Http_Client'); // 캘린더 서비스를 위해 인증된 HTTP 클라이언트 생성 $gcal = Zend_Gdata_Calendar::AUTH_SERVICE_NAME; $user = "username@gmail.com"; $pass = "pass"; $client = Zend_Gdata_ClientLogin::getHttpClient($user, $pass, $gcal); $gcal = new Zend_Gdata_Calendar($client); // 이벤트 목록을 얻기 위해 질의 생성 $query = $gcal->newEventQuery(); $query->setUser('default'); $query->setVisibility('private'); $query->setProjection('basic'); // 캘린더 피드 획득과 해석 // 결과 출력 try { $feed = $gcal->getCalendarEventFeed($query); } catch (Zend_Gdata_App_Exception $e) { echo "Error: " . $e->getResponse(); } ?>

<?php echo $feed->title; ?>

<?php echo $feed->totalResults; ?> event(s) found.
    <?php foreach ($feed as $event) { echo "
  1. \n"; echo "

    " . stripslashes($event->title) . "

    \n"; echo stripslashes($event->summary) . "
    \n"; echo "
  2. \n"; } echo ""; ?>

Listing 3은 가장 먼저 젠드 클래스 라이브러리를 로드한다. 그런 다음, Zend_Http_Client 클래스 인스턴스를 초기화한다. 이 클래스에 필요한 사용자 인증 정보를 제공한 후 캘린더 서비스에 인증된 채널로 연결한다. 인증 채널로 캘린더 서비스에 연결한 후에는 getCalendarEventFeed() 메서드로 캘린더 피드를 가져온다. 이 메서드는 EventQuery 객체를 받는데, 이 객체에 사용자 이름, 피드 유형(public 또는 private), 정보 상세 수준(full 또는 basic) 등 필요한 매개변수를 지정한다. getCalendarEventFeed() 메서드는 XML 문서를 반환하며, PHP 객체로 변환하는 작업을 거친다. 마지막으로 변환된 PHP 객체 속성에서 필요한 정보를 추출하여 HTML 페이지에 표시한다.

그림 2는 Listing 3으로 얻은 결과다.

그림 2. 젠드 GData 클라이언트 라이브러리로 가져온 캘린더 이벤트 목록

새 이벤트 추가하기

지금까지 클라이언트 프로그램에서 이벤트 목록만 가져왔다. 그렇다면 새로운 이벤트는 어떻게 추가할까?

생각보다 어렵지 않다. 구글 캘린더 데이터 API를 사용하면 간단하다. 먼저, XML 형식으로 이벤트 <entry> 엘리먼트를 생성한 후 캘린더 피드에 POST 메서드로 전송하면 그만이다. Listing 4는 새 이벤트를 나타내는 XML 예제다.

Listing 4: 새 이벤트를 나타내는 예제 XML

Dinner with the gang

젠드 라이브러리를 사용하면 더욱 간단하다. insertEvent() 메서드만 호출하면 그만이다. insertEvent() 메서드가 Listing 4와 같은 XML을 생성하여 캘린더 피드로 전송한다. Listing 5는 이벤트 관련 정보를 사용자에게 받아 캘린더에 해당 이벤트를 추가하는 코드다. 아래서는 젠드 라이브러리를 사용하여 XML을 생성한다.

Listing 5: 웹 폼을 통해 새 이벤트 추가하기

Add Event

<?php if (!isset($_POST['submit'])) { ?> Event title:

Start date (dd/mm/yyyy):

Start time (hh:mm):
End date (dd/mm/yyyy):

End time (hh:mm):
<?php } else { // 클래스 로드 require_once 'Zend/Loader.php'; Zend_Loader::loadClass('Zend_Gdata'); Zend_Loader::loadClass('Zend_Gdata_ClientLogin'); Zend_Loader::loadClass('Zend_Gdata_Calendar'); Zend_Loader::loadClass('Zend_Http_Client'); // 서비스에 접속 $gcal = Zend_Gdata_Calendar::AUTH_SERVICE_NAME; $user = "username@gmail.com"; $pass = "pass"; $client = Zend_Gdata_ClientLogin::getHttpClient($user, $pass, $gcal); $gcal = new Zend_Gdata_Calendar($client); // 입력 유효성 검사 if (empty($_POST['title'])) { die('ERROR: Missing title'); } if (!checkdate($_POST['sdate_mm'], $_POST['sdate_dd'], $_POST['sdate_yy'])) { die('ERROR: Invalid start date/time'); } if (!checkdate($_POST['edate_mm'], $_POST['edate_dd'], $_POST['edate_yy'])) { die('ERROR: Invalid end date/time'); } $title = htmlentities($_POST['title']); $start = date(DATE_ATOM, mktime($_POST['sdate_hh'], $_POST['sdate_ii'], 0, $_POST['sdate_mm'], $_POST['sdate_dd'], $_POST['sdate_yy'])); $end = date(DATE_ATOM, mktime($_POST['edate_hh'], $_POST['edate_ii'], 0, $_POST['edate_mm'], $_POST['edate_dd'], $_POST['edate_yy'])); // 이벤트 객체 생성 // 서버에 저장 try { $event = $gcal->newEventEntry(); $event->title = $gcal->newTitle($title); $when = $gcal->newWhen(); $when->startTime = $start; $when->endTime = $end; $event->when = array($when); $gcal->insertEvent($event); } catch (Zend_Gdata_App_Exception $e) { echo "Error: " . $e->getResponse(); } echo 'Event successfully added!'; } ?>

Listing 5는 크게 두 부분으로 나뉜다. 하나는 웹 폼이고, 다른 하나는 사용자가 웹 폼에 입력한 정보를 처리하는 PHP 코드다. 그림 3은 웹 폼을 보여준다.

그림 3. 새 이벤트를 추가하는 웹 폼

일단 사용자가 이벤트 정보를 이 폼에 입력한 후 폼을 제출하면 코드 나머지 절반이 실행된다. 가장 먼저, 스크립트는 HTTP 클라이언트를 초기화한다. 이 과정에서 HTTP 클라이언트는 구글 캘린더 데이터 API와 인증된 연결을 연다. 다음으로, 스크립트는 사용자가 웹 폼에 입력한 정보를 검증한다. 이벤트 시작 날짜와 종료 날짜를 확인한 후 모든 날짜를 RFC 3339 형식으로 변환한다.

이벤트 정보를 검증한 후에는 새로운 EventEntry 객체를 생성한다. 이 객체는 캘린더에 삽입할 새 이벤트를 나타내며, newTitle()과 newWhen() 메서드를 제공한다. 스크립트는 두 메서드를 사용하여 이벤트 제목과 시작 날짜와 종료 날짜를 설정한다. 객체 속성을 모두 설정한 후에는 insertEvent() 메서드를 호출하여 구글 서버에 해당 이벤트를 저장한다. 저장한 이벤트는 캘린더에 즉시 표시된다.

그림 4는 캘린더에 새 이벤트를 성공적으로 추가한 후 얻어지는 결과다.

그림 4. 새 이벤트를 추가한 결과

기존 이벤트 삭제하고 수정하기

이벤트를 삭제하기는 더욱 쉽다. 해당 이벤트 URL을 얻은 후 해당 URL에 DELETE 요청을 보내면 그만이다. 젠드 라이브러리에서는 getCalendarEventEntry() 메서드로 이벤트 객체를 얻은 후 객체의 delete() 메서드를 호출한다. 자세한 내용은 Listing 6을 참조한다.

Listing 6: 이벤트 삭제하기

<?php // 클래스 로드 require_once 'Zend/Loader.php'; Zend_Loader::loadClass('Zend_Gdata'); Zend_Loader::loadClass('Zend_Gdata_ClientLogin'); Zend_Loader::loadClass('Zend_Gdata_Calendar'); Zend_Loader::loadClass('Zend_Http_Client'); // 서비스에 연결 $gcal = Zend_Gdata_Calendar::AUTH_SERVICE_NAME; $user = "username@gmail.com"; $pass = "pass"; $client = Zend_Gdata_ClientLogin::getHttpClient($user, $pass, $gcal); $gcal = new Zend_Gdata_Calendar($client); // 이벤트 인출 // 이벤트 삭제 try { $event = $gcal->getCalendarEventEntry('http://www.google.com/calendar/ feeds/default/private/full/xxxxxxx'); $event->delete(); } catch (Zend_Gdata_App_Exception $e) { echo "Error: " . $e->getResponse(); } echo 'Event successfully deleted!'; ?>

이벤트를 수정하는 방법도 비슷하다. 해당 이벤트 URL을 얻은 후 이 URL에 PUT 요청과 수정할 정보를 보내면 그만이다. 젠드 라이브러리에서는 이벤트 객체 속성에 새 값을 설정한 후 save() 메서드로 변경된 값을 이벤한다.

Listing 7: 이벤트 수정하기

<?php // 클래스 로드 require_once 'Zend/Loader.php'; Zend_Loader::loadClass('Zend_Gdata'); Zend_Loader::loadClass('Zend_Gdata_ClientLogin'); Zend_Loader::loadClass('Zend_Gdata_Calendar'); Zend_Loader::loadClass('Zend_Http_Client'); // 서비스에 연결 $gcal = Zend_Gdata_Calendar::AUTH_SERVICE_NAME; $user = "username@gmail.com"; $pass = "pass"; $client = Zend_Gdata_ClientLogin::getHttpClient($user, $pass, $gcal); $gcal = new Zend_Gdata_Calendar($client); // 이벤트 인출 // 새로운 이벤트 속성 설정과 이벤트 갱신 try { $event = $gcal->getCalendarEventEntry('http://www.google.com/calendar/feeds/ default/private/full/xxxxxxxxxxx'); $event->title = $gcal->newTitle($title); $when = $gcal->newWhen(); $when->startTime = $start; $when->endTime = $end; $event->when = array($when); $event->save(); } catch (Zend_Gdata_App_Exception $e) { die("Error: " . $e->getResponse()); } echo 'Event successfully modified!'; ?>

캘린더 작업 통합하기

지금까지 익힌 지식을 바탕으로 좀 더 실용적인 프로그램을 구현해 보자. Listing 8은 Listing 3을 개선한 코드로, 각 이벤트에 편집과 삭제 링크를 추가한다. 각 링크는 edit.php와 delete.php 스크립트를 가리키며, (이벤트 목록에서 추출한) 이벤트 식별자를 각 스크립트에 GET 메서드로 넘긴다.

Listing 8: 이벤트 목록 가져오기

<?php require_once 'Zend/Loader.php'; Zend_Loader::loadClass('Zend_Gdata'); Zend_Loader::loadClass('Zend_Gdata_ClientLogin'); Zend_Loader::loadClass('Zend_Gdata_Calendar'); Zend_Loader::loadClass('Zend_Http_Client'); $gcal = Zend_Gdata_Calendar::AUTH_SERVICE_NAME; $user = "username@gmail.com"; $pass = "pass"; $client = Zend_Gdata_ClientLogin::getHttpClient($user, $pass, $gcal); $gcal = new Zend_Gdata_Calendar($client); $query = $gcal->newEventQuery(); $query->setUser('default'); $query->setVisibility('private'); $query->setProjection('basic'); try { $feed = $gcal->getCalendarEventFeed($query); } catch (Zend_Gdata_App_Exception $e) { echo "Error: " . $e->getResponse(); } ?>

<?php echo $feed->title; ?>

<?php echo $feed->totalResults; ?> event(s) found.
    <?php foreach ($feed as $event) { echo "
  1. \n"; echo "

    " . stripslashes($event->title) . "

    \n"; echo stripslashes($event->summary) . "
    \n"; $id = substr($event->id, strrpos($event->id, '/')+1); echo "edit | "; echo "delete
    \n"; echo "
  2. \n"; } echo ""; ?>

Add a new event

그림 5는 Listing 8을 실행한 결과다.

그림 5. 이벤트 목록을 표시하는 웹 페이지

Listing 9는 delete.php 스크립트 코드다. 이 스크립트는 GET 메서드로 이벤트 식별자를 받아 해당 이벤트를 삭제한다. 구체적인 설명은 Listing 6을 참조한다.

Listing 9: 이벤트 삭제하기

Delete Event

<?php // 클래스 로드 require_once 'Zend/Loader.php'; Zend_Loader::loadClass('Zend_Gdata'); Zend_Loader::loadClass('Zend_Gdata_ClientLogin'); Zend_Loader::loadClass('Zend_Gdata_Calendar'); Zend_Loader::loadClass('Zend_Http_Client'); // 서비스에 연결 $gcal = Zend_Gdata_Calendar::AUTH_SERVICE_NAME; $user = "username@gmail.com"; $pass = "pass"; $client = Zend_Gdata_ClientLogin::getHttpClient($user, $pass, $gcal); $gcal = new Zend_Gdata_Calendar($client); // 이벤트 ID가 존재하면 // 피드에서 이벤트 객체를 얻는다. // 이벤트 삭제 if (isset($_GET['id'])) { try { $event = $gcal->getCalendarEventEntry('http://www.google.com/calendar/ feeds/default/private/full/' . $_GET['id']); $event->delete(); } catch (Zend_Gdata_App_Exception $e) { echo "Error: " . $e->getResponse(); } echo 'Event successfully deleted!'; } else { echo 'No event ID available'; } ?>

Listing 10은 edit.php 스크립트 코드다.

Listing 10: 이벤트 편집하기

Edit Event

<?php // 클래스 로드 require_once 'Zend/Loader.php'; Zend_Loader::loadClass('Zend_Gdata'); Zend_Loader::loadClass('Zend_Gdata_ClientLogin'); Zend_Loader::loadClass('Zend_Gdata_Calendar'); Zend_Loader::loadClass('Zend_Http_Client'); // 서비스에 연결 $gcal = Zend_Gdata_Calendar::AUTH_SERVICE_NAME; $user = "username@gmail.com"; $pass = "pass"; $client = Zend_Gdata_ClientLogin::getHttpClient($user, $pass, $gcal); $gcal = new Zend_Gdata_Calendar($client); // 이벤트 세부 내역 얻기 if (!isset($_POST['submit'])) { if (isset($_GET['id'])) { try { $event = $gcal->getCalendarEventEntry('http://www.google.com/calendar/ feeds/default/private/full/' . $_GET['id']); } catch (Zend_Gdata_App_Exception $e) { echo "Error: " . $e->getResponse(); } } else { die('ERROR: No event ID available!'); } // 자료를 사람이 읽을 수 있는 형식으로 변환 // 이 레코드로 웹 폼 생성 $title = $event->title; $when = $event->getWhen(); $startTime = strtotime($when[0]->getStartTime()); $sdate_dd = date('d', $startTime); $sdate_mm = date('m', $startTime); $sdate_yy = date('Y', $startTime); $sdate_hh = date('H', $startTime); $sdate_ii = date('i', $startTime); $endTime = strtotime($when[0]->getEndTime()); $edate_dd = date('d', $endTime); $edate_mm = date('m', $endTime); $edate_yy = date('Y', $endTime); $edate_hh = date('H', $endTime); $edate_ii = date('i', $endTime); ?> Event title:

Start date (dd/mm/yyyy):

Start time (hh:mm):
End date (dd/mm/yyyy):

End time (hh:mm):
<?php } else { // 폼을 제출했다면 // 입력한 정보를 검증 if (empty($_POST['id'])) { die('ERROR: Missing event ID'); } if (empty($_POST['title'])) { die('ERROR: Missing title'); } if (!checkdate($_POST['sdate_mm'], $_POST['sdate_dd'], $_POST['sdate_yy'])) { die('ERROR: Invalid start date/time'); } if (!checkdate($_POST['edate_mm'], $_POST['edate_dd'], $_POST['edate_yy'])) { die('ERROR: Invalid end date/time'); } $title = htmlentities($_POST['title']); $start = date(DATE_ATOM, mktime($_POST['sdate_hh'], $_POST['sdate_ii'], 0, $_POST['sdate_mm'], $_POST['sdate_dd'], $_POST['sdate_yy'])); $end = date(DATE_ATOM, mktime($_POST['edate_hh'], $_POST['edate_ii'], 0, $_POST['edate_mm'], $_POST['edate_dd'], $_POST['edate_yy'])); // 존재하는 이벤트 레코드를 가져옴 // 이벤트 속성 갱신 // 변경 사항을 서버에 저장 try { $event = $gcal->getCalendarEventEntry('http://www.google.com/calendar/ feeds/default/private/full/' . $_POST['id']); $event->title = $gcal->newTitle($title); $when = $gcal->newWhen(); $when->startTime = $start; $when->endTime = $end; $event->when = array($when); $event->save(); } catch (Zend_Gdata_App_Exception $e) { die("Error: " . $e->getResponse()); } echo 'Event successfully modified!'; } ?>

Listing 9와 마찬가지로, Listing 10도 GET 메서드로 이벤트 식별자를 받는다. 그런 다음, getCalendarEventEntry() 메서드에 이벤트 식별자를 넘겨 해당 이벤트 정보를 가져온 후 세부 내역을 웹 폼으로 표시한다. 사용자는 폼에서 이벤트 정보를 살펴본 후 수정한다. 사용자가 수정한 폼을 제출하면 스크립트는 다시 구글 캘린더 데이터 API에 연결하고, 새 이벤트 정보가 담긴 <entry> 엘리먼트를 생성한 후, save() 메서드를 호출해 서버에 저장한다.

이벤트 검색하기

여느 구글 데이터 API와 마찬가지로, 캘린더 API 역시 REST 질의에 다음과 같은 몇 가지 매개변수를 지정하는 방법으로 개발자가 결과를 제어할 수 있다.

  • 매개변수 start-index: 항목에서 시작 색인을 지정한다.
  • 매개변수 max-results: 가져올 항목 수를 지정한다.
  • 매개변수 start-min과 start-max: 반환할 항목에 대한 날짜 범위를 지정한다.
  • 매개변수 orderby: 정렬 방법을 지정한다.

Listing 11은 Listing 2에서 가져왔던 이벤트 목록 전체 중 다음 주 이벤트만 시작 날짜 순서로 가져오는 코드다.

Listing 11: 날짜로 이벤트 검색하기

<?php // 환경 설정 매개변수 설정 $userid = 'username%40googlemail.com'; $magicCookie = 'cookie'; $start = urlencode(date(DATE_ATOM, strtotime('today 00:00'))); $end = urlencode(date(DATE_ATOM, strtotime('+7 days 23:59'))); // 피드 URL 생성 $feedURL = "http://www.google.com/calendar/feeds/$userid/private- $magicCookie/basic?start-min=$start&start-max=$end&orderby=starttime"; // 피드를 SimpleXML 객체로 읽음 $sxml = simplexml_load_file($feedURL); // 이벤트 개수 얻기 $counts = $sxml->children('http://a9.com/-/spec/opensearchrss/1.0/'); $total = $counts->totalResults; ?>

<?php echo $sxml->title; ?>

<?php echo $total; ?> event(s) found.
    <?php // 범주에 속한 항목 순회 // 각 항목 세부 내역 출력 foreach ($sxml->entry as $entry) { $title = stripslashes($entry->title); $summary = stripslashes($entry->summary); echo "
  1. \n"; echo "

    $title

    \n"; echo "$summary
    \n"; echo "
  2. \n"; } ?>

또한 특정 질의 용어에 해당하는 항목만 반환하는 대신 전문 검색으로 캘린더를 검색한 후 해당 이벤트만 반환하는 방법도 있다. 구체적인 방법은 Listing 12를 참조한다.

Listing 12: 질의 용어로 이벤트 검색하기

<?php // 환경 설정 매개변수 설정 $userid = 'username%40googlemail.com'; $magicCookie = 'cookie'; $query = urlencode('party'); // 피드 URL 생성 $feedURL = "http://www.google.com/calendar/feeds/$userid/private- $magicCookie/basic?q=$query"; // 피드를 SimpleXML 객체로 읽음 $sxml = simplexml_load_file($feedURL); // 이벤트 개수 얻기 $counts = $sxml->children('http://a9.com/-/spec/opensearchrss/1.0/'); $total = $counts->totalResults; ?>

<?php echo $sxml->title; ?>

<?php echo $total; ?> event(s) found.
    <?php // 범주에 속한 항목 순회 // 각 항목 세부 내역 출력 foreach ($sxml->entry as $entry) { $title = stripslashes($entry->title); $summary = stripslashes($entry->summary); echo "
  1. \n"; echo "

    $title

    \n"; echo "$summary
    \n"; echo "
  2. \n"; } ?>

젠드 클라이언트 라이브러리도 이런 매개변수를 지원한다. Listing 13은 Listing 8 코드에 검색 폼과 폼 처리기를 추가한 코드다.

Listing 13: 사용자와 대화식 검색 기능 추가

<?php require_once 'Zend/Loader.php'; Zend_Loader::loadClass('Zend_Gdata'); Zend_Loader::loadClass('Zend_Gdata_ClientLogin'); Zend_Loader::loadClass('Zend_Gdata_Calendar'); Zend_Loader::loadClass('Zend_Http_Client'); $gcal = Zend_Gdata_Calendar::AUTH_SERVICE_NAME; $user = "username@gmail.com"; $pass = "pass"; $client = Zend_Gdata_ClientLogin::getHttpClient($user, $pass, $gcal); $gcal = new Zend_Gdata_Calendar($client); $query = $gcal->newEventQuery(); $query->setUser('default'); $query->setVisibility('private'); $query->setProjection('basic'); $query->setOrderby('starttime'); if(isset($_GET['q'])) { $query->setQuery($_GET['q']); } try { $feed = $gcal->getCalendarEventFeed($query); } catch (Zend_Gdata_App_Exception $e) { echo "Error: " . $e->getResponse(); } ?>

<?php echo $feed->title; ?>

<?php echo $feed->totalResults; ?> event(s) found.
    <?php foreach ($feed as $event) { echo "
  1. \n"; echo "

    " . stripslashes($event->title) . "

    \n"; echo stripslashes($event->summary) . "
    \n"; $id = substr($event->id, strrpos($event->id, '/')+1); echo "edit | "; echo "delete
    \n"; echo "
  2. \n"; } echo ""; ?>

Add a new event

Search for events containing:

Listing 13을 실행한 결과는 그림 6과 같다.

그림 6. 검색 폼

그림 7은 'party'라는 낱말이 포함된 모든 이벤트를 검색한 결과다.

그림 7. 캘린더 검색 결과

요약

이상이다. 지금까지 PHP 프로그램에 구글 캘린더 서비스를 통합하는 방법을 살펴봤다. 구체적으로는 SimpleXML과 젠드 클라이언트 라이브러리를 사용하는 방법을 익혔다. 이 기사에서는 살펴본 내용은 다음과 같다.

  • 구글 캘린더 피드 형식 소개
  • 날짜와 키워드로 캘린더를 검색하는 방법
  • 캘린더 이벤트를 추가하고 수정하고 삭제하는 방법
  • 구글 캘린더를 바탕으로 나름대로 서비스를 구현하는 방법

위 예제에서 보듯이, 구글 캘린더 데이터 API는 완성도가 높고, 사용하기 편하며, 유연성도 높다. 그래서 개발자 입장에서 구글 캘린더를 바탕으로 자신만의 웹 앞단을 생성하기가 매우 쉽다. 직접 사용하면서 가능성을 짚어보기 바란다.

필자소개

Vikram Vaswani는 Melonfire 사의 창립자이자 CEO다. Melonefire 사는 오픈 소스 도구와 기술을 전문으로 다루는 컨설팅 서비스 회사다. Vikram Vaswani는 PHP Programming Solutions How to do Everything with PHP and MySQL 을 저술한 지은이이기도 하다.

제공 : DB포탈사이트 DBguide.net