language:php:php와mysql-ch6-oo-php [KIEUN's Wiki 문기은 위키]

사용자 도구

사이트 도구


language:php:php와mysql-ch6-oo-php

6장 - OO PHP

클래스 선언

class MySample
{
  public $var1;
	function func1() {}
}
// ';' 는 필요 없나? -> 없어도 된다.

생성자,소멸자

class MySample
{
	public $var = 'class attribute';
 
	//생성자
	function __construct( /* param if need */ ) 
	{ echo 'construct'.'<br/>'; }
	//소멸자
	function __destruct() 
	{ echo 'destruct' . '<br/>'; }
}

인스턴스

$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 . '<br/>';

정적(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 . '<br/>'; }

이것보다 복잡한 방식이라면, iterator를 만들어야 한다.

예제코드가 길기때문에 패스. 필요하면 인터넷 검색.

클래스를 문자열로

$p = new someclass;
echo $p;

__toString() 함수를 클래스에 구현하면, 클래스를 출력할때 (위의 코드) 이 함수가 호출 된다.

class Printable {
	public $test1;
	public $test2;
	public function __toString()
	{
		return (var_export($this, TRUE));
	}
}

reflection API

디버깅용인가?

<?php
require_once('page.inc');
$nc = new ReflectionClass('Page');
echo '<pre>' . $nc . '</pre>';
?>

해당 클래스, 여기에서는 Page,의 상세 정보가 쭈욱 출력된다.

7장 - 예외처리

try {
	//code
	throw new Exception('msg',code);
}
catch( Exception $e ) {
	//예외처리
}

Exception Class

Exception class의 기본 메소드

  • getCode()
  • getMessage()
  • getFile()
  • getLine()
  • getTrace()
  • getTraceAsString()
  • __toString() : 이 함수를 구현하면, Exception 클래스를 바로 출력할때, 필요한 정보만 줄 수 있다.

디버깅 클래스를 따로 만드는 것이 낫지 않나?

language/php/php와mysql-ch6-oo-php.txt · 마지막으로 수정됨: 2013/05/24 12:15 저자 kieuns