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



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



출처 : http://www.phpschool.com/gnuboard4/bbs/board.php?bo_table=tipntech&wr_id=1776

 

PHPLIB 강좌 1

작성자 : 나종성 konlo@geonji.co.kr , http://dev.geonji.co.kr/~konlo

1 시작하기

웹 페이지를 PHP로 개발하던 중 마소 11월 호에 PHPLIB를 보게 되었습니다. 한 참 사용자의 관리 때문에 골 머리를 썩고 있었는데, 마침 PHPLIB에 페이지 관리 기능을 보고 잡지 책과 홈페이지 (http://phplib.netuse.de)의 매뉴얼을 보고 PHPLIB을 분석하게 되었습니다.

라이브러리를 만든 이의 그 심오한 뜻(?)은 잘 알지 못하지만 그나마 분석하여 사용할 수 있을 정도의 분석을 해보았습니다.  그간 도움만 받았던 Internet 사용자들에게 이제 조금이나마 도움을 드리고자 합니다. ^^:

일단 설명은 php를 아시는 분, 그리고 기타 Unix, Linux 등의 서버 명령어들을 아시고 계신 분, DB를 사용 관리하실 줄 아시는 분으로 설명하겠습니다. ^^: 시작은 역시 설치부터 시작하여 설치 후 PHPLIB가 제대로 동작하는가를 살펴 보겠습니다. 기본 구성의 PHPLIB의 매뉴얼 순서대로 가며 제가 필요하다고 생각하여 공부한 내용들만 다루겠습니다. (사실 영어도 딸리고 아직 전부를 안다고는 할 수 없으니...^^:)

2 설치 하기

2-1 소스 받기

    PHPLIB의 홈페이지인 http://phplib.netuse.de 에 가셔서 download페이지에 가시면 phplib-7.2c.tar.gz을 받으실 수 있습니다. 무척이나 쉽죠 ? ^^:

2-2 설치 하기

    여기서 부터는 일단 PHPLIB에 나와 있는 매뉴얼의 단계에 따라서 인스톨을 해 보겠습니다. 원래 매뉴얼이라는 것이 한 번 읽어보면 영~~ 감이 오지 않더군요 ..(머리가 나빠서인가 ?? -_-;;) 일단 매뉴얼의 단계를 보지요. 매뉴얼 보시면 step1 ~ step10까지 설치 과정이 있는데 별로 어렵지는 않았는데 처음에는 왜 이렇게 헤맸는지 (역시 머리가 나빠서 ? -_-++) 제가 혹시라도 해석을 잘 못 할 수도 있으니 원문과 함께 부가 설명을 하는 것이 좋을 듯 하군요 . 그리고 편의를 위하여 가상 드렉토리를 만들지요.

   현재 제 홈디렉토리는 /home/konlo 그리고 웹서버는 /home/konlo/httpd 그리고 document root는 /home/konlo/httpd/htdocs/ 입니다.

Step 1

Create an include directory named php parallel to your web servers document root directory. Do not put the include directory below your web servers document root.

document root directory와 나란하게 php라는 디렉토리를 만들라고 했습니다. 제가 해석을 맞게 한 것인지는 모르겠지만 이 부분은 어는 곳에다가 설치해도 관계가 없을 것 같군요. 나중에 include_path만 설치된 지정해주면 되니깐요. 그래도 혹시 모르니...

ex) 현재 디렉토리 /home/konlo/httpd

/home/konlo/httpd> mkdir php <- 일단 디렉토리를 만듭니다. 그럼 다음과 같은 드렉토리가 생기겠죠? /home/konlo/http/php

Step 2

Unpack your PHPLIB distribution. Move the contents of the php distribution directory into the php directory you just created.

PHPLIB의 압축을 풀고 php의 내용을 생성된 php디렉토리로 이동시키라고 했습니다. 파일 압축을 풀고 tar를 풀면 파일 이름과 같은 디렉토리가 하나 생성 됩니다. 그 안으로 들어가시면 php 라는 디렉토리가 있는데 이것을 전 단계에서 만들었던 php 디렉토리에 복사를 합니다.

ex)

사실 압축은 어디에다 풀어도 관계 없구요  저는 그냥 홈디렉토리에서 압축을 풀겠습니다.

/home/konlo>gzip -d phplib-7.2c.tar.gz <- 이렇게 하면 압축이 풀리면서 phplib-7.2c.tar와 같은 파일로 변합니다.

/home/konlo>tar -xvf phplib-7.2c.tar  <-이렇게 하면 tar를 풀리면서 파일명과 같은 디렉토리가 생성됩니다. 그럼 한 번 들어가보죠

/home/konlo>cd phplib-7.2c <- 파일명에서 tar를 빠지고요... ^^:

