본문 바로가기
Program

히치하이커를 위한 PHP 가이드 ④ : PHP, 어른이 되다

본문

제 1 주 PHP 하십니까?
제 2 주 PHP를 이용한 개발기간의 단축
제 3 주 PHP와 오라클을 이용한 엔터프라이즈 애플리케이션 개발
제 4 주 PHP, 어른이 되다
제 5 주 오라클/PHP 환경의 확장
제 6 주 PHP 5 Data Object (PDO) Abstraction Layer와 오라클
제 7 주 PHP 5, 오라클, 그리고 미래

히치하이커를 위한 PHP 가이드 ④

PHP, 어른이 되다

Philippe Lachaise │프로그래머

PHP가 성숙된 기술로 발전하면서, 이제 스크립트 개발자와 OO(object-oriented) 개발자들이 머리를 맞대고 고민할 때가 되었습니다.

PHP처럼 폭발적인 인기를 얻은 프로그래밍 언어의 예를 찾기란 쉽지 않습니다. DIY (Do-It-Yourself) 방식의 스크립트 언어로 공개되어 각광을 받은 PHP의 사례는, 성공을 위해 반드시 용의주도한 계획과 마케팅이 선행되어야만 하는 것은 아니라는 사실을 반증하고 있습니다. 하지만 과연 PHP가 앞으로도 대규모 IT 환경에서 그 명맥을 이어갈 수 있을 것인지 현 시점에서 질문을 던져보아야 할 것입니다. 사실 오라클과 같은 메이저 벤더가 PHP를 적극적으로 지원하고 있다는 사실 역시, PHP의 성숙도가 일정 수준에 도달했음을 알려주는 증거의 하나로 볼 수 있을 것입니다.

지금까지의 성공은 “우연”에 기인한 바가 큽니다. PHP의 팬들은 마치 PHP가 IT 업계의 “신동”이라도 되는 듯 떠받들고 있습니다. 하지만 이 신동이 자라면서 수염을 기르고 어른의 목소리로 이야기할 때까지 팬들의 환호가 계속될 수 있을까요?

다른 오픈 소스 프로젝트와 마찬가지로, PHP는 IT 업계의 풀뿌리 문화가 주류 테크놀로지로 성장하는 한 과정을 보여주고 있습니다. PHP는 과연 실망스러운 결과로 그 존재를 마감하게 될까요? 아니면 대규모 IT 환경에서 기대되는 요구사항을 만족할 수 있을까요?

두 종류의 프로그래밍 문화에 대해

PHP의 성공 사례는 다양한 배경의 개발자들로부터 관심을 얻고 있습니다. “code-and-run” 스크립팅 방식에 익숙했던 초기의 Rasmus (PHP의 창시자) 추종자들은 이제 UML 기반의 OO(object-oriented) 프로그램 개발자들과 경쟁하기 위해 PHP를 새로운 경지로 끌어올리고 있습니다. 스크립트 개발자 진영과 OO 개발자 진영은 모두 웹 개발에 능숙하며 하나의 강력한 문화를 형성하고 있다는 공통점을 갖고 있습니다. 양쪽 어느 편도 무시할 수는 없는 상황입니다.

PHP 진영은 웹 개발에 대해 어떤 지식을 갖고 있을까요? 그들이 좋아하는 것, 싫어하는 것은 무엇일까요? 우선 그들은 설계에 관한 지식이 풍부합니다. 그들은 때로 의심스러운 수준의 취향을 드러내기도 하지만, 적어도 HTML과 CSS, 그리고 RIA(Rich Internet Application) 테크놀로지에 대해서는 누구보다도 잘 알고 있다고 자부합니다. 그들은 매우 젊고, PHP 포럼에 자주 모습을 드러냅니다. 그들은 “object-oriented”라는 개념에 거부감을 보이기도 합니다. 그들의 관심사는 코드의 유지보수성(maintainability)이 아닌 코드의 렌더링(rendering)에 있습니다.

