|
|
PHP/매뉴얼 번역 2008/06/20 00:43
Late Static Bindings
PHP 5.3.0 이후 PHP 는 Late Static Bindings 라는 기능을 도입하였다. 이 기능을 사용하면 정적 상속컨텍스트에서 호출된 클래스를 참조할 수 있다.
이 Late Static Bindings 라는 이름은 내부동작을 고려하여 붙여진 이름이다. Late Bindings 의 유래는 메소드를 정의하고 있는 클래스를 사용해도 static:: 의 해결이 불가능해졌기때문이다. 그 대신 실행시 정보를 기본으로 해결할수 있게되었다. static binding" 의 유래는 정적메소드의 호출에 사용할 수 있게되어서 있다. (단 정적메소드 이외에서도 사용할 수 있다. )
self:: 의 제한
self:: 또는 __CLASS__ 에 의해 현재의 클래스에의 정적참조는 해당 메소드가 속한 클래스에 의해 해결된다.(즉 해당 메소드가 정의된 클래스)
self:: 사용예
<?php class A { public static function who() { echo __CLASS__; } public static function test() { self::who(); } }
class B extends A { public static function who() { echo __CLASS__; } }
B::test(); ?>
출력결과
A Late Static Bindings 의 사용방법 Late Static Bindings은 이러한 제한을 해결하기위한 키워드를 도입해서 실행시 맨처음에 호출된 클래스를 참조하도록 하고 있다. 이 키워드를 사용하면 앞에서 예를 든 test() 에서 B 를 참조할수 있게된다. 이 키워드는 새롭게 추가한 것이 아니고 이미 예약된 static 를 사용하고 있다. static:: 의 간단한 사용법
<?php class A { public static function who() { echo __CLASS__; } public static function test() { static::who(); // Here comes Late Static Bindings } }
class B extends A { public static function who() { echo __CLASS__; } }
B::test(); ?> 결과
B 주의: static:: 의 동작은 정적메소드에서는 $this 와 다르다! $this-> 는 상속규칙을 따르지만 static:: 는 따르지 않는다.
비정적 컨텍스에서의 static:: 사용법
<?php class TestChild extends TestParent { public function __construct() { static::who(); }
public function test() { $o = new TestParent(); }
public static function who() { echo __CLASS__."\n"; } }
class TestParent { public function __construct() { static::who(); }
public static function who() { echo __CLASS__."\n"; } } $o = new TestChild; $o->test();
?>
결과
TestChild TestParent 주의: 정적호출이 대체없이 완전하게 해결된 시점에서 종료한다.
<?php class A { public static function foo() { static::who(); } public static function who() { echo __CLASS__."\n"; } }
class B extends A { public static function test() { A::foo(); }
public static function who() { echo __CLASS__."\n"; } }
B::test(); ?>
결과
A
특수한경우 PHP 에서 메소드를 호출하는 방법엔 여러가지가 있다. 예를 들어 콜백 , 매직메소드등이 그중에 하나이다. Late Static Bindings 은 실행시의 정보를 바탕으로 해결을 하며 , 이런 특수한 경우에는 예상치못한 결과를 낼 수 도 있다. 매직메소드내에서의Late Static Bindings
<?php class A {
protected static function who() { echo __CLASS__."\n"; }
public function __get($var) { return static::who(); } }
class B extends A {
protected static function who() { echo __CLASS__."\n"; } }
$b = new B; $b->foo; ?> 결과
B 원문링크:http://www.php.net/manual/en/language.oop5.late-static-bindings.php
목차로 PHP 클래스와 오브젝트 ( Classes and Objects ) PHP 5
Trackback 0
:
Trackback Address :: http://breakpoint.a4box.com/trackback/123
PHP/매뉴얼 번역 2008/06/20 00:43
타이프 힌팅(Type Hinting)PHP 5 에서는 타이프힌팅 (Type Hinting) 이 도입되었다. 함수는 (클래스의 이름을 함수 프로토타이프에서 지정하여) 패러미터를 오브젝트 또는 배열(PHP5.1 이후) 가 반드시 지정되도록 할 수 있게 되었다. 그러나 디폴트 파라미터 값으로 NULL 을 사용한 경우에는 나중에 임의의 값을 파라미터로 지정할 수 있게 되었다. 예
<?php // An example class class MyClass { /** * A test function * * First parameter must be an object of type OtherClass */ public function test(OtherClass $otherclass) { echo $otherclass->var; }
/** * Another test function * * First parameter must be an array */ public function test_array(array $input_array) { print_r($input_array); } }
// Another example class class OtherClass { public $var = 'Hello World'; } ?> 타이프힌트의 지정조건을 만족시키지 못하면 캐치가능한 치명적 에러가 발생한다.
<?php // An instance of each class $myclass = new MyClass; $otherclass = new OtherClass;
// Fatal Error: Argument 1 must be an object of class OtherClass $myclass->test('hello');
// Fatal Error: Argument 1 must be an instance of OtherClass $foo = new stdClass; $myclass->test($foo);
// Fatal Error: Argument 1 must not be null $myclass->test(null);
// Works: Prints Hello World $myclass->test($otherclass);
// Fatal Error: Argument 1 must be an array $myclass->test_array('a string');
// Works: Prints the array $myclass->test_array(array('a', 'b', 'c')); ?>
타이프힌팅은 함수에서도 사용가능하다.
<?php // An example class class MyClass { public $var = 'Hello World'; }
/** * A test function * * First parameter must be an object of type MyClass */ function MyFunction (MyClass $foo) { echo $foo->var; }
// Works $myclass = new MyClass; MyFunction($myclass); ?> 타이프힌트는 NULL 값을 사용할 수 있다.
<?php
/* Accepting NULL value */ function test(stdClass $obj = NULL) {
}
test(NULL); test(new stdClass);
?> 타이프힌트는 object 타입 , array 타입 (PHP5.1 이후) 에서만 사용할 수 있다. int 및 string 같은 일반적인 타이프힌팅은 지원하지않는다. 원문링크 : http://www.php.net/manual/en/language.oop5.typehinting.php목차에 PHP 클래스와 오브젝트 ( Classes and Objects ) PHP 5
Trackback 0
:
Trackback Address :: http://breakpoint.a4box.com/trackback/122
PHP/매뉴얼 번역 2008/06/20 00:42
오브젝트의 비교(Comparing objects)
PHP 5에서 오브젝트의 비교는 오브젝트지향언어에서 흔히 처리하는 방식의 동작에 대응하고 있어서 PHP 4 보다 더 복잡해졌다. ( 단 , PHP 5 는 오브젝트지향언어가 아니다. )
비교 연산자(==) 를 사용할때 오브젝트 변수는 단순하게 비교된다. 즉 , 두개의 오브젝트의 인스턴스는 같은 속성과 값을 가지고 있고 같은 클래스의 인스턴스 일경우 같다고 본다.
한편 일치연산자 (===) 를 사용할 경우 , 오브젝트변수는 같은 클래스의 같은 인스턴스를 참조할때만 같다고 본다.
이러한 룰을 나타낸 예가 다음과 같다.
<?php function bool2str($bool) { if ($bool === false) { return 'FALSE'; } else { return 'TRUE'; } }
function compareObjects(&$o1, &$o2) { echo 'o1 == o2 : ' . bool2str($o1 == $o2) . "\n"; echo 'o1 != o2 : ' . bool2str($o1 != $o2) . "\n"; echo 'o1 === o2 : ' . bool2str($o1 === $o2) . "\n"; echo 'o1 !== o2 : ' . bool2str($o1 !== $o2) . "\n"; }
class Flag { public $flag;
function Flag($flag = true) { $this->flag = $flag; } }
class OtherFlag { public $flag;
function OtherFlag($flag = true) { $this->flag = $flag; } }
$o = new Flag(); $p = new Flag(); $q = $o; $r = new OtherFlag();
echo "Two instances of the same class\n"; compareObjects($o, $p);
echo "\nTwo references to the same instance\n"; compareObjects($o, $q);
echo "\nInstances of two different classes\n"; compareObjects($o, $r); ?>
결과
Two instances of the same class o1 == o2 : TRUE o1 != o2 : FALSE o1 === o2 : FALSE o1 !== o2 : TRUE
Two references to the same instance o1 == o2 : TRUE o1 != o2 : FALSE o1 === o2 : TRUE o1 !== o2 : FALSE
Instances of two different classes o1 == o2 : FALSE o1 != o2 : TRUE o1 === o2 : FALSE o1 !== o2 : TRUE
원문링크 : http://www.php.net/manual/en/language.oop5.object-comparison.php
목차에 PHP 클래스와 오브젝트 ( Classes and Objects ) PHP 5
Trackback 0
:
Trackback Address :: http://breakpoint.a4box.com/trackback/120
PHP/매뉴얼 번역 2008/06/20 00:42
오브젝트의 클론 생성
오브젝트를 복사할때 프로퍼티도 전부다 이중화한다고 항상 원하는 동작을 한다고 장담할 수 없다. 복사컨스트럭터를 필요로하는 예로서 GTK윈도우를 나타내는 오브젝트를 가지고 있고 그 오브젝트가 GTK 윈도우의 리소스를 가지고 있을때 복사를 작성할때에 똑같은 프로퍼티를 가지고 있는 윈도우를 작성하여 새로운 오브젝트가 새로운 윈도우의 리소스를 가지도록 하는 경우가 있을 수 있다. 다른 예로서는 오브젝트가 , 해당 오브젝트가 사용하는 다른 오브젝트에의 레퍼런스를 가지고 있고 , 부모 오브젝트를 복사할때 복사가 독립된 오브젝트의 복사본을 가지고있도록 그 오브젝트의 인스턴스를 새롭게 작성하려하는 경우가 있을 수 있다.
오브젝트의 복사는 clone 키워드 (해당 오브젝트의 __clone() 메소드가 있는 경우에 이것을 호출한다.) 로 작성된다. 오브젝트의 __clone() 메소드를 직접 호출하는것은 불가능하다. $copy_of_object = clone $object; 오브젝트의 클론이 작성될때 PHP 5 는 해당 오브젝트의 프로퍼티를 전부 shallow copy 한다. 다른 변수에의 레퍼런스를 가지고 있는 모든 프러퍼티는 레퍼런스 상태를 유지한다. __clone() 메소드가 정의되어 있는 경우 신규작성된 오브젝트의 __clone() 메소드가 호출되기 때문에 이 내부에서 프로퍼티의 필요한 변경을 행할 수 있다. 오브젝트 클론 생성 예.
<?php class SubObject { static $instances = 0; public $instance;
public function __construct() { $this->instance = ++self::$instances; }
public function __clone() { $this->instance = ++self::$instances; } }
class MyCloneable { public $object1; public $object2;
function __clone() { // Force a copy of this->object, otherwise // it will point to same object. $this->object1 = clone $this->object1; } }
$obj = new MyCloneable();
$obj->object1 = new SubObject(); $obj->object2 = new SubObject();
$obj2 = clone $obj;
print("Original Object:\n"); print_r($obj);
print("Cloned Object:\n"); print_r($obj2);
?>
결과
Original Object: MyCloneable Object ( [object1] => SubObject Object ( [instance] => 1 )
[object2] => SubObject Object ( [instance] => 2 )
) Cloned Object: MyCloneable Object ( [object1] => SubObject Object ( [instance] => 3 )
[object2] => SubObject Object ( [instance] => 2 )
)
원문링크: http://www.php.net/manual/en/language.oop5.cloning.php
목차에 PHP 클래스와 오브젝트 ( Classes and Objects ) PHP 5
Trackback 0
:
Trackback Address :: http://breakpoint.a4box.com/trackback/119
PHP/매뉴얼 번역 2008/06/20 00:42
final 키워드
PHP 5 에서 키워드 final 이 도입되어 final 을 앞에 붙여서 정의된 메소드는 자식 클래스를 오버라이딩 할 수 없다. 클래스 자체가 final 로 정의된 경우에는 클래스의 확장을 할 수 없다.
final 메소드 예
<?php class BaseClass { public function test() { echo "BaseClass::test() called\n"; } final public function moreTesting() { echo "BaseClass::moreTesting() called\n"; } }
class ChildClass extends BaseClass { public function moreTesting() { echo "ChildClass::moreTesting() called\n"; } } // Results in Fatal error: Cannot override final method BaseClass::moreTesting() ?>
final 클래스 예
<?php final class BaseClass { public function test() { echo "BaseClass::test() called\n"; }
// Here it doesn't matter if you specify the function as final or not final public function moreTesting() { echo "BaseClass::moreTesting() called\n"; } }
class ChildClass extends BaseClass { } // Results in Fatal error: Class ChildClass may not inherit from final class (BaseClass) ?>
원문링크:http://www.php.net/manual/en/language.oop5.final.php
목차에 PHP 클래스와 오브젝트 ( Classes and Objects ) PHP 5
Trackback 0
:
Trackback Address :: http://breakpoint.a4box.com/trackback/118
PHP/매뉴얼 번역 2008/06/20 00:41
매직메소스
함수명 __construct, __destruct (컨스트럭터와 디스트럭터참조), __call , __callStatic , __get, __set, __isset, __unset (오버로드참조), __sleep, __wakeup, __toString, __set_state 및 __clone 은 PHP 클래스 관련 특수함수이름이다. 이 함수들에 관련된 특별한 기능을 사용할 경우를 제외 하고 클래스 내에 이러한 이름의 함수를 작성할 수 없다.
警告
PHP 는 __ 로 시작하는 함수명을 특수함수로서 예약하고 있다. 문서화된 특수기능을 필요로 하는 경우를 제외하고 __로 시작하는 함수명을 사용하지말것을 권장한다.
__sleep __wakeup
serialize() 는 클래스에 특수한 이름 __sleep 함수가 있는지 없는지를 조사한다. 만약 있으면 시리얼화하기 전에 해당 함수를 실행한다. 이 함수는 오브젝트를 클리어할 수 있다. 또한 시리얼화하는 오브젝트의 모든 변수명을 배열로 해서 리턴하는것을 전제로 하고 있다. 이 메소드가 아무것도 리턴하지 않는 경우는 NULL 이 시리얼화되어 E_NOTICE 가 발생한다.
전형적인 __sleep 의 사용법은 도중에 데이터를 커밋하거나 비슷한 태스크의 클린업을 하는것들이다. 또한 오브젝트 크기가 꽤 크고 완전하게 보존할 필요가 없을경우 이 함수를 사용하면 유용하다.
unserialize() 는 특수한 이름 __wakeup 을 가진 함수가 존재하는지 조사한다. 만약 존재할 경우 오브젝트가 가지고 있는 모든 리소스를 재구축할 수 있다.
전형적인 __wakeup 의 사용법은 시리얼화할때 소실된 데이터베이스 컨넥션을 다시 행하거나 그 밖에 재초기화를 행한다.
Sleep 과 wakeup
<?php class Connection { protected $link; private $server, $username, $password, $db; public function __construct($server, $username, $password, $db) { $this->server = $server; $this->username = $username; $this->password = $password; $this->db = $db; $this->connect(); } private function connect() { $this->link = mysql_connect($this->server, $this->username, $this->password); mysql_select_db($this->db, $this->link); } public function __sleep() { return array('server', 'username', 'password', 'db'); } public function __wakeup() { $this->connect(); } } ?>
_toString __toString 메소드를 사용하여 클래스가 문자열로 변환될때의 동작을 결정할 수 있다.
예
<?php // Declare a simple class class TestClass { public $foo;
public function __construct($foo) { $this->foo = $foo; }
public function __toString() { return $this->foo; } }
$class = new TestClass('Hello'); echo $class; ?>
출력결과
Hello
주의해야 할것은 PHP 5.2.0 이전에서는 __toString 메소드는 echo() 또는 print() 와 직접결합된 경우에는 호출되었다. PHP 5.2.0 이후부터는 모든 문자열 컨텍스트(예를 들어 printf() 의 %s 수식자)에서 호출된다. 그러나 그 이외의 타입의 컨텍스트 (예를 들어 %d 수식자)에서는 호출되지 않는다. PHP 5.2.0 이후에서는 __toString 메소드를 가지고 있지 않는 오브젝트를 문자열로 변환하려고 하면 E_RECOVERABLE_ERROR 가 발생한다.
__set_state
이 static 메소드는 PHP 5.1.0 이후부터 var_export() 에 의해 익스포트된 클래스를 위해 호출된다.
이 메소드의 유일한 패러미터는 익스포트된 프로퍼티를 array('property' => value, ...) 의 형식을 가지고 있는 배열이다.
__set_state 의 사용법 예PHP 5.1.0 이후)
<?php
class A { public $var1; public $var2;
public static function __set_state($an_array) // As of PHP 5.1.0 { $obj = new A; $obj->var1 = $an_array['var1']; $obj->var2 = $an_array['var2']; return $obj; } }
$a = new A; $a->var1 = 5; $a->var2 = 'foo';
eval('$b = ' . var_export($a, true) . ';'); // $b = A::__set_state(array( // 'var1' => 5, // 'var2' => 'foo', // )); var_dump($b);
?>
출력 결과
object(A)#2 (2) { ["var1"]=> int(5) ["var2"]=> string(3) "foo" }
원문링크: http://www.php.net/manual/en/language.oop5.magic.php목차에 PHP 클래스와 오브젝트 ( Classes and Objects ) PHP 5
Trackback 0
:
Trackback Address :: http://breakpoint.a4box.com/trackback/117
PHP/매뉴얼 번역 2008/06/20 00:40
패턴
패턴은 가장좋은 방법과 좋은 설계를 기술하기위한 수단이다. 패턴은 일반적인 프로그램상의 과제에 유연한 해결책을 제공한다.
Factory
Factory 패턴으로 실행시에 오브젝트를 초기화할 수 있다. 오브젝트를 "제조한다"는 면에서 닮았기에 Factory 패턴이라는 이름이 붙었다. 패러미터화된 Factory 가 생성하는 클래스명을 패러미터로 받는다.
패러미터화된 팩토리 메소드의 예
<?php class Example { // The parameterized factory method public static function factory($type) { if (include_once 'Drivers/' . $type . '.php') { $classname = 'Driver_' . $type; return new $classname; } else { throw new Exception ('Driver not found'); } } } ?>
위 메소드를 클래스내에서 정의함으로 해서 실행시에 로드되는 드라이버를 생성할 수 있게 된다. Example 클래스가 데이터베이스 추상화클래스에서 MySQL 및 SQLite 드라이버를 로드하면 다음과 같이 할 수 있다.
<?php // Load a MySQL Driver $mysql = Example::factory('MySQL');
// Load a SQLite Driver $sqlite = Example::factory('SQLite'); ?>
Singleton
Singleton 패턴은 클래스의 인스턴스가 하나만 필요한 경우에 적용된다. 가장 일반적인 예가 데이터베이스에의 접속이다. 이 패턴을 구현하게 되면 프로그래머는 이 단일 인스턴스가 다른 많은 오브젝트로부터 쉽게 억세스할 수 있도록 할 수 있다.
<?php class Example { // Hold an instance of the class private static $instance; // A private constructor; prevents direct creation of object private function __construct() { echo 'I am constructed'; }
// The singleton method public static function singleton() { if (!isset(self::$instance)) { $c = __CLASS__; self::$instance = new $c; }
return self::$instance; } // Example method public function bark() { echo 'Woof!'; }
// Prevent users to clone the instance public function __clone() { trigger_error('Clone is not allowed.', E_USER_ERROR); }
}
?>
<?php // This would fail because the constructor is private $test = new Example;
// This will always retrieve a single instance of the class $test = Example::singleton(); $test->bark();
// This will issue an E_USER_ERROR. $test_clone = clone $test;
?>
원문링크 : http://www.php.net/manual/en/language.oop5.patterns.php
목차에 PHP 클래스와 오브젝트 ( Classes and Objects ) PHP 5
Trackback 0
:
Trackback Address :: http://breakpoint.a4box.com/trackback/116
PHP/매뉴얼 번역 2008/06/20 00:39
Object Iteration(Object Iteration)
PHP 5 는 아이템리스트에 대해 반복처리 (예를 들면 foreach 명령)를 가능하도록 오브젝트를 정의하는 수단을 제공한다. 디폴트로 모든 억세스권한이 있는 프로퍼티는 반복처리에 사용할 수 있다.
<?php class MyClass { public $var1 = 'value 1'; public $var2 = 'value 2'; public $var3 = 'value 3';
protected $protected = 'protected var'; private $private = 'private var';
function iterateVisible() { echo "MyClass::iterateVisible:\n"; foreach($this as $key => $value) { print "$key => $value\n"; } } }
$class = new MyClass();
foreach($class as $key => $value) { print "$key => $value\n"; } echo "\n";
$class->iterateVisible();
?>
출력결과
var1 => value 1 var2 => value 2 var3 => value 3
MyClass::iterateVisible: var1 => value 1 var2 => value 2 var3 => value 3 protected => protected var private => private var
출력결과로 알 수 있는것처럼 foreach 에 의한 반복처리가 모든 억세스권한이 있는 변수에 대해 일어나고 있다. 또한 Iterator 라는 이름의 PHP 5 내부 interface 를 implement 할 수도 있다. 오브젝트를 어떤식으로 반복처리할까를 정할 수 있다. Iterator를 구현한 오브젝트의 반복처리
<?php class MyIterator implements Iterator { private $var = array();
public function __construct($array) { if (is_array($array)) { $this->var = $array; } }
public function rewind() { echo "rewinding\n"; reset($this->var); }
public function current() { $var = current($this->var); echo "current: $var\n"; return $var; }
public function key() { $var = key($this->var); echo "key: $var\n"; return $var; }
public function next() { $var = next($this->var); echo "next: $var\n"; return $var; }
public function valid() { $var = $this->current() !== false; echo "valid: {$var}\n"; return $var; } }
$values = array(1,2,3); $it = new MyIterator($values);
foreach ($it as $a => $b) { print "$a: $b\n"; } ?> 결과
rewinding current: 1 valid: 1 current: 1 key: 0 0: 1 next: 2 current: 2 valid: 1 current: 2 key: 1 1: 2 next: 3 current: 3 valid: 1 current: 3 key: 2 2: 3 next: current: valid:
단순히 PHP 5 의 IteratorAggregate인터페이스를 구현하여 Iterator 함수를 정의할 필요없이 자신의 클래스를 정의 할 수도 있다.
<?php class MyCollection implements IteratorAggregate { private $items = array(); private $count = 0;
// Required definition of interface IteratorAggregate public function getIterator() { return new MyIterator($this->items); }
public function add($value) { $this->items[$this->count++] = $value; } }
$coll = new MyCollection(); $coll->add('value 1'); $coll->add('value 2'); $coll->add('value 3');
foreach ($coll as $key => $val) { echo "key/value: [$key -> $val]\n\n"; } ?> 출력결과
rewinding current: value 1 valid: 1 current: value 1 key: 0 key/value: [0 -> value 1]
next: value 2 current: value 2 valid: 1 current: value 2 key: 1 key/value: [1 -> value 2]
next: value 3 current: value 3 valid: 1 current: value 3 key: 2 key/value: [2 -> value 3]
next: current: valid:
원문링크 : http://www.php.net/manual/en/language.oop5.iterations.php목차에 PHP 클래스와 오브젝트 ( Classes and Objects ) PHP 5
Trackback 0
:
Trackback Address :: http://breakpoint.a4box.com/trackback/115
PHP/매뉴얼 번역 2008/06/20 00:36
오버로드 (Overloading)
PHP 의 오버로드기능은 멤버 , 메소드를 동적으로 작성하기위한 방법이다. 이러한 동적 엔티티는 매직메소드를 이용하여 처리된다. 매직메소드는 클래스내에서 여러가지 액션타입에 대응하여 준비할 수 있다.
오버로드메소드는 선언되어있지 않은 멤버 ,메소드를 조작하려할때 호출된다. 또한 현재의 스코프에서는 억세스불가능한 멤버, 메소드를 조작하려할때 호출된다. 이 장에서는 이러한 (선언되지 않거나 현재의 스코프에서 억세스 불가능한 ) 멤버 , 메소드를 "억세스불가능 멤버" 및 "억세스 불가능 메소드" 로 표기한다.
오버로드메소드는 모두 public 으로 정의하여야 한다. 주의: 이러한 매직메소드의 패러미터는 、 리퍼런스값으로 넘길 수 없다. 주의: PHP 에서의 "오버로드" 의 해석은 다른 많은 오브젝트지향언어와 다르다. 일반적으로 오버로드란 이름은 같지만 패러미터의 갯수 타입이 다른 메소드를 복수 가질수 있는것을 말한다.
변경 이력
멤버오버로딩
void __set ( string $name , mixed $value )
mixed __get ( mixed $name )
bool __isset ( string $name )
void __unset ( string $name )
__set() 은 억세스 불가능멤버에 데이터를 쓸때 실행됨
__get() 은 억세스 불가능멤버로부터 데이터값을 읽어들일때 사용
__isset() 은 isset() 또는 empty() 를 억세스불가능멤버에 실행시 기동한다.
__unset() 은 unset() 을 억세스불가능멤버에 실행했을때 기동한다.
패러미터 $name 은 작업을 행하는 멤버의 이름이다. __set() 메소드의 패러미터 $value 은 $name 에 설정하려는 값이다.
멤버의 오버로드가 오브젝트의 컨텍스트에서만 동작한다. 이러한 메직메소드는 정적 컨텍스트에서는 기동하지않는다. 따라서 이러한 메소드는 stati 선언을 할 수 없다.
__get, __set, __isset, __unset 을 사용한 오버로드 예
<?php class MemberTest { /** Location for overloaded data. */ private $data = array();
/** Overloading not used on declared members. */ public $declared = 1;
/** Overloading not triggered when accessed inside the class. */ private $hidden = 2;
public function __set($name, $value) { echo "Setting '$name' to '$value'\n"; $this->data[$name] = $value; }
public function __get($name) { echo "Getting '$name'\n"; if (array_key_exists($name, $this->data)) { return $this->data[$name]; }
$trace = debug_backtrace(); trigger_error( 'Undefined property: ' . $name . ' in ' . $trace[0]['file'] . ' on line ' . $trace[0]['line'], E_USER_NOTICE); return null; }
/** As of PHP 5.1.0 */ public function __isset($name) { echo "Is '$name' set?\n"; return isset($this->data[$name]); }
/** As of PHP 5.1.0 */ public function __unset($name) { echo "Unsetting '$name'\n"; unset($this->data[$name]); }
/** Not a magic method, just here for example. */ public function getHidden() { echo "'hidden' visible here so __get() not used\n"; return $this->hidden; } }
echo "<pre>\n";
$obj = new MemberTest;
$obj->a = 1; echo $obj->a . "\n";
var_dump(isset($obj->a)); unset($obj->a); var_dump(isset($obj->a));
echo $obj->declared . "\n"; echo $obj->getHidden() . "\n"; echo $obj->hidden . "\n"; ?>
출력결과
Setting 'a' to '1' Getting 'a' 1 Is 'a' set? bool(true) Unsetting 'a' Is 'a' set? bool(false) 1 'hidden' visible here so __get() not used 2 Getting 'hidden'
Notice: Undefined property: hidden in <file> on line 64 in <file> on line 28 메소드의 오버로드
mixed __call ( string $name , array $arguments )
mixed __callStatic ( string $name , array $arguments )
__call() 은 억세스불가능메소드를 오브젝트의 컨텍스트에서 실행했을때 기동한다.
__callStatic() 은 억세스불가능메소드를 정적컨텍스트에서 실행했을때 기동한다.
패러미터 $name 는 콜하려는 메소드의 이름이다. 패러미터 $arguments 는 배열 이며 메소드 $name 에 넘겨주려는 패러미터가 들어간다.
__call 및 ___callStatic 으로 인스턴스화된 메소드의 오버로드예
<?php class MethodTest { public function __call($name, $arguments) { // Note: value of $name is case sensitive. echo "Calling object method '$name' " . implode(', ', $arguments). "\n"; }
/** As of PHP 5.3.0 */ public static function __callStatic($name, $arguments) { // Note: value of $name is case sensitive. echo "Calling static method '$name' " . implode(', ', $arguments). "\n"; } }
$obj = new MethodTest; $obj->runTest('in object context');
MethodTest::runTest('in static context'); // As of PHP 5.3.0 ?>
출력결과
Calling object method 'runTest' in object context Calling static method 'runTest' in static context
원문링크: http://www.php.net/manual/en/language.oop5.overloading.php
목차에 클래스와 오브젝트 ( Classes and Objects ) PHP 5
Trackback 0
:
Trackback Address :: http://breakpoint.a4box.com/trackback/114
PHP/매뉴얼 번역 2008/06/20 00:07
오브젝트 인터페이스(Object Interfaces)
오브젝트인터페이스를 이용해서 메소드의 실체를 정의 하지 않고도 어떤 클래스가 구현해야하는 메소드의 종류를 지정하는 코드를 생성할수 있다. 인터페이스는 키워드 interface 로 정의되며 일반적인 클래스처럼 정의 할수 있지만 메소드의 구현은 정의되지 않는다. 인터페이스내에서 선언되는 모든 메소드는 public 이어야 한다.
implements
인터페이스를 구현하기위해서는 implements 연산자를 사용하며 , 이 인터페이스에 포함되는 모든 메소드를 구현해야한다. 구현되지 않은 경우 치명적인 에러를 발생한다. 각각의 인터페이스를 콤마로 구분해서 지정하여 클래스는 복수의 인터페이스를 구현할 수 있다.
주의 : 하나의 클래스내에서 같은이름의 함수를 가지고 있는 2개의 인터페이스를 구현할 수 없다.
<?php // Declare the interface 'iTemplate' interface iTemplate { public function setVariable($name, $var); public function getHtml($template); }
// Implement the interface // This will work class Template implements iTemplate { private $vars = array(); public function setVariable($name, $var) { $this->vars[$name] = $var; } public function getHtml($template) { foreach($this->vars as $name => $value) { $template = str_replace('{' . $name . '}', $value, $template); } return $template; } }
// This will not work // Fatal error: Class BadTemplate contains 1 abstract methods // and must therefore be declared abstract (iTemplate::getHtml) class BadTemplate implements iTemplate { private $vars = array(); public function setVariable($name, $var) { $this->vars[$name] = $var; } }
?>
원문링크: http://www.php.net/manual/en/language.oop5.interfaces.php목차로 PHP 클래스와 오브젝트 ( Classes and Objects ) PHP 5
Trackback 0
:
Trackback Address :: http://breakpoint.a4box.com/trackback/113
PHP/매뉴얼 번역 2008/06/19 19:28
클래스의 추상화
PHP 5 에서는 추상클래스와 메소드가 도입되었다. abstract 로 선언된 클래스의 인스턴스는 생성할 수 없다. 하나 이상의 추상메소드를 포함하는 모든 클래스 도 추상클래스이다. abstract 로 정의된 메소드는 signature 만 선언할 수 있고 구현할 수 없다.
추상클래스를 상속할때 부모클래스의 선언에서 abstract 라고 선언된 모든 메소드는 자식클래스에서 정의해야한다. 추가로 그러한 메소드는 동등의 (또는 제약이 조금은 덜한) 의 억세스권으로 정의 되어야 한다. 예를 들어 추상메소드가 protected 로 정의된 경우 해당 함수의 구현은 protected 또는 public 중 하나로 정의해야한다. private 로는 정의할 수 없다.
추상클래스 예
<?php abstract class AbstractClass { // Force Extending class to define this method abstract protected function getValue(); abstract protected function prefixValue($prefix);
// Common method public function printOut() { print $this->getValue() . "\n"; } }
class ConcreteClass1 extends AbstractClass { protected function getValue() { return "ConcreteClass1"; }
public function prefixValue($prefix) { return "{$prefix}ConcreteClass1"; } }
class ConcreteClass2 extends AbstractClass { public function getValue() { return "ConcreteClass2"; }
public function prefixValue($prefix) { return "{$prefix}ConcreteClass2"; } }
$class1 = new ConcreteClass1; $class1->printOut(); echo $class1->prefixValue('FOO_') ."\n";
$class2 = new ConcreteClass2; $class2->printOut(); echo $class2->prefixValue('FOO_') ."\n"; ?>
출력 결과
ConcreteClass1 FOO_ConcreteClass1 ConcreteClass2 FOO_ConcreteClass2 'abstract' 라는 이름의 유저정의함수 또는 코드는 수정없이 사용 가능하다.
원문링크 : http://www.php.net/manual/en/language.oop5.abstract.php
목차에 PHP 클래스와 오브젝트 ( Classes and Objects ) PHP 5
Trackback 0
:
Trackback Address :: http://breakpoint.a4box.com/trackback/112
PHP/매뉴얼 번역 2008/06/19 18:27
클래스 상수 (Class Constants)값을 변경할 수 없는 정수(constants)를 클래스내에 정의할 수 있다. 정수는 일반적인 변수와 달리 정의 및 사용할때 $ 기호를 붙이지 않는다.
정의하는 값은 정수표현이어야 하며 변수, 클래스의 멤버 , 연산결과 또는 함수의 호출 등은 사용할 수 없다.
PHP 5.3.0 이후부터는 변수를 이용하여 클래스를 참조할 수 있다. 변수의 값에 키워드를 (예를 들어 self 또는 parent、 static ) 지정할 수 없다.
정수의 정의와 사용 예
<?php class MyClass { const constant = 'constant value';
function showConstant() { echo self::constant . "\n"; } }
echo MyClass::constant . "\n";
$classname = "MyClass"; echo $classname::constant . "\n"; // As of PHP 5.3.0
$class = new MyClass(); $class->showConstant();
echo $class::constant."\n"; // As of PHP 5.3.0 ?>
정적데이터 예
<?php class foo { // As of PHP 5.3.0 const bar = <<<'EOT' bar EOT; } ?>
주의: Nowdoc 는 PHP 5.3.0 이후부터 사용가능하다.
원문링크: http://www.php.net/manual/en/language.oop5.constants.php
목차에 PHP 클래스와 오브젝트 ( Classes and Objects ) PHP 5
Trackback 0
:
Trackback Address :: http://breakpoint.a4box.com/trackback/111
PHP/매뉴얼 번역 2008/06/19 18:19
static 키워드
클래스 멤버 또는 메소드를 static 으로 선언하면 클래스를 인스턴스화 하지않고도 억세스가 가능하다. static 멤버는 인스턴스화된 클래스오브젝트로부터 억세스할 수 없다. (static 멤버로부터는 가능하다. )
PHP 4 와의 호환성을 유지하기위하여 、억세스권(접근권한 : Visibility) 선언이 없는 경우 해당 멤버또는 메소드는 public 으로 선언되어있다고 판단한다.
static 메소드는 오브젝트의 인스턴스를 생성하지 않고 호출할 수 있다. pseudo 변수 $this 는 static 으로 선언된 메소드의 내부에서 이용할 수 없다.
static 프로퍼티는 、화살표연산자 (the arrow operator ) -> 를 사용하여 오브젝트로부터 억세스할수 없다.
non-static 메소드를 정적으로 호출하면 E_STRICT 레벨의 경고가 발생한다.
PHP 5.3.0 이후에서는 변수를 이용하여 클래스를 참조할 수 있다. 변수 값에 키워드를 (예를 들어 self 또는 parent、 static ) 지정할 수 없다.
static 멤버 예
<?php class Foo { public static $my_static = 'foo';
public function staticValue() { return self::$my_static; } }
class Bar extends Foo { public function fooStatic() { return parent::$my_static; } }
print Foo::$my_static . "\n";
$foo = new Foo(); print $foo->staticValue() . "\n"; print $foo->my_static . "\n"; // Undefined "Property" my_static
print $foo::$my_static . "\n"; $classname = 'Foo'; print $classname::$my_static . "\n"; // As of PHP 5.3.0
print Bar::$my_static . "\n"; $bar = new Bar(); print $bar->fooStatic() . "\n"; ?>
static 메소드 예
<?php class Foo { public static function aStaticMethod() { // ... } }
Foo::aStaticMethod(); $classname = 'Foo'; $classname::aStaticMethod(); // As of PHP 5.3.0 ?>
원문링크: http://www.php.net/manual/en/language.oop5.static.php
목차로 PHP 클래스와 오브젝트 ( Classes and Objects ) PHP 5
Trackback 0
:
Trackback Address :: http://breakpoint.a4box.com/trackback/110
PHP/매뉴얼 번역 2008/06/19 17:59
스코프 연산자(::) Scope Resolution Operator (::)
스코프정의연산자 (Paamayim Nekudotayim 라고도 함) , 그냥 보이는 대로 부르면 더블콜론은 static, 정수(constant ) 그리고 오버라이드된 클래스의 멤버 , 메소드 에 접근 할 수 있도록 하는 토큰중에 하나이다. 위의 아이템들을 클래스정의의 외부에서 참조할때 클래스의 이름을 사용하도록 한다. PHP 5.3.0 이후부터는 변수를 이용하여 클래스를 참조할 수 있다. 변수의 값은 키워드를 지정할수 없다. (예를 들어 self 또는 parent、 static 같은 ...) 왜 더블콜론에 Paamayim Nekudotayim 라는 이름을 붙였을까 ? Zend Engine 0.5 (PHP 3 의 엔진) 을 작성할때 Zend 팀은 더블콜론의 이름을 이렇게 정하였다. 실은 더블콜론을 의미하는 히브루(Hebrew)어라고... 클래스정의 외부에서의 예
<?php class MyClass { const CONST_VALUE = 'A constant value'; }
$classname = 'MyClass'; echo $classname::CONST_VALUE; // As of PHP 5.3.0
echo MyClass::CONST_VALUE; ?>
두개의 특별한 키워드 self 와 parent 가 클래스정의의 내부에서 멤버 또는 메소드를 억세스할때 사용된다.
클래스정의 내부에서의 예
<?php class OtherClass extends MyClass { public static $my_static = 'static var';
public static function doubleColon() { echo parent::CONST_VALUE . "\n"; echo self::$my_static . "\n"; } }
$classname = 'OtherClass'; echo $classname::doubleColon(); // As of PHP 5.3.0
OtherClass::doubleColon(); ?>
확장된 클래스가 부모클래스의 메소드의 정의를 오버라이드할때 PHP 는 부모클래스의 메소드를 호출하지 않는다. 부모클래스의 메소드를 호출할지 말지는 확장된 클래스에서 결정할 일이다. 컨스트럭터 및 디스트럭터 , 오버로드 그리고 매직메소드의 정의에도 적용된다.
부모클래스의 메소드 호출예
<?php class MyClass { protected function myFunc() { echo "MyClass::myFunc()\n"; } }
class OtherClass extends MyClass { // Override parent's definition public function myFunc() { // But still call the parent function parent::myFunc(); echo "OtherClass::myFunc()\n"; } }
$class = new OtherClass(); $class->myFunc(); ?>
원문링크 : http://www.php.net/manual/ja/language.oop5.paamayim-nekudotayim.php목차에 PHP 클래스와 오브젝트 ( Classes and Objects ) PHP 5
Trackback 0
:
Trackback Address :: http://breakpoint.a4box.com/trackback/109
PHP/매뉴얼 번역 2008/06/19 17:11
컨스트럭터와 디스트럭터 (Constructors and Destructors)Constructor
void __construct ([ mixed $args [, $... ]] )
PHP 5 에서는 개발자가 클래스의 컨스트럭터 메소드를 선언할 수 있다. 컨스트럭터메소드를 가진 클래스는 새로운 오브젝트가 생성될때마다 이 메소드를 호출한다. 이 호출에 의해서 오브젝트를 사용하기전에 필요한 초기화를 행할 수 있다.
주의: 자식 클래스가 컨스트럭터를 가지고 있는 경우 부모클래스의 컨스트럭터가 암묵적으로 호출되지 않는다. 부모클래스의 컨스트럭터를 실행하기위해서는 자식 클래스내에서 parent::__construct() 를 호출하여야 한다. 새롭게 통합된 컨스트럭터 사용 예
<?php class BaseClass { function __construct() { print "In BaseClass constructor\n"; } }
class SubClass extends BaseClass { function __construct() { parent::__construct(); print "In SubClass constructor\n"; } }
$obj = new BaseClass(); $obj = new SubClass(); ?>
하위 호환성을 유지하기 위하여 PHP 5 가 주어진 클래스에서 __construct() 함수를 찾을 수 없는 경우 구형식의 컨스트럭터 함수 , 즉 클래스 이름과 똑같은 함수를 찾게된다. 실제로 호환성의 문제가 발생할 가능성이 있는것은 주어진 클래스가 __construct() 라는 이름의 메소드를 가지고 있으며 다른 용도로 사용되고 있는 경우이다. Constructor
void __destruct ( void )
PHP 5 에서는 C++ 같은 다른 오브젝트지향언어와 닮은 개념의 디스트럭터가 도입되었다. 디스트럭터메소드는 특정 오브젝트에의 모든 참조(레퍼런스)가 삭제된 직후 도는 오브젝트가 명시적으로 파기된 직후 호출된다. 또는 스크립트의 종료시에도 무작위로 호출된다. 디스트럭터 예
<?php class MyDestructableClass { function __construct() { print "In constructor\n"; $this->name = "MyDestructableClass"; }
function __destruct() { print "Destroying " . $this->name . "\n"; } }
$obj = new MyDestructableClass(); ?>
컨스트럭터와 마찬가지로 부모클래스의 디스트럭터가 엔진에 의해 암묵적으로 호출되지 않는다. 부모클래스의 디스트럭터를 실행하기위해서는 디스트럭터내에서 명시적으로 parent::__destruct() 를 호출하여야 한다.
주의: 스크립트의 셧다운시 디스트럭터가 호출되는 경우 HTTP 헤더는 이미 송신되어 있다. 스크립트의 셧다운시의 작업디렉토리는 SAPI (예를 들어 아파치)에 따라 다르다.
주의: 디스트럭터의 내부에서 (스크립트의 종료처리시에) 예외를 던지려고 하면 치명적인 에러를 일으킨다.
원문링크: http://www.php.net/manual/en/language.oop5.decon.php
목차로 PHP 클래스와 오브젝트 ( Classes and Objects ) PHP 5
Trackback 0
:
Trackback Address :: http://breakpoint.a4box.com/trackback/107
|