/home/konlo/phplib-7.2c> ls <- 보시면 php라는 디렉토리가 있습니다.

CHANGES  COMMIT  COPYING  CREDITS  HELP  Makefile  README  TODO  VERSION  doc/  pages/  php/  stuff/  unsup/

이제 이 php의 디렉토리에 있는 내용들을 아까 만들었던 디렉토리에 복사를 합니다.

/home/konlo/phplib-7.2c>cp php/* /home/konlo/httpd/php

이렇게 하면 php내용들이 새로 만든 드렉토리에 복사되겠죠?

Step 3

Get to the php3.ini file for your web servers PHP interpreter and update the include_path statement so that it points to that php directory. Update the auto_prepend_file statement so that it points to the prepend.php3 file in that include directory.

If you do not have control over your php3.ini file, you did not read the VERY IMPORTANT NOTE above.

여기에서 php3.ini 파일이 나왔는데 PHPLIB가 php3를 가지고 만들어서 그런 것 같구요. 파일 이름은 별로 신경 쓰시지 마시고 일단 모르시는 분들을 위해서 php.ini 파일에 대해서 간단하게 설명드리면  php의 환경을 저장하고 있는 화일로 기타 여러가지 설정을 할 수 있는 파일입니다. 위의 문장에서는 include_path를 지정하여 php(새로 만들었던)디렉토리를 지정하라구했구요 ..그리고 auto_prepend_file를 prepend.php3로 지정하도록했습니다.

php.ini 파일은 보통 /usr/local/lib 에 넣고 사용하는데요 phpinfo()함수를 호출하여 보면 첫 번째 테이블에 Configuration file (php.ini) path 라는 항목이 있으니 이곳에 php.ini파일을 놓고 고치시면 됩니다. 설정 변경은 다른 방법이 있는 것이 아니라 vi 또는 기타 편집기를 이용하여 include_path와 auto_prepend에 각각 값을 넣어주면 됩니다. 설정 이름에서 알 수 있듯이 include_path는 include될 파일의 위치를 지정하는 것이고 auto_prepend는 pre-라는 접두사에서 알 수 있듯이 처음에 미리 시작되는 코드를 지정하는 것입니다. 즉 각각의 페이지가 열릴 때마다 미리 파일에서 열려서 그 내용을 페이지가 사용하는 겁니다. 대표적으로 여기서는 관련 class를 포함합니다.

위의 값들을 각각 다음과 같이 설정합니다.

include_path    = ".:/home/konlo/httpd/php"

auto_prepend_file       = "prepend.php3";

include_path에서 잘 보시면 ':' 이 부분이 보일 것입니다. 이것은 include_path를 두 개 이상 지정할 때 사용합니다.(소스를 직접 보시면 아시겠지만 Unix 는 delimiter는 콜론(:), Window는 세미콜론(;)을 사용합니다.) 그러니깐 위와 같이 설정하면 include될 파일의 위치가 현재 디렉토리와 /home/konlo/httpd/php가 된다는 이야기입니다. 그리고 prepend.php3가 페이지마다 읽혀지게 되는 것입니다.

Step 4

Also check that track_vars are enabled and that you have enabled magic_quotes_gpc. While you are at it, you might want to check sendmail_path, if you plan to send mail from your application. It has to be set to /usr/lib/sendmail -t on most UNIX systems to work.

If you do not have control over your php3.ini file, you did not read the VERY IMPORTANT NOTE above.

step 3과 같이 php.ini 파일을 변경하는 부분입니다. php3.ini or php.ini 화일에서 track_vars와 magic_quotes_gpc를 On으로 변경합니다. 그리고 sendmail에 대한 설명이 나와있는데 이것은그냥 놔두셔도 괜찮을 것 같군요. 혹시 모르니 관계되는 분은 잘 살펴보시길..

ex)

magic_quotes_gpc        =       On

track_vars                      =       On

Step 5

cd into the php include directory. Edit local.inc. In class DB_Example supply the appropriate parameters for your database connection.

여기서는 DB를 위해서 설정하는 부분입니다.새로 생성된 php디렉토리로 이동하셔서 local.inc 파일을 DB에 접근할 수 있도록 DB_Example의 내용을 편집합니다. 다른 것이 아니라 MySql에 연결할 수 있도록 host, Database, User, Password 값을 입력하는 것입니다. 참고로 local.ini 파일은 기본적인 class을 상속받아서 개인들의 구미에 맞게 변경할 수 있도록 상속된 클래스들이 모여 있습니다. default로 XXX_Example로 되어 있는 것들입니다. 그중에서 DB에 관련된 DB_Example의 클래스 메버 변수들을 수정하는 겁니다.

ex)

host가 local 호스트이고 DB가 Homepage 그리고 사용자가 root , root의 패스워드가 123a라면 다음과 같이 입력하면 됩니다.

class DB_Example extends DB_Sql {   var $Host     = "localhost";   var $Database = "Homepage";   var $User     = "root";   var $Password = "123a"; }

Step 6

For this database, run create_database.mysql from the distribution to create active_sessions and auth_user. auth_user will be populated with a sample user named kris with a password test.

phplib리는 기본적으로 세션 관리를 db를 통해서 하게 됨으로 DB가 필수입니다. PHPLIB가 데이터를 저장할 수 있는 table들을 만들어줘야하는데 기본적으로 active_session, active_session_split,  auth_user, auth_user_md5, db_sequence를 만들게 됩니다. 그리고 기본적으로 사용할 수 있는 사용자로 kris라는 user와 test라는 password를 제공합니다. 이작업은 아주 편하게도 다 스크립트로 만들어 놨습니다. 그냥 우리는 좀 복잡한 명령어(?) 한 줄이면 필요한 table과 데이터를 생성할 수 있습니다. 실행 스크립트는 처음에 압축을 푼 디렉토리를 보면 stuff라는 디렉토리가 있습니다. 그 디렉토리에 가보시면 각 DB만다 스크립트가 있는데 저는 MySql를 사용 함으로  create_database.mysql를 사용하겠습니다. 대충 create_database.mysql 파일을 열어보시면 아시겠지만 방금 말씀드렸던 table에 대한 스키마가 있습니다. 그리고 가장 상단에 사용 법이 다음과 같이 나와 있습니다.

mysql -h host database_name < 이렇게요   <->

여기에 사용자가 있다면 -u 옵셥. 그리고 패스워드가 있으면 -p 옵션을 같이 사용해도 문제 없겠군요 .

위와 같은 명령어를 실행시키면 table이 생성되게 됩니다. 물론 mysql daemon이 떠있어야 하구요 (그냥 위와 같이 실행하라고만 말씀드렸는데 mysql실행할 때의 경로와 create_database.mysql의 path도 신경을 써주셔야 합니다. )

ex) 혹시 하는 마음에 예를 보여드리지요

저는 mysql이 /home/konlo/mysql 에 설치되어 있구요 mysql이라는 파일은 ./bin있습니다. 그러니 다음과 같이 하면 됩니다.

/home/konlo/mysql/bin>mysql -u root -p homepage < /home/konlo/phplib-7.2c/stuff/create_database.mysql

이렇게요

Step 7

Move the contents of the pages directory and all its subdirectories into your document root directory.

이부분은 설정과는 관계가 없는데요 phplib가 제대로 설치가 되었는지 보기 위해서 예제페이지를 만들어 놓은 것입니다. 압축 푼 디렉토리에 보시면 pages라는 디렉토리가 있습니다. 이것을 document root directory로 이동하라고 했습니다. 그러니깐 pages의 위치는 다음과 같이 됩니다. 복사도 좋고 이동도 좋습니다.

/home/konlo/httpd/htdocs/pages

Step 8

Access the "/" URL of your web server with cookies enabled. If no index.html is present, index.php3 will be displayed. If you reload that page, the number shown must increment. Access your database with the mysql command client and select * from active_sessions. Check that there is a single session record for your browser and see how the text in val changes when you reload the page and select * from active_sessions again. If this works, the session class is functional with cookie mode.

여기서부터는 설치가 잘 되었는지를 보기 위한 단계입니다. 브라우저에서 테스트를 위해 만들었던 pages의 내용을 테스트하는 단계입니다. 저같은 경우는 http://dev.geonji.co.kr:9080/pages/index.php3 으로 브라우저에서 보면 실행 화면을 볼 수 있습니다. 위의 내용은 페이지를 reload할 때마다 그 데이터 값이 증가되어야한다는 이야기를 하고 있습니다.(나중에 나오겠지만 session 데이터여서 같은 세션에서는 계속해서 데이터 값이 증가합니다. )

Step 9

Now access showoff.php3. Try to login as kris, password test. Check active_sessions again. You now should have a Example_Session entry (see the name column) and a Example_User entry in your table. Both should increment on reload.

여기서는 showoff.php3에서 kris/test 로 로그인 할 수 있다는 이야기를 하고 있습니다. 그리고 그곳에서도 데이터 값이 증가해야한 다는 이야기를 하고 있습니다.

Step 10

Try again with cookies disabled. You should get a new session (the cookie is lost) and you should be able to see your session id as the get parameter part of your URL.

여기서는 cookie를 disable 시키면 세션 아이디를 URL의 파라미터로 볼 수 있을 것이라는 이야기를 하고 있습니다. 제가 해보지는 않았지만 다음과 같은 파라미터를 볼 수 있을 것입니다. Example_Session=SID(세션 아이디 좀 복잡한 숫자와문자의 조합을 되어있지요)

여기까지 매뉴얼의 설치 과정을 한 번 살펴 보았는데 ... 잘 따라해보셨는지 모르겠더군요 . ^^: 아~ 그리고 여기서 한가지 설치가 제대로 되었다고 하더라고 step 8의 페이지 데이터 증가가 cache 때문에 잘 증가 되지 않더군요. 실제로 값이 증가가 되었는데도 캐쉬 때문에 값이 증가되지 않는 것처럼 보입니다. 제가 처음에는 잘 못 설치된 줄 알았는데 좀 찾아보니 그것이 아니더군요. 캐쉬에 대한 설정하는 멤버 변수가 있는데 이부분을 수정하면 됩니다. 어려운 것은 아니구요 ^^:

아까 local.inc (새로 만들었던 php 디렉토리에 )에 상속 받은 Example_Session 클래스를 보시면 멤버 변수 중에 var $allowcache 라는 것이 있습니다. 이것을 "no"로 설정해주시면 됩니다.

var $allowcache = "no";

이렇게 하면 reload를 할 때마다 데이터 값이 잘 증가하는 것을 볼 수 있을 것입니다.

초보 시절 (지금도 반 초보지만 ^^:) 뭣 좀 해보려고 해도 설치가 안 되어서 시작도 못해보는 경우가 많았는데 여기저기 도움을 받아서 겨우겨우 했던 기억이 나는군요. 어떻게 큰 도움이 되지는 못하더라도 조금이나마 설치에 도움을 줬으면 합니다.

혹시 이해가 잘 안 되시거나 잘 못 된 부분 있으면 다음으로 연락주십시오~ konlo@geonji.co.kr

다음에는 마소지에 실린 내용과 매뉴얼 그리고 제가 소스를 분석한 내용을 가지고 사용법(특히 default 사용자에 대한..참 괜찮은 것 같아요 ^^:)에 대해서 다시 한 번 강좌(?)를 올리도록 하지요. 그리고 더욱 관심 있으신 분은 마소 11월호 12월호 를 참고 하십시오. 1월 호에서는 template에 대해서 연재된다고 합니다. 소스코드와 디자인의 분리라는 측면에서 참 많이 관심이 갑니다. 아시는 분은 아시겠지만 참으로 두 개가 꼬여서 여간 번거롭지가 않습니다. 기회가 되다면 이것도 한 번 정리를 해보죠 ~~ ^^: 벌써 2001년 새해가 밝았습니다. 모든 희망하시는 일 잘 되기를 기원합니다. ~~ 그럼 이만 꾸벅

ps: 혹시라도 제 글이 다른 곳에 올려질 때는 연락이라도 좀 주십시오~~ 큭큭 ..^^:



자동차를 직거래로 매매하게 되었는데 자동차민원 대국민포털에서 진행하였고 사용성이 좋아 앞으로 개발할 때 많은 아이디어를 주었습니다.

이 사이트의 장점은 다음과 같습니다.

1) 많이 찾는 질문에 대해서는 길잡이 메뉴로 분리하여 찾기 쉽게 했다.

2) 단계별로 예시를 들어서 대입하기 쉽게 하였다.

3) 각 단계별로 다이어그램을 표시하여 총 단계 중 현재는 어디인지 찾기 쉽게 하였다.

4) 각 메뉴마다 인쇄하기를 별도로 두어 오프라인으로 확인할 수 있도록 하였다.

5) 각 단계가 끝날때마다 인수자, 인도자에게 SMS와 메일로 알려준다.

 

기능별

1) 메인화면

image

2) 초보자 길라잡이 – 매뉴얼 보다 더 쉽게 따라할 수 있게 도와줌

image

 

image

 

3) 인도하기

image

4) 인수하기

- 필요한 서류가 3개 있는 경고 2개가 온라인으로 인증 가능한 경우 모두 다 첨부를 요구하지 않고 필요한 서류만 첨부를 받도록 안내함으로서 혼란을 없애고 사용자의 편의를 도왔다.

예를 들어 주민등록등본 , 의무보험 가입증명서는 확인됨으로 나오고 양도증증명서만 파일을 첨부하도록 하고, 첨부하면 상태에 “v” 표시를 해서 확인을 쉽게 하도록 했다.

image

5) 단계별 안내

다이어그램으로 현재 어디까지 갔는지 쉽게 확인할 수 있게 도와줌

ecar1-1

http://www.ecar.go.kr



* 현재 시간구하기

$sigan=strftime("%Y/%m/%d %H:%M:%S",time());

2011/12/08 17:58:05

* 현재시간 + 2분

$sigan_limit=strftime("%Y/%m/%d %H:%M:%S",mktime(date("H"), date("i")
+$minute_limit, date("s"), date("m"), date("d"), date("Y")));

2011/12/08 17:58:05   2011/12/08 18:00:05



세상에. 단위업무 유지보수 계약을 해도 계약서가 10페이지가 넘어가는데 IT아웃소싱을 하는데도 10페이지 내외면 심각하네요.

출처 : 전자신문

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

10년차 IT아웃소싱, 여전히 '주먹구구식'

제대로 된 계약서도 없어…부실 운영에 불신만 가득

2000년대 들어 기업은 비용 절감 수단으로 IT아웃소싱 전략을 앞다퉈 채택했다. 대부분 그룹은 삼성·LG에 이어 IT셰어드서비스 체계 수립을 적극 실시했다. 국내에 IT아웃소싱 바람이 분 지 10년이 지났다. 그러나 여전히 국내 IT아웃소싱 수준은 ‘주먹구구식’이란 평가를 받고 있다. 당초 취지인 비용절감은 물론이고 업무 효율화도 이루지 못하고 있다. IT아웃소싱 서비스를 제공받는 기업과 수행하는 기업 간 불신만 커지고 있는 것이 현실이다.

기업들은 IT아웃소싱 효과를 제대로 보고 있지 못하다. 가장 큰 배경으로 전문가들은 그룹 내 계열 IT서비스기업이 당연하게 IT아웃소싱을 수행하는 관행 때문이라고 입을 모은다. ‘우리’라는 문화적 인식 때문에 철저한 준비 없이 IT아웃소싱을 진행하는 경우가 대부분이다. 제3자에게 IT아웃소싱을 제공받는 경우도 크게 다르지 않다. 현재 기업들이 IT아웃소싱 시행 시 자주 범하게 되는 잘못은 △부실한 계약서 내용 △객관적인 대가체계 기준 미흡 △서비스 수준 관리 미흡 △평가체계 부재 등이다.

◇명확하지 않은 부실 계약서=IT아웃소싱 시행에서 가장 큰 문제점 중 하나가 부실한 계약서다. 현재 우리나라 대부분 기업은 그룹 계열 IT서비스기업이 아웃소싱을 수행하다 보니 계약서가 구체적이지 못하다. 책임 조항도 명확하지 않다. 해외 선진기업은 아웃소싱사업 준비만도 3~6개월 동안 진행하고 계약서도 200~300페이지에 이를 정도로 상세한 내용을 담는다. 그러나 우리나라 기업은 대부분 계약서 분량이 10페이지에 그친다.

최근 한 온오프라인 쇼핑업체는 판매처리시스템 운용 실수로 전산장애가 발생해 막대한 손실을 입었음에도 불구하고 어떤 책임도 운용업체에 묻지 못했다. 이는 계약서에 운영상 발생된 피해에 손해배상이나 책임 소재 관련 조항이 없어서다. 장애 발생 시 협의해 해결해 나간다는 모호한 내용만이 계약서에 명시돼 있을 뿐이다.

원승영 콤파스매니지먼트컨설팅코리아 대표는 “아웃소싱은 복잡하고 다양한 변수를 포함하고 있어 장기간 운영 중에 수많은 분쟁이 발생할 수 있다”며 “그러나 많은 기업은 계열사 간 특수관계나 한국적 사고방식으로 계약서 중요성이 간과되고 있다”고 지적했다. 원 대표는 “계약서에 모든 요구사항 및 서비스 범위, 책임과 역할을 상세하게 명시해 분쟁을 사전에 방지해야 한다”고 덧붙였다.

◇기준 없이 헤드카운팅으로 산정=객관적인 대가체계 기준이 없다는 것도 아웃소싱 질을 떨어뜨리는 원인이다. 국내 대부분 기업은 아웃소싱 비용을 산정하는 명확한 기준이 없다. 애플리케이션 영역은 기준 마련조차 쉽지 않다. 이러한 이유로 많은 기업은 아웃소싱 비용을 ‘맨먼스(Man/Month)’ 기준으로 책정하고 있다. 이 맨먼스 기준도 실제적으로는 ‘헤드카운팅’ 방식으로 적용된다. 이 방식은 발주기업 담당자가 쉽게 비용을 산정할 수 있고 아웃소싱 수행업체도 매년 단가를 높일 수 있어 양쪽 모두 선호한다.

그러나 서비스 질을 높이는 데는 한계가 있다. 계약 당시 업무별로 인력 수와 수준을 정해 놓기 때문에 수행업체는 유연하게 인력을 운영할 수 없다. 결국 수행업체가 비용절감으로 운영 효율화를 이뤄 서비스 질을 높이는 것은 불가능하다. 발주기업이 비용절감을 위해 아웃소싱 비용을 인하할 경우 수행업체는 무리한 인력운영을 할 수밖에 없다. 아웃소싱 수행 인력들이 과다한 업무에 시달리는 것도 이러한 이유에서다.

대가체계 기준 개선에 노력이 전혀 없었던 것은 아니다. 삼성전자 등 일부 대기업은 아웃소싱 비용 산정 방식에 기능점수(펑션포인트)나 전일종사노동자수(FTE) 등을 적용하기도 했다. 그러나 기능점수나 FTE 적용을 위한 산출 방법이 명확하지 않아, 결국 맨먼스 방식으로 선회했다. 해외에서는 업무량 기반 대가체계가 널리 사용되고 있다.

◇SLA 인식 부족과 평가체계 없어=서비스 수준 관리가 이뤄지지 않고 있다는 것도 문제다. 많은 아웃소싱 수행업체는 발주기업과 서비스수준협약(SLA)을 맺고 있지만, 대부분이 수행업체 위주로 작성돼 있다. 이는 발주기업 아웃소싱 담당자들이 SLA에 폭넓은 이해가 없기 때문이다. 최근 한 컨설팅업체가 국내 대형 그룹 계열사 아웃소싱 담당자를 대상으로 SLA 이해도를 조사한 결과, 주력 계열사 담당자 한 명을 제외하고는 모두 개념 정도만 알고 있는 수준이었다.

SLA를 알고 있다 하더라도 이에 따른 효과에 관심을 갖는 경우는 드물다. 한 IT서비스기업 아웃소싱 담당자는 “발주기업 담당자들은 SLA가 실질적으로 도움을 가져다주지 못한다고 생각한다”며 “SLA 부분은 부속서류 정도로만 여기고 있는 것이 현실”이라고 전했다.

평가체계가 마련돼 있지 못한 것도 서비스 수준을 높이는 데 한계요인이다. IT아웃소싱 체계가 계열사 수행 구조로 이뤄지다 보니 평가 필요성조차 느끼지 못한 경우도 많다. 한 제조업체 CIO는 “제공받고 있는 IT아웃소싱 서비스가 제대로 이뤄지고 있는지 평가를 하고 싶어도 평가체계가 없어 수행하지 못하고 있다”며 “수행한다 하더라도 계열사 관계여서 계약 내용을 변경하는 것도 쉽지 않다”고 토로했다.

해외 선진사례에서는 IT아웃소싱 계약에는 ‘벤치마킹’이라는 평가와 개선과정을 명시해 놓고 있다. 이를 기반으로 장기 아웃소싱 계약을 체결했다 하더라도 1~2년 주기로 정기적인 아웃소싱 서비스 평가를 실시한다. 평가결과에 따라 서비스 수준이나 가격을 조정하기도 한다.

신혜권기자 hkshin@etnews.com

 

[부실한 10년차 IT아웃소싱②]감리 없는 공공 유지보수 사업

전국 26개 운전면허시험장 전산망 마비와 코레일 전산시스템 장애, 금융결제원 지로시스템 전산장애 등 공공기관 전산장애가 올해도 끊임없이 발생했다. 공공기관 전산장애가 끊이지 않고 계속해서 발생하는 것은 정보시스템 유지보수에 문제가 있어서다.

대형 유지보수사업에 감리가 의무화돼 있지 않다는 점이 문제다. 대법원 등 규모가 큰 공공기관 정보시스템 규모는 크고 복잡하다. 그만큼 유지보수 시 발생될 수 있는 정보시스템 추가, 삭제, 변경 등 변동요인이 많다. 적절하게 유지보수를 수행하고 있는지 감독이 필요하다. 현행법에는 공공기관 대형 시스템통합(SI)사업에는 감리를 해야 하지만, 유지보수사업에는 그러한 조항이 없다. 해외에서는 공공기관 정보시스템 유지보수사업에 감리는 필수로 여겨진다.

공공기관 유지보수 담당 공무원들의 정보시스템 운용 대한 이해가 낮은 것도 해결해야 할 과제다. 이러다 보니 담당 공무원은 유지보수사업자에 의존하게 된다. 유지보수업체를 조정하기는커녕 사업자를 쉽게 변경하지도 못한다. 공공기관이 유지보수사업자 선정을 해마다 실시하지만 기존 사업자 외에는 제안조차 하지 않는 이유가 이 때문이다. 최근 발주된 공공기관 유지보수사업 중 100억원 이상 규모 사업은 대부분 단독응찰로 1차 유찰됐다. 지난해 11~12월에 발주된 대형 유지보수사업도 대부분 단독응찰로 1차 유찰됐다.

공공기관 정보시스템 유지보수사업에 적용되는 예산이 단년제로 책정되는 것도 문제다. 유지보수 수행업체가 운영 효율화를 이루기 위해 장기계약이 필요하나 현 예산제도로는 불가능하다. 수행업체도 사업자가 변경되지 않고 장기간 수행해 왔다 하더라도 매년 추진되는 사업자 선정으로 1년 단위로 서비스 체계를 갖출 수밖에 없다. IT서비스기업 한 관계자는 “공공기관 정보시스템 유지보수사업도 민간기업처럼 서비스수준협약(SLA) 기반으로 장기계약을 체결할 수 있도록 법이나 제도 등이 개선돼야 한다”고 말했다.

신혜권기자 hkshin@etnews.com

 

[부실한 10년차 IT아웃소싱③]해외선 IT아웃소싱 평가 실시

 

해외 선진기업들은 우리 기업보다 철저하게 준비한 상태에서 IT아웃소싱을 진행한다. 또 계약기간 중 주기적인 진단과 평가를 실시, 사전에 불신을 제거하고 적정한 대가와 서비스 품질을 유지하도록 한다.

‘IT아웃소싱 벤치마킹’이라고 부르는 서비스 평가는 기업 특성을 고려해 아웃소싱 규모, 비용, 생산성, 품질 부문을 가장 우수한 외부 사례와 비교해 분석하는 방법이다. 일반적으로 제3자에 의해 1~2년 주기로 이뤄진다. 이를 기반으로 △IT운용 환경은 변화하는데 계약금액이 적정한지, 조정 가능한 부분이 있는지 △적당한 품질의 서비스를 받고 있는지 △IT운용 인력 수는 적정한지 △성과를 향상시킬 수 있는 방법은 없는지 등의 해답을 찾는다.

선진국가에서 벤치마킹은 모든 IT아웃소싱 계약에서 필수 단계로 인식돼 있다. 계약 전 발주기업과 공급자 간 합의를 거쳐 계약서에 명시한다. 이는 벤치마킹 결과에 따라 가격을 조정하거나 재계약 시 협상 근거로 활용되기 때문이다. 벤치마킹 권한은 발주기업과 공급사 모두에 부여돼 부당한 서비스 및 대가에 대한 갈등을 사전에 막을 수 있다.

한 컨설팅기업 조사결과에 따르면 벤치마킹을 수행한 발주기업이 수행하지 않은 기업에 비해 아웃소싱 효율이 36%가량 높다. 호주 최대 은행인 커몬웰스은행은 IT아웃소싱 벤치마킹을 위한 개별부서를 두고 2년 주기로 실시하고 있다. 커몬웰스은행은 최근 수행업체와 맺은 10년 장기계약이 완료되자 5년 연장하는 재계약을 체결했다.

신혜권기자 hkshin@etnews.com



출처 : http://www.ciobiz.co.kr/news/articleView.html?idxno=7162

기업을 바꾸는 QR코드, 혁신의 끝은?

QR코드 기반 업무 혁신, 어디까지 진행되었나

 

아이폰이 가져온 스마트폰 빅뱅은 기업 정보화 흐름을 바꿔 놨다. 모바일기기로 이메일부터 전사자원관리(ERP) 시스템까지 사용하는 모바일 오피스는 유행처럼 퍼지고 있다.

하나 더 주목할 것이 있다. 'QR코드'다. 스마트폰 카메라로 읽으면 웹과 연계된다는 점에서 이용이 급속히 확산되고 있는 바코드의 일종이다. QR란 빠른 반응(Quick Response)을 줄인 말로 이미지의 검정색은 1, 흰색은 0을 표시하는 디지털 코드의 일종이다.

스마트폰으로 포털의 '코드 검색'이나 QR코드 전용 리더 앱으로 코드를 스캔하면 동영상, 모바일 웹, 약도 등 다양한 웹 상의 정보를 띄워준다. QR코드는 스마트폰 확산과 더불어 기업 마케팅 수단에서 핵심 정보 전달 매개체로 진화하고 있다. 물류부터 유통 정보 흐름, 소비 모습도 바꾸고 있다. 기존 바코드처럼 쉽게 인쇄가 가능해서 잠재력도 무궁무진하다.

◇홍보 수단에서 물류 등 핵심 정보 매개체로 진화=최근 한 이슬람권 업체는 이슬람교 신도를 위한 QR코드 시스템을 개발했다. 신도들이 사원으로 기도를 하러 가면 자동차를 대절해 신도들을 태우는데 신도들마다 고유의 QR코드를 부여해 탈 때마다 스캔하면 코드를 부여받은 승객이 어느 버스를 타야 하고 위치가 어디인지, 또 목적지가 어디인지 알 수 있다. 일일이 대화를 주고받지 않아도 된다.

유사한 서비스를 고민하는 국내 기업이 있다. QR코드를 아이들 옷에 인쇄해 아이들의 정보를 담을 수 있게 해주는 서비스다. 예를 들어 아이가 옷에 QR코드가 담긴 라벨을 붙이고 있으면 QR코드 안에 부모님 전화번호는 물론이고 옷에 대한 주의사항까지 담을 수 있다는 것이다.

이 같은 고민을 하는 기업은 최근 QR코드를 물류 공급망관리(SCM)에 접목해 업무 속도를 높인 푸드머스다. 풀무원그룹 식자재 공급업체 푸드머스는 전자태그(RFID) 대신 QR코드로 자재 입고와 출고를 관리하기 시작했다. QR코드를 스마트폰으로 읽으면 식품의 영양소까지 파악 가능하도록 개발 중이다. 물류 혁신부터 '믿을 수 있는' 식품을 만드는 역할까지 맡은 것이다.

식자재는 짧은 시간에 정확히 배송해야 하지만 특히 비정형 제품들이 많고 다품종 소량이란 특징이 있다. 기존 막대형 1차원 바코드를 사용하던 푸드머스는 RFID와 QR코드 가운데 고민하다 인식률과 원가 등을 고려해 QR코드를 도입했다.

QR코드는 협력업체들이 마치 바코드를 인쇄하듯 QR코드를 SCM 포털로 인쇄할 수 있도록 하면 되기 때문에 리더 도입 비용만 일시적으로 들었다. 바로 이러한 점이 최근 기업들이 관심을 가지는 QR코드의 가능성이다.

◇RFID 대체 가능할까. 동시 인식 어려워=QR코드는 기존 바코드처럼 '인쇄'만 하면 된다. 원가가 저렴하면서 기존 바코드 이상의 효과를 낼 수 있는 것이다.

QR코드의 단점은 RFID처럼 다수 제품 동시 인식이 되지 않는다는 점이다. 최근 QR코드를 도입한 제약업계 관계자는 “생산 공정에서는 RFID를 사용하고 단순 정보를 담아 소비자에게 전달하는 데는 QR코드를 쓰는 등 그 영역을 분리하고 있다”며 “아직 QR코드로 다량의 제품을 동시에 스캔하기 어렵기 때문에 생산 현장에서 쓰기는 어렵다”고 말했다.

현재 기술로는 RFID도 다수 제품 동시 인식률이 완벽하지는 않다. 단품 단위 인식에서는 대등한 위치에 있다. QR코드 스캔 장비를 개발하는 업체도 늘어나면서 단품 단위 스캔 인식은 RFID 인식 속도를 넘어서고 있다. 스캐너로 인식하면 iOS 혹은 안드로이드OS 모바일기기로 정보가 바로 전송된다.

특히 QR코드는 스마트폰으로 직접 인식이 가능해 '생산-유통-소비자'를 이을 수 있다는 특장점이 있다. 사실 RFID는 스마트폰과의 게이트웨이 역할을 하는 중간 통신수단이 있어야 한다.

이에 QR코드가 붙은 광고판을 판매와 연계한 홈플러스의 '지하철 가상매장' 등 사례도 G마켓 등에 이어 유통업계에서 빠르게 확산되고 있다. 영업 사원도 모바일기기를 가지고 다니다가 QR코드만 스캔해 원하는 정보를 고객에게 보여줄 수 있는 시스템이 개발되고 있다. 레스토랑 등에서도 활용이 확대되고 있다.

태그 인식의 장점도 있다. 푸드머스에 적용된 QR코드 리더를 개발한 유니온넷 관계자는 “기존 RFID 최대 취약점은 전도성 있는 철이나 수분이 들어있는 제품”이라면서 “주로 식음료 업체에서 RFID 도입이 어려웠던 것이 사실”이라고 말했다. RFID 태그는 원가가 높은데다 은박지 재질 등에 영향을 받으면 인식률이 낮다. 반면에 QR코드는 반사 재질이 있는 비닐 등에서 인식률이 낮다.

이 때문에 전자제품에 QR코드가 더 적절하다. 최근 삼성전자 등이 QR코드 활용을 늘리고 있는 이유다. 이 같은 장점을 기반으로 기업 정보화 영역에서 QR코드 적용이 어디까지 확장될 지 기대된다.

유효정기자 hjyou@etnews.com