UML 기반의 OO 개발자 진영은 HTML 코드에 <?php?> 구문을 양념처럼 마구 뿌려대는 관행에 반감을 갖고 있습니다. 그들의 관심사는 애플리케이션 아키텍처, 클래스 레벨의 코드 재사용, 팀워크, 소스 컨트롤과 같은 것들입니다. 그들은 그리 복잡하지 않은 웹 사이트 구성도 하나의 “애플리케이션”으로 간주하며, 잘못된 설계로 인해 데드라인을 놓치거나, 고객을 화나게 하거나, 일자리를 잃게 되는 상황을 두려워합니다.

웹 개발 환경이 마케팅 전략과 경제적 고려사항에 의해 좌우되고 있는 오늘의 현실을 고려한다면, UML 진영의 접근방식이 더 효과적일 것이라고 성급한 판단을 내릴 수도 있을 것입니다. 그렇다면 PHP 개발자들은 멸종 위기에 처한 종족으로 보아야 할까요? 그렇지는 않을 것입니다. 웹이 메인프레임은 물론(3270 터미널을 아직도 기억하는 분 계십니까?), 데스크탑과 비교했을 때에도 전혀 다른 성격을 갖는 매체라는 점을 고려했을 때, PHP 진영의 비조직적인 접근방식이 성공한 이유가 무엇인지 음미해 볼 필요는 있다고 생각됩니다.

먼저 실제적인 문제와, 이에 대한 실제적인 해결방법을 검토해 보기로 합시다.

문화적 격차 좁히기

PHP5가 공개되면서, 이제 PHP 세계에도 OO 개념이 도입되는 시점이 도래했습니다. ZE2 (Zend Engine 2) 프로젝트를 통해 PHP의 코어에 오브젝트의 개념이 구현된 것입니다. PHP5에 새롭게 구성된 언어 구성요소(language construct)는 오브젝트 프로그래밍 스타일을 따르고 있을 뿐 아니라, 언어의 구현 방식 역시 다른 OO 환경과 맥락을 같이 하고 있습니다. 몇 가지 예를 들어 보겠습니다. 오브젝트는 복제되는 대신 참조(reference)를 통해 처리됩니다. 또 Java와 같은 오브젝트 환경에서만 의미를 갖는 새로운 키워드(final, static 등)가 도입되었습니다. delegate와 같은 기능은 개발자로 하여금 오브젝트 디자인 패턴을 사용하도록 유도하고 있습니다 (불과 몇 개월 후에 “레거시 PHP4”라는 표현이 등장할 지도 모를 일입니다). 이러한 PHP의 중대한 변화는, 오늘날 주도적인 프로그래밍 모델로 부상하고 있는 오브젝트 기반의 접근법을 그 기반으로 하고 있습니다. 원하든 원치 않든, 오브젝트 접근법은 복잡한 애플리케이션의 구현에 가장 효과적인 방식으로, 미래의 대세로 인정받고 있습니다. 결국 우리는 서로 다른 문화를 가진 PHP 진영과 OO 진영의 화해를 도모하고, 서로의 장점을 배우도록 유도할 수 밖에 없을 것입니다.

이러한 “화해”가 가능하려면, 프로그래밍 언어가 제공하는 다양한 기능을 희생하지 않는 범위에서 명확한 한계를 정의하기 위한 방법론의 개발 작업이 선행되어야 합니다. 그렇게 함으로써 외딴 “섬”처럼 존재하던 프로그래밍 언어들이 강력한 아키텍처를 기반으로 공존할 수 있게 해야 합니다.

PHP CMS 또는 애플리케이션 프레임워크에 대한 합의가 이루어지지 못하고 있는 현실을 직시할 필요가 있습니다. 개발자들은 어떤 프로젝트든지 기존 시스템을 그대로 활용할 수 있는 경우는 없다고 불평합니다. 사람들은 몇 가지 시스템을 비교 검토하다가, 결국 프레임워크를 직접 개발하는 방향으로 선회하곤 합니다. 도대체 그 이유가 무엇일까요?

