출처 : http://www.nice2seeyou.com/zbxe/?mid=info&page=5&document_srl=6372
PHP 클래스를 사용하려면 알아야할 7가지를 정리한 내용을 찾았습니다.
목차
1. 클래스 정의 ( 형식 class Cart { 멤버 변수와 메서드 생성 } )
2. 객체 생성 ( 형식 new 키워드 사용 $cart = new Cart; $cart(클래스)->(지정연산자)add_item;
3. 클래스 상속 ( 형식 class Named_Cart extends Cart(부모클래스) { 부모클래스의 멤버 사용가능 )
4. 생성자 ( 형식 class Cart { function Auto_Cart () { 자동적으로 호출되는 클래스 내의 함수 )
5. 범위연산자 ( 형식 Cart::Auto_Cart (); new키워드 없이 클래스의 멤버를 사용할때 )
6. 부모키워드 ( 형식 parent::example(); 자식클래스에서 부모클래스 멤버를 사용할때 )
7. 매직함수 ( 형식 __sleep, __wakeup과 같이 "__"로 시작, 아래 내용 참조 )
1. 클라스 정의 |
클래스란? 클래스는 객체의 변수와 함수를 정의하는 템플릿이며, 이에 따라 변수로 표현되는 데이터 영역과 이러한 데이터 영역에 접근할 수 있는 함수로 구성됩니다. 클래스 내에 정의된 변수를 멤버변수(member variable)라고 하고 함수를 메쏘드(method)라고 합니다. C++과 같은 객체지향언어에서는 멤버변수를 데이터멤버, 메쏘드를 멤버함수라고 호칭합니다. PHP에서 클래스를 사용하는 것은 C++ 또는 자바와 거의 비슷합니다. 클래스 정의 클래스를 정의(class definition)할 때는 키워드 "class"를 사용합니다. 클래스를 구성하는 멤버변수와 메쏘드를 정의할 때는 "var"과 "function"이라는 키워드를 사용합니다. "function"은 일반 함수를 정의할 때도 사용되지만 "var"은 클래스의 멤버변수를 정의할 때만 사용되는 키워드로, 멤버변수를 정의할 때는 반드시 명시하여야 합니다. 예를 들어 클래스는 아래와 같이 정의합니다. 이 예는 PHP 매뉴얼에 있는 것으로 수정하지 않고 가져왔습니다. 이 예에서는 $items라는 멤버변수와 add_item, remove_item라는 메쏘드가 정의되어 있습니다.
멤버변수의 초기화 PHP에서는 멤버변수값을 아래와 같이 상수 또는 변수를 이용하여 초기화할 수 있습니다.
반면 PHP4에서는 var 변수에는 상수로만 초기화할 수 있고, 상수가 아닌 값을 가지고 초기화할 때는 생성자를 이용하여야 합니다. 즉, var $items = $GLOBALS["items"];와 같은 표현은 허용하지 않습니다. 따라서 아래와 같은 표현은 PHP4에서는 허용하지 않습니다.
PHP4에서 초기화할 때 동일한 결과를 얻으려면 아래와 같이 생성자를 이용합니다.
PHP4 예약어 stdClass stdClass는 Zend에서 내부적으로 사용하고 있는 예약어입니다. 따라서 사용자는 클래스명으로 stdClass를 사용할 수 없습니다. get_declared_classes() 함수를 사용하면 현재 스크립트에 정의된 클래스명을 배열에 담아 되돌려 줍니다. 따라서 이 함수를 이용하면 stdClass의 존재를 확인할 수 있습니다.
이 문서를 실행하면 아래와 같은 결과를 얻을 수 있습니다.
위 예제의 실행결과를 보면, 사용자가 정의한 vegetable, spinach 외에도 stdClass, OverloadedTestClass, Directory, OCI-Lob가 있는 것을 볼 수 있습니다. 좀 더 자세한 것은 메뉴 "클래스&객체 함수 >> get_declared_classes()"를 살펴보시기 바랍니다. 매직함수(magic function) __sleep, __wakeup과 같이 "__"로 시작하는 매직함수는 PHP 클래스 내에서 특수한 목적으로 사용됩니다. 따라서 이 함수들이 가지고 있는 문서화된 매직 기능을 사용할 필요가 없다면 클래스 내에 이 함수들을 정의해서는 안됩니다. 자세한 것은 메뉴에서 "매직함수"장을 살펴보기 바랍니다. $this가 무엇에 쓰는 물건인고? 클래스 메쏘드 내에서만 사용되며, 클래스의 현재 인스턴스를 참조할 때 사용하는 변수이며, 예를 들어 현재 객체 내에 something라고 명명된 임의의 변수 또는 함수를 참조하기 위해서는 $this->something을 사용하여야 합니다. 즉, "$this"의 의미는 new 연산자에 의해 생성될 객체 자신을 의미합니다. 그러니 아직 생성되지 않은 객체 자신을 의미하는 의사(擬似)변수(pseudo variable)이며, "my own" 또는 "current object"라고 불리웁니다. 앞에서 클래스를 붕어빵 틀과 같다고 했습니다. 정의된 클래스에 의해 생성된 객체는 붕어빵 틀로 만들어낸 수많은 붕어빵이지요. 아래 예에서 본다면, $붕어빵1->make("특급밀가루")으로 make() 메쏘드에 접근한다면 이 때 make() 메쏘드 내의 $this는 $붕어빵1을 의미하고, $붕어빵2->make("중급밀가루")으로 접근한다면 이 때 $this는 $붕어빵2를 의미하고, $붕어빵3->make("저급밀가루")으로 접근한다면 이 때 $this는 $붕어빵3을 의미합니다.
|
2. 객체 생성 |
객체 생성=객체 초기화(object initialization)=인스턴스화(instantiation) 클래스는 붕어빵을 만드는 틀(= type, =template)과 같은 것으로, 클래스 내에 정의된 메쏘드와 멤버변수를 사용하기 위해서는 틀을 가지고 붕어빵을 만드는 것같이 객체를 생성하여야 합니다. 객체(object)를 초기화하는 방법은 new 연산자를 사용하여 객체를 변수에 인스턴스 시키는 것입니다.
위와 같이 하면 클래스 Cart에 대한 객체 $cart가 생성됩니다. 객체 함수 add_item()은 장바구니에 품목번호 "10"의 수량을 1개 추가하기 위해 호출됩니다. 지정연산자 "->"의 의미 "->"는 객체의 멤버변수 또는 메쏘드를 지정하는데 사용되는 지정연산자입니다. C++ 언어를 접해 본 분은 쉽게 이해하시겠지만, new 연산자로 생성되는 객체를 나타내는 객체명에는 실제로 객체의 멤버(변수 또는 함수)가 존재하는 것이 아니라 객체의 멤버가 존재하는 메모리상에 위치를 나타내는 주소(adress)가 담겨져 있습니다. 이와 같이 객체지향언어에서는 주소를 가지고 멤버를 참조하려면 아래와 같이 지정연산자 "->"를 이용하게 됩니다.
C++ 언어에서는 "->"를 화살표 멤버 연산자라고 말하며, "->"의 앞쪽에 있는 식별자(여기서는 객체명)가 포인터(pointer; 주소를 의미함)일 때 그 멤버를 참조하기 위한 연산자입니다. 지역 변수에 초기화된 객체 객체를 지역변수에 인스턴스할 수 있기 때문에, 클래스를 정의하고 객체를 생성하는 것을 하나의 모듈로 개발할 수 있습니다.
객체 생성할 때 생성자명을 가변함수로 지정하기
이 코드는 PHP와 PHP4 모두에서 정상적으로 동작합니다. 메쏘드명을 변경하기(가변함수) PHP의 매뉴얼을 보면 가변함수(variable function)를 지원하는데 이것은 변수명 뒤에 괄호가 왔을 때, PHP는 그 이름을 가진 함수를 찾아 실행하는 것입니다. 이것은 클래스의 메쏘드에서도 그대로 사용할 수 있습니다.
이것을 응용하여 같은 실행문으로 A0, A1, A2라는 메쏘드에 번갈아 가면서 접근하려면 역시 가변함수를 사용하면 됩니다.
위에 것은 모두 PHP3와 PHP4에서 모두 동작되는 코드입니다. 만약, PHP4에서만 동작시켜도 무방하다면 아래와 같이 중괄호를 이용하면 소스를 간결하게 코딩할 수 있습니다.
객체명을 변경하기(가변변수) 가변변수(Variable Variables)의 유용함은 모두 알고 있겠지만 PHP4에서는 별문제가 없지만 PHP에서 객체변수를 가변변수로 사용하기는 그리 쉽지 않습니다.
PHP에서 위와 같이 작성하여 실행한다면,
와 같은 에러를 만나게 됩니다. 그러나 PHP4에서는 객체변수에도 가변변수를 제대로 지원하기 시작했습니다. 따라서 위의 예제가 에러없이 잘 실행되지요. 그러면 PHP에서는 객체변수의 이름을 변경할 수 없을까요? 아래와 같이 $GLOBALS 배열을 사용해 보세요. 아무 문제없이 잘 실행될 겁니다.
따라서 PHP3와 PHP4 모두에서 동작되기를 바란다면 $GLOBALS 배열을 이용하여 작성하세요. 배열구조의 멤버변수를 가변변수로 다루는 방법
위와 같이 클래스 test에 배열 구조의 멤버변수가 있을 때, 이러한 멤버변수의 배열 요소에 접근하려면 $obj->arr[0]; 와 같이 사용하면 됩니다. 여기서 멤버변수명 "arr"을 가변변수로 처리하려면,
와 같이 가변변수 $prop를 중괄호로 묶어주세요. 여기서 겹따옴표는 생략해도 됩니다. PHP3와 PHP4에서 모두 잘 동작할 것입니다. |
3. 클래스 상속 |
클래스를 상속하려면? 기존에 이미 작성된 클래스를 상속(class inheritance)받으면 이미 작성된 메쏘드와 멤버변수를 그대로 이어받게 됩니다. 상속받은 특성에 덧붙여 새로운 특성을 추가하는 방법으로 새로운 클래스를 정의하게 됩니다. 이와 같이 기존의 클래스로부터 특성을 이어받는 것을 상속이라고 합니다. 이 때 확장된 클래스를 정의하기 위해 "extends"라는 키워드를 사용합니다. 부모클래스 & 자식클래스에 관련된 용어 기존의 클래스와 확장된 클래스를 나타내는 용어는 객체지향언어마다 다양하게 사용되고 있습니다. 그러나 어떤 용어를 사용하더라도 같은 의미로 사용되고 있다고 이해하시면 됩니다.
클래스 상속 예제
클래스 Named_Cart는 클래스 Cart의 모든 변수와 함수를 그대로 상속받게 되며, 새로운 멤버인 변수 $owner과 함수 set_owner()를 추가하여 정의합니다. 앞서 배운 new 연산자를 이용하여 클래스 Named_Cart의 객체를 생성한 후 장바구니 주인을 지정하거나 주인이 누구인지 확인할 수 있습니다. 아울러 부모클래스 Cart에 있는 장바구니 관련 함수를 그대로 사용할 수 있습니다.
단일 상속 PHP는 다중 상속(multiple inheritance)를 지원하지 않으며, 오로지 단일 상속만 지원합니다. |
4. 생성자 |
생성자란? 생성자(constructor)는 클래스의 새로운 인스턴스가 생성될 때 자동적으로 호출되는 클래스 내의 함수이며, 클래스명과 동일한 이름를 갖는 특수한 메쏘드입니다.
위의 예제는 클래스 Auto_Cart가 new 연산자로 만들어질 때마다 품목번호 "10"의 수량이 1을 갖도록 장바구니를 초기화시키는 생성자를 새로이 포함하여 정의하였습니다. 생성자에 전달되는 인자 생성자는 필요하면 선택적으로 인자(argument)를 전달할 수도 있기 때문에 매우 유용하게 사용됩니다.
PHP3와 PHP4 생성자 사이에 발생하는 미묘한 차이 PHP에서는 클래스와 동일한 이름을 가진 함수를 생성자로 처리하고 있습니다. 따라서 아래와 같은 경우에 클래스 B의 이름과 동일한 이름의 함수 B()가 없으므로 객체를 생성할 때 실행할 생성자가 없습니다.
그러나 만약 아래와 같이 클래스 A에 함수 B()가 정의되어 있다면 설사 클래스 B를 가지고 객체를 생성하더라도 클래스 A에 있는 일반함수 B()를 클래스 B의 생성자로 인식합니다. 즉, PHP에서는 함수 B()가 클래스 B에 속해 있는지 아니면 부모 클래스로부터 상속된 함수인지를 인식하지 못합니다. 따라서 객체 $b를 생성할 때 클래스 A에 있는 일반함수 B()를 생성자로써 실행하게 되는 것이지요.
클래스 B에 속하지도 않은, 부모클래스로부터 상속된 일반 함수 B()를 클래스 B의 생성자로 인식한다는 것은 대부분 우리가 전혀 의도하지 않는 일로 잘못하다가는 원치않는 결과를 초래할 수도 있습니다. 객체지향언어에서 말하는 생성자의 구분이 모호해 진다는 것이지요. 이러한 문제를 PHP4에서는 바로 잡았습니다. 단지 이름만 같다고 생성자로 처리하는 것이 아니라 반드시 해당 클래스 내에 포함되어 있는 것만 생성자로 처리하도록 수정하였습니다. 따라서 위의 예를 PHP4에서 수행한다면 클래스 A에 속한 일반함수 B()를 생성자로써 실행하지는 않습니다. 대신에 PHP4에서는 생성자와 관련하여 새로운 기능이 추가되었습니다. 파생클래스에서 생성자가 정의되어 있지 않으면 그 부모 클래스에 정의된 생성자가 실행하도록 수정되었습니다. 즉, 위의 예에서보면 객체 $b를 생성할 때 클래스 B에 해당하는 생성자 B() 함수가 정의되어 있지 않으므로 그 부모 클래스의 생성자인 A()가 생성자로 수행됩니다. 이러한 PHP3와 PHP4 사이의 미묘한 차이를 명확히 구분하지 못한 상태에서 생성자를 다루게 되면 프로그램이 매우 심각한 오류에 빠질 수 있다는 것을 참고하시기 바랍니다. ***** 주의 ***** PHP4에서의 개선내용은 http://www.php.net/manual/en/language.oop.constructor.php에서 문서화된 내용입니다만 실제로 PHP4는 이 문서와 같이 동작하지 않는 것으로 보고되고 있습니다(아래 주소 참조할 것). http://www.phpbuilder.com/lists/php-documentation-list/2003031/0100.php 이러한 문제로 인하여 2003년 2월 17일 bugs.php.net에 공식적으로 버그리포팅되어 있습니다. http://bugs.php.net/bug.php?id=22253 2003년 2월 17일 당시에는 PHP 버전 4.3.1이 공개된 시점으로 이 이후 버전에서도 이 버그는 개선되지 않고 있습니다. 위에서 언급한 www.phpbuilder.com에 의하면 PHP3와 php4가 동일하게 동작하며, 단지 PHP5에서만 개선된 내용대로 동작하고 있음을 알 수 있습니다. |
5. 범위연산자 |
범위연산자란? PHP4에서만 지원되며 클래스와 메쏘드 또는 클래스와 멤버변수를 연결시켜 주는 일로 범위연산자(scope resolver) 뒤에 나오는 메쏘드와 멤버변수의 스코프(사용범위)를 지정하는 일을 하는 것입니다.
범위연산자 사용목적
인스턴스되지 않은 클래스에 있는 메쏘드에 접근할 때
아직 클래스 A에 대한 객체가 생성되기 전이지만 범위연산자를 이용하면 일반 함수처럼 실행시킬 수 있습니다. 그러나 클래스 A에 대한 객체가 전혀 생성되어 있지 않으므로 클래스 외부에서 이 함수에 접근할 때는 이 함수 내에 $this 객체를 사용해서는 안됩니다. 물론 일반 함수와 마찬가지로 지역 변수 및 전역 변수를 사용할 수는 있습니다.
위의 예제를 보면 아직 클래스 A에 대한 객체가 생성되지 않았으므로 멤버변수 $var에 대한 기억장소가 할당되지도 않았고 더구나 초기값을 설정할 수도 없습니다. 그러니 아무리 범위연산자를 이용하여 메쏘드 example()에 접근한다해도 멤버변수 $var의 초기값을 나타낼 수는 없을 것입니다. 실험해 본 바로는 이 경우 $this->var의 값이 NULL로 처리되는 것 같습니다. 부모클래스의 메쏘드에 접근할 때
이 예의 출력결과를 보면 아래와 같이 나타날 것입니다.
범위연산자는 클래스가 상속되었을 때 재정의되기 전의 부모클래스에 있는 메쏘드에 접근할 때 유용하게 사용될 수 있습니다. 부모클래스의 멤버변수에 접근할 때 php.net의 문서 설명과는 달리 아직 공개되지 않는 어떤 방법이 있는 지는 모르겠으나 부모클래스의 멤버변수로 접근하는 방법에 대하여는 문서화되지 않은 것 같습니다. |
6. 부모키워드 |
부모클래스의 메쏘드 호출 보통 부모클래스에서 선언된 메쏘드를 자식클래스에서 재정의하는 이유는 크게 두가지가 있습니다.
첫번째 기능은 부모클래스의 메쏘드를 무시하고 메쏘드에 새로운 정의를 함으로써 부모클래스의 메쏘드 정의를 숨기는 것입니다. 그러나 때로는 부모클래스의 메쏘드를 모두 지우는 것보다는 추가적인 기능이 필요한 경우가 있습니다. 이같은 경우에는 부모클래스의 메쏘드와 자식클래스에서 재정의된 메쏘드를 모두 수행하게 될 것입니다. 즉, 재정의된 메쏘드 구문 내에서 부모클래스의 메쏘드를 호출할 수 있어야 하며 필요한 기능만 추가적으로 작성하면 될 것입니다. 이럴 때 부모클래스의 메쏘드를 호출하기 위해서 사용하는 키워드가 parent입니다. 자바에서의 키워드 super와 같은 역할을 하며 이것은 그 메쏘드 호출을 상위클래스로 전달합니다. 부모키워드 parent는 $this 키워드와 비슷하게 이 클래스의 부모클래스를 나타내는 위치 지정자입니다. 현재 클래스의 부모클래스를 참조해야 되는 경우에는 부모키워드 parent를 사용할 수 있습니다.
이 예의 출력결과를 보면 아래와 같이 나타날 것입니다.
앞장 범위연산자에서 설명한 대로 키워드 parent 대신에 extends 다음에 기술된 부모클래스명을 직접 사용해도 됩니다.
키워드 parent를 써야 될 이유 위의 예에서 부모클래스를 A가 아닌 A1으로부터 상속받도록 수정하여야 한다면 아래와 같이 extends 다음에 있는 부모클래스명을 변경하는 것으로 모든 작업은 끝나게 됩니다. 만약 parent::example()가 아닌 A::example()라고 작성하였었다면 이 부분도 A1::example()라고 수정하여야 할 것입니다. 결국 수정할 때 손이 더 많이 가야 하는 것이지요. 그러니 부모클래스에 있는 메쏘드에 접근하는 경우라면 키워드 parent를 이용하는 것이 소스 코드를 관리하는데 훨씬 유리할 것입니다.
|
7 매직함수 |
__sleep, __wakeup과 같이 "__"로 시작하는 매직함수(magic function)는 PHP 클래스 내에서 특수한 목적으로 사용됩니다. 따라서 이 함수들이 가지고 있는 문서화된 매직 기능을 사용할 필요가 없다면 클래스 내에 이 함수들을 정의해서는 안됩니다. __sleep serialize 함수를 통해 객체를 직렬화할 때 해당 클래스에 매직 함수 __sleep가 정의되어 있는지 확인합니다. 만약 정의되어 있다면 객체를 직렬화하기 전에 __sleep 함수를 수행합니다. 이 함수는 직렬화하기 전에 객체 멤버에 대하여 조작해야 하는 작업, 또는 직렬화하기 전에 미리 수행해야 하는 작업(예를 들어 데이터베이스 연결 종료 등)을 수행할 수 있습니다. __sleep 함수는 직렬화할 객체의 모든 멤버변수의 이름을 변수에 담아 반환합니다.
__wakeup unserialize 함수를 통해 문자열을 객체화할 때 해당 클래스에 매직 함수 __wakeup가 정의되어 있는지 확인합니다. 만약 정의되어 있다면 객체화하기 전에 __wakeup 함수를 수행합니다. 이 함수를 수행할 때 객체화하기 전에 객체를 상대로 수행해야하는 작업, 또는 객체화하기 전에 미리 수행해야 하는 작업(예를 들어 데이터베이스 연결 등)을 수행할 수 있습니다.
|
로그인에서 사용하는 세션샘플 (0) | 2012.08.12 |
---|---|
jqGrid 입력,수정,삭제 기능구현 2 (0) | 2012.07.21 |
jqGrid 셀렉트+검색+페이징 구현1 (0) | 2012.07.06 |
PHP 프레임워크 라이트버전 개발방향 10가지 (0) | 2012.05.09 |
Mysql 콘솔창에서 사용할 경우 (0) | 2012.05.09 |
댓글 영역