~~Title:PHP 클래스~~ {{page>language:php:php_문서_목차&noheader&nofooter&noeditbtn&firstseconly}} ====== OO PHP ====== ===== 클래스 선언 ===== class MySample { public $var1; function func1() {} } // ';' 는 필요 없나? -> 없어도 된다. ===== 생성자,소멸자 ===== class MySample { public $var = 'class attribute'; //생성자 function __construct( /* param if need */ ) { echo 'construct'.'
'; } //소멸자 function __destruct() { echo 'destruct' . '
'; } }
===== 인스턴스 ===== $mySamp = new MySample; 이름으로 생성 할 수도 있다. 변수 이름을 대입해서 사용하는 변수로서. $MySample = 'MySample'; $mySamp2 = new $MySample; ===== 클래스 속성(Attribute) 사용 ===== 클래스 속성을 사용하려면, class MySample { public $var = 'class attribute'; //... function foo() { echo $this->var; } } $a = new MySample; echo $a->var; __get(), __set()을 사용해서, 속성을 사용할 때 데이터를 캡슐화 할 수 있다. class MySample { public $var2 = 'a'; function __get( $name ) { return $this->$name; } function __set( $name, $value ) { $this->$name = $value; } } 어디에 쓸 것인가, 각 속성이 사용되는 시점에 데이터의 정합성을 확인하는 용도가 있다라고 하는데.. 익숙하지 않은 개념이라 잘 모르겠다. ===== 클래스 연산(operator) ===== 따로 적을 필요 있나.. (class instance)->(operator(...)); ===== 상속 ===== 키워드 : extends 로 상속 받는다. class MySample2 extends MySample { public $var3; } ===== 오버라이딩 ===== 연산자(operator) 이름이 같다면, 오버라이딩은 기본이다. 자식 클래스 쪽의 오버라이딩된 함수에서 부모의 함수를 호출하려면 parent::를 붙여서 호출하면 된다. class A { function operA() { echo 'from a'; } } class B { function operA() { echo 'from b'; parent::operA(); } } ==== final ==== 연산자에 final을 붙이면, 오버라이딩이 되지 않는다. class MySample { final function operA() {} } class 에 final을 붙이면 상속이 되지 않는다. final class MySample { //... } 이 두 경우 모두 실행하면 에러가 발생된다. ===== 다중 상속 ===== 지원하지 않는다. ===== 인터페이스 ===== 자바의 인터페이스와 같다. 클래스의 인터페이스를 만든다. interface Displayable { function display(); } 사용하려면, class SomePage implements Displayable { function display() { // .. } } ===== php 고급 객체 지향 기능 ===== ==== 클래스당 상수 ==== class Math { const pi = 3.14; } echo Math::pi . '
';
==== 정적(static) 메소드 ==== static 을 붙이면 인스턴스를 만들지 않아도 호출이 가능하다. class Math { static function squared( $input ) { return $input * $input; } } // 사용하기 echo Math::squared(2); ==== 클래스 타입검사와 hinting ==== instanceof * 특정 클래스의 인스턴스인가 * 특정 클래스를 상속 받았는가? * 인터페이스를 구현한 것인가? 판단하는 키워드. if( $b instanceof A ) // $b는 A의 무엇인가에 따라 리턴 값이 true , false가 나온다. === 힌팅 === // if class B가 있다면 function check_hint( B $someclass ) { //... } 함수 파라미터에 클래스 이름을 적어서, 다른 종류의 클래스 인스턴스를 받는 것을 막는다. ==== 정적 바인딩 ==== 정적 함수에 대한 오버라이딩 기능이 적용된다. php v5.3 부터 적용. class A { public static function who() { echo __CLASS__; } public static function test() { static::who(); } } class B extends A { public static function who() { echo __CLASS__; } } B::test(); // 결과는 B ==== 객체복사 ==== clone 명령어로 복사 $c = clone $b; 직접 복사하는 기능을 추가하는 경우, __clone()함수를 정의하여 필요한 부분을 넣는다. clone 을 실행해도 , 완전히 똑같이 복사본을 만드는 기본 행동 뒤에 __clone()가 호출되므로, 전체를 다시 복사하지 않아도 된다. ==== 추상 클래스 ==== 인터페이스 클래스가 있는데 이건 왜 만들었을까? abstract와 같이 사용해서 추상 클래스를 만든다. 내부 메소드도 추상 여부에 대한 키워드를 추가할 수 있다. abstract class A { abstract function operationX( $param1, $param2 ); } ==== __call() 메소드 오버로딩 ==== 흥미로운 기능이다. 오버로딩 기능 중에 유용하게 쓸 수 있을 것 같다. 첫번째 파라미터는 호출되는 메소드 이름. 두번째는 호출되는 메소드에 넘어갈 파라미터의 배열이다. //예제함수 public function __call( $methodName, $param ) { if( $methodName == 'display' ) { if( is_object($param[0]) ) $this->displayObject( $param[0] ); else if( is_array($param[0]) ) $this->displayArray( $param[0] ); else $this->displayScala( $param[0] ); } } //사용 예 $ov = new overload; $ov->display( array(1,2,3) ); // call displayArray() $ov->display( 'cat' ); // call displayObject() display()라는 메소드를 호출하면 __call() 메소드가 실행 되고, __call() 내부에서는 display() 메소드가 호출되는 경우에 대한 코드가 실행 된다. 그 코드에서는 파라미터에 따라 각각 다른 함수를 부르는 부분이 실행된다. 약간의 오버로드는 예상되지만.. 복잡한 실행 구조를 감추는 편의 함수를 작성할때 요긴할 것 같다. display()는 구현할 필요가 없다. ==== __autoload ==== 클래스에서 사용하는 함수가 아니라 독립된 함수로서, __autoload()를 구현하면 클래스를 생성하려고 할때 자동으로 호출된다. new 연산자를 오버로딩한 것 같은 효과? 필요한 클래스의 인스턴스를 만들때, 클래스가 선언된 파일을 불러 오는 용도로 주로 사용한다고 한다. function __autoload( $name ) { include_once $name . ".php"; } ==== Iterator와 반복 구현하기 ==== 배열처럼 클래스 속성에 접근할 수 있다? (정말로?) class myClass { public $a = '5'; public $b = '3'; public $c = '3'; } $x = new myClass; foreach( $x as $attribute ) { echo $attribute . '
'; }
이것보다 복잡한 방식이라면, iterator를 만들어야 한다. 예제코드가 길기때문에 패스. 필요하면 인터넷 검색. ==== 클래스를 문자열로 ==== $p = new someclass; echo $p; __toString() 함수를 클래스에 구현하면, 클래스를 출력할때 (위의 코드) 이 함수가 호출 된다. class Printable { public $test1; public $test2; public function __toString() { return (var_export($this, TRUE)); } } ==== reflection API ==== 디버깅용인가? ' . $nc . ''; ?> 해당 클래스, 여기에서는 Page,의 상세 정보가 쭈욱 출력된다. ====== 7장 - 예외처리 ====== try { //code throw new Exception('msg',code); } catch( Exception $e ) { //예외처리 } ===== Exception Class ===== Exception class의 기본 메소드 * getCode() * getMessage() * getFile() * getLine() * getTrace() * getTraceAsString() * __toString() : 이 함수를 구현하면, Exception 클래스를 바로 출력할때, 필요한 정보만 줄 수 있다. 디버깅 클래스를 따로 만드는 것이 낫지 않나?