데스크탑 환경에서는 운영체제 별로 GUI 설계가 한 번 결정되고 나면 다시 손 볼 일이 없게 됩니다. 하지만 웹은 독창적인 비주얼 디자인을 필요로 하는 플랫폼입니다. 웹 사이트는 이미지를 전달하는 매체로 활용되며, 그 이미지에 따라 기업의 매출이 좌우될 수도 있습니다. 비주얼의 독창성과 브랜드 이미지는 매우 깊은 상관관계를 갖고 있습니다.

또 한 편으로, 사용자의 불편을 최소화하기 위해서는 유연한 로직을 애플리케이션에 구현할 수 있어야 합니다 (데스크탑 사용자에 비해 웹 사용자의 전문성이 떨어진다는 것은 인정해야 합니다).

웹 디자이너는 프로그래머가 직접 구현한 시스템에 적응하느라 애를 먹기도 합니다. 반대로, 디자이너가 잘못 설계한 포탈 프레임워크에 애플리케이션 코드를 꾸겨 넣느라 개발자들이 곤욕을 치르는 경우도 있습니다. 대개의 경우, 그리 만족스럽지 못한 타협으로 마무리가 지어지곤 하는데, 이 경우 어색한 비주얼 효과, 사용성의 제약, 관리성의 제약과 같은 부작용이 남게 됩니다 (이러한 문제들은 PHP 애플리케이션에서만 발견되는 것이 아닙니다.)

이러한 문제를 극복하기 위해서는, 웹 디자이너와 OO 개발자가 서로에게 방해가 되지 않으면서 효과적으로 협력할 수 있는 방안을 강구해야 합니다. 다른 그룹의 선례로부터 배움을 얻는 것이 아마도 가장 좋은 방법이 될 것입니다.

“장인제도”에서 하나의 “산업”으로

위에서 제기한 문제를 잠시 접어두고 현재의 상황을 살펴보기로 합시다. PHP의 과거 역사를 돌아보고, “Enhanced HTML” 개발 진영의 사례에 대해 논의해 보겠습니다.

이들이 사용하는 툴은 “Pure HTML” 개발 진영에서 사용하는 것과 크게 다르지 않습니다. 사용편의성 면에서 뛰어난 HTML 에디터와, 프로젝트 관리 툴, 그리고 PHP, ASP, JavaScript 등의 통합을 위한 툴 정도면 충분합니다.

우선적으로 코드 문제에 대해 생각해 봅시다. 이들이 작성한 웹 페이지를 보면서 제일 먼저 눈에 들어오는 사실은, 이처럼 다양한 툴을 사용해서 생성한 웹사이트의 외양이 대부분의 경우 믿기 어려울 만큼 멋지다는 것입니다. 이것은 단순한 테크닉의 문제가 아니라 “재능”의 문제입니다. 웹 디자이너들은 매우 긍정적이고 감성적인 효과를 활용하여 방문자들이 편안함을 느낄 수 있는 비주얼 환경을 창조해 냅니다.

하지만 OO 개념에 익숙한 개발자의 눈으로 바라보았을 때 상황은 180도 달라집니다. 작성된 코드를 훑어보니 나중의 문제를 고려하지 않은 “한탕주의”식의 코드에 불과합니다. 대부분의 경우가 그러합니다.

그렇다면 이것은 과연 문제일까요? 나중에 웹 사이트를 부분적으로, 또는 전체적으로 헐어내고 처음부터 다시 꾸미는 것이 문제가 될 수 있을까요? 아마 그렇지 않을 것입니다. 매장의 인테리어도 완전하게 새로 단장하는 경우가 허다합니다. “쇼 윈도우”로서의 웹 사이트만을 고려한다면, 이와 같은 막무가내식의 PHP 프로그래밍 방식도 문제될 것은 없습니다. PHP 언어를 이용하면, 방문자의 눈길을 사로잡는 다양한 시각적 효과를 만들어낼 수 있습니다. 여기에서 굳이 오브젝트 방법론을 거론할 필요는 없습니다.

하지만 애플리케이션 로직이 수반되는 환경에서라면 관점이 완전히 달라집니다. 웹 사이트에 정기적으로 방문하는 사용자들을 위한 마케팅 정보를 수집하기 위해 몇 가지 폼(form)을 구현하는 경우를 생각해 봅시다. 수집된 정보의 정확성을 보장하기 위해서는 검증 코드(validation code)를 삽입하는 것이 바람직할 것입니다. 또 악성 스크립트 또는 악성 SQL 구문의 침입을 방지하기 위한 대책을 마련할 필요가 있습니다. OTN 회원 여러분들이라면 데이타베이스의 개념에도 어느 정도 친숙할 것입니다. 수집된 정보는 DB 테이블에 저장되며, PHP 코드는 DB의 스키마를 반영하는 SELECT 구문을 실행하여 정보를 가져옵니다. 그렇다면 웹 사이트는 비즈니스 인프라스트럭처를 기반으로 하는 완전한 형태의 “애플리케이션”으로 보아야 할 것입니다.

이 문제도 잠시 접어 두기로 합시다. 하드 코딩된 링크, 부적절한 타입 컨버전, 보안 문제를 안고 있는 웹 사이트로부터 눈을 돌려, “PHP OO” 애플리케이션에 대해 다시 한 번 이야기해 봅시다. 숙련된 웹 디자이너조차도 이 영역에는 친숙하지 않을 뿐더러 더 나아가 적대감을 표시하기도 합니다. 이 환경에서는 “장인정신”이 통하지 않습니다. 웹 개발은 이제 하나의 “산업”으로 자리를 잡고 있습니다. 이 영역에서 한 자리를 차지하려면, 클래스, 상속, 데이타 추상화, 코드 인캡슐레이션과 같은 개념에 친숙해져야만 합니다.

이제 규칙이 필요합니다. 코딩 규칙은 준수되어야 합니다. 소스 파일은 버전/소스 관리 시스템에 의해 관리되어야 합니다. 파일은 계층화된 구조를 통해 엄격하게 조직되고 관리되어야 합니다. 위험한 코딩 트릭은 배제되어야 합니다. 코드는 읽기 쉬워야 하며, 코멘트로 처리되어야 합니다.

지루하다고요? 하지만 효율적입니다. 이제 웹 애플리케이션을 구현할 단계입니다. 인트라넷, 전자상거래 웹 사이트, e-마켓플레이스와 같은 환경에서 설계 상의 문제는 비즈니스의 성패를 좌우할 수도 있습니다. 간단하게 말한다면, 이제부터 우리는 “복잡성”의 문제와 싸워야 합니다.

프로젝트 관리자들은 단순히 PHP를 “사랑한다”는 이유로 PHP를 선택하지 않습니다. 그들이 PHP OO를 선택하는 것은, PHP가 벤더 솔루션의 훌륭한 대안인 동시에 무료로 제공되기 때문입니다.

앞으로 어떻게 될 것인가?

그렇다면 C++와 Java에 익숙한 이들이 제창한 방법론을 PHP 환경에 도입함으로써 어떤 효과를 기대할 수 있을까요?

PHP5는 기존의 관행을 파괴하는 언어가 될 것입니다. 그렇기 때문에 아직 속단하기에는 이릅니다. 일부 개발자들은 OO 방법론을 부분적으로 도입하려 시도할 것이고, 또 일부는 OO의 세계를 처음으로 접하고 “개종”하려 할 것입니다. 또 어떤 이들은 막연히 좋았던 옛 시절이 계속되기를 기대하면서 과거의 관행을 고집할 것입니다.

실제 사례

이제 다시 기본으로 돌아가, 기술적인 관점에서 변화를 모색하기 위한 단순하고도 효과적인 솔루션이 무엇인지 생각해 보기로 합시다. 간단한 프로그래밍 “규칙(convention)”을 적용하는 것만으로도 코딩 작업을 효율화하고 애플리케이션의 확장성을 개선할 수 있습니다.

명명 규칙(naming convention)은 가장 적용하기 쉬운 방법입니다. (PEAR와 같은) 코드 라이브러리를 주로 사용하는 개발자라면, 자신만의 명명 규칙을 개발하는 것이 좋습니다. Simplified Hungarian Notation (헝가리인 Chargles Symonyi가 처음으로 제안하면서 붙여진 이름입니다)은 느슨한 타이핑 (loose typing) 요구사항을 갖는 환경에 적합합니다. 또 클래스 멤버에 사용하는 접두사(prefix)를 underscore(_)로 연결하는 방법이 바람직합니다. 또, 클래스 외부에서 호출될 수 없는 메소드에 대해서는 별도의 접두사(예: impl_)를 적용하는 것도 좋은 방법입니다.

어떤 명명 규칙을 사용하든 간에, 코드를 읽기 쉽고 명확하게 작성하는 것이 중요합니다. 숙련된 개발자는 마치 초상화에 찍힌 얼룩을 발견해 내듯, 잘 작성된 코드에서 코딩 에러를 집어 낼 수 있을 것입니다.

또 명명 규칙을 적용할 때 주의해야 할 사항은, 코드의 광범위한 재활용이 가능하려면 이름 간의 충돌(name conflict)이 발생할 가능성을 최소화해야 한다는 것입니다. 오브젝트의 이름을 짓는 개발자들의 상상력에도 한계가 있습니다. 예를 들어 Page 클래스가 몇 가지 있는데, 개발자 자신도 모르는 사이에 전혀 다른 기능을 갖는 두 가지 클래스에 똑같은 이름을 부여할 수도 있습니다. 운이 나쁜 경우입니다. 뒤늦게 클래스의 이름을 바꾸려 하면 코드 유지보수 문제가 걸림돌이 됩니다. 그러므로 애초에 이런 문제를 원천적으로 차단하는 것이 중요합니다. 그렇다고 GUID (“_16B280C5_EE70_11D1_9066_00C04FD9189D_Page”!)를 사용하는 방법은 좀 지나친 감이 있습니다. 모양도 보기 좋지 않고 PHP의 기본 정신에 위배되는 일입니다.

클래스 이름 간의 충돌을 방지하는 가장 간단한 방법은, 클래스의 특성을 나타내는 여러 단어들을 이름에 사용하는 것입니다 (예: GalleryPage). 그런 다음, Java 개발자들이 사용하는 방법 대로 도메인 명을 접두사로 사용함으로써, 충돌의 가능성을 최소화할 수 있습니다. (예: com_mydomain_GalleryPage).

돈 한 푼 안들이고 여러분의 일자리를 보존할 수 있는 또 한 가지 중요한 프로그래밍 습관이 있습니다. 자주 사용되는 “atomic”한 구문들을 별도의 채널을 통해 관리하는 것입니다. 예를 들어, "echo” 구문은 전체 애플리케이션에서 단 한 번만 구현되어야 하며, 하나의 함수(또는 클래스 메소드) 내에서만 구현되어야 합니다. 이와 같이 함으로써, “echo” 명령을 사용하여 사전처리(preprocess) 또는 리다이렉트(redirect)되어야 하는 기능이 있는 경우에도 많은 수의 파일을 검색하고 편집하는 수고를 거치지 않고 몇 줄의 코드만으로 목적을 달성할 수 있게 됩니다.

에러 핸들링은 C++만큼 엄격하게 적용될 필요는 없습니다 (C++의 경우에는 포인터 문제 또는 버퍼 오버플로우 문제 등으로 인해 심각한 결과가 초래될 수도 있습니다). 데이타 무결성 면에서 문제가 될 것이 없다면, 사용자에게 “문제가 있었으니 다시 한 번 시도하라”는 메시지를 던져 주는 것만으로 충분할 수도 있습니다. set_error_handler() 함수는 매우 유용한 기능입니다. 이 함수를 이용하여 “atomic”한 이벤트들을 한 장소에서 중앙집중적으로 관리하고, 에러 핸들링을 전담하는 코드를 구현할 수 있습니다. 발생한 모든 문제들을 로그에 기록하여 관리하고자 하는 경우에도 이 함수를 활용할 수 있습니다.

코딩 문제에 관련한 논의를 마무리하면서, 마지막으로 중요한 팁 하나를 더 드리고자 합니다. PHP5에서는 오브젝트 레퍼런스(object reference)를 할당 또는 전달하는 방식을 디폴트로 사용합니다 (여기서 “레퍼런스”란 오브젝트의 “핸들(handle)”을 의미하며, 오브젝트 자체 또는 오브젝트의 복사본을 의미하지 않습니다). PHP4 환경에서는, 오브젝트를 전달하는 과정에서 주의를 기울이지 않으면 예상치 못한 문제가 발생할 수 있습니다. 한 예로, 아래 코드는 $obj1를 $obj2에 복사합니다 (여기까지는 문제될 것이 없습니다).

$obj2=$obj1;

별도로 명시하지 않은 경우, 함수는 복사본을 취하고, 복사본을 반환합니다. 아래 코드의 버그는 찾기도 쉽지 않습니다:

class ObjectKeeper { var $_obj; // Whatever object is function & get_object() { return $this->_obj; } } A reference is returned-fine. Now comes the trap: $keeper=new ObjectKeeper(); $obj1=$keeper->get_object(); $obj1->modify(); $obj2=$keeper->get_object(); // Ask new reference to same object if ($obj2->is_modified()) { echo 'OK'; // this will NEVER print }

올바르게 수정된 구문이 아래와 같습니다 ("=" 기호 대신 "=&" 기호가 사용되었음을 주목하시기 바랍니다):

$obj1=&$keeper->get_object(); // Notice "=&" instead of "="

"=&” 기호를 사용하지 않는 경우, $obj1에는 반환된 레퍼런스가 참조하는 오브젝트의 “복사본”이 할당됩니다. 따라서 어떤 작업을 수행하든, 기존 오브젝트에는 아무런 변화도 발생하지 않게 됩니다. 다시 말해, 모든 업데이트는 소실되어 버리고 맙니다.

웹 디자이너의 문화와 프로그래머의 문화 사이에 존재하는 간극을 좁히는데 템플릿(template)이 큰 역할을 하게 될 수도 있습니다. 템플릿은 고정된 레이아웃(주로 HTML 코드)을 통해 모든 기능을 구현하며, 템플릿 엔진은 페이지가 생성되는 과정에서 컨텐트를 자동으로 구현합니다. 대부분의 템플릿 엔진은 캐싱 메커니즘(caching mechanism)을 구현하고 있으므로, 데이타 소스가 대량으로 업데이트되는 상황을 제외하고는 성능적인 오버헤드가 발생하지 않습니다.

템플릿 엔진은 레이아웃/그래픽과 비즈니스 로직의 합리적인 구분을 가능하게 합니다. 가장 널리 사용되는 템플릿 엔진으로 Smarty를 들 수 있습니다. Smarty는 다양한 오픈소스 CMS 및 프레임워크 프로젝트와 통합된 기능을 제공합니다.

하지만 기본적인 검색/업데이트(search-and-replace) 수준을 벗어나는 로직을 구현해야 하는 경우에는 템플릿의 활용이 제한될 수 밖에 없습니다. 이러한 점에서 볼 때, 미래에는 XSLT 테크놀로지가 중요한 역할을 담당하게 될 것입니다. 또 PHP5에 포함된 XML 지원 기능 역시 많은 변화를 가져올 것으로 기대됩니다.

마지막으로 아주 중요한 문제를 짚어 보려 합니다. 바로 라이브러리의 코드를 재활용하는 문제입니다. 이 문서에서는 논의의 범위를 PEAR에 한정하기로 합니다 (PEAR는 표준 PHP 배포판에 포함된 형태로 제공되고 있습니다).

PEAR는 이제 표준 PHP 소프트웨어 컴포넌트의 하나로 인정받기 시작하고 있습니다. 엄격한 선정작업과 품질 표준을 적용한 결과, PEAR의 컴포넌트는 벤더 툴에서 제공되는 것만큼이나 뛰어난 수준을 제공하게 되었습니다. 또 PEAR가 제공하는 버전 규칙(versioning convention)을 이용하여, 애플리케이션에 가장 적합한 버전을 선택할 수 있습니다. PEAR는 폼 핸들링(form handling), 데이타베이스 추상화 계층(PEAR::DB)에서 Web Service, WebDAV 지원에 이르기까지 다양하고 풍부한 기능을 제공하고 있습니다.

굳이 말할 필요도 없는 문제겠지만, PEAR를 포함하는 PHP 코드 라이브러리에 친숙해지려면 마음 잡고 며칠을 투자해야 할 것입니다.

PHP5의 미래

PHP는 Linux, Apache와 함께 가장 중요한 오픈 소스 성공 사례로 자리매김하였습니다. 많은 결점에도 불구하고, PHP는 IT 업계에 단단히 뿌리를 내렸으며, 많은 사용자들이 PHP를 활용하고 있습니다.

PHP5는 “헤비급” 웹 애플리케이션의 개발을 촉진하는 효과를 가져올 것입니다. 더 많은 비즈니스 로직과, 더 많은 데이타베이스 관련 기능이 PHP 코드를 통해 구현될 것입니다. 또 한편으로, “Agile Coding” 방법론을 이용한 XML 테크놀로지의 활용 사례가 늘면서 웹 디자이너와 개발자, 소프트웨어 설계담당자가 함께 공존할 수 있는 환경이 마련될 것입니다.

새로운 세대의, 매력적이고 편리한 PHP 기반 웹 애플리케이션의 출현을 기대하십시오.

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

[이 게시물은 듀라님에 의해 2015-04-03 10:08:13 워드프레스에서 이동 됨]
[이 게시물은 듀라님에 의해 2015-04-03 10:27:24 Public에서 이동 됨]
[이 게시물은 듀라님에 의해 2015-04-03 10:33:53 팁과강좌에서 이동 됨]
[이 게시물은 최고관리자님에 의해 2017-06-10 14:26:42 PHP에서 이동 됨]
0 0
  • 페이스북으로 보내기
  • 트위터로 보내기
  • 구글플러스로 보내기
  • 카카오톡으로 보내기

페이지 정보

l2j (121.♡.101.20) 작성일07-05-02 15:39 조회1,300회 댓글0건

댓글목록

등록된 댓글이 없습니다.

Program 목록

게시물 검색

사이트 정보

  • 회사명 회사명 / 대표 대표자명
  • 주소 OO도 OO시 OO구 OO동 123-45
  • 사업자 등록번호 123-45-67890
  • 전화 02-123-4567 / 팩스 02-123-4568
  • 통신판매업신고번호 제 OO구 - 123호
  • 개인정보관리책임자 정보책임자명

고객센터

  • 02-1234-5678
  • abc@abc.com
  • 월-금 am 11:00 - pm 05:00
  • 점심시간 : am 12:00 - pm 01:00
  • 주말&공휴일은 1:1문의하기를 이용하세요.
상단으로