RSS구독하기:SUBSCRIBE TO RSS FEED
즐겨찾기추가:ADD FAVORITE
글쓰기:POST
관리자:ADMINISTRATOR
New Object Model

PHP 5 에는 새로운 객체 모델이 존재한다. PHP의 객체 조작사항은 더 나은 성능과 보다 많은 특징을 위해 완벽하게 재작성되었다. PHP이전 버전에서 객체는 원시적인 형태로 조작되었다. ( 실례를 들자면 정수나 문자열 같은 것들을 말이다. ). 이 객체 안의 메소드가 가진 결점은 의미론적으로, 어떤 변수가 할당되었거나 파라미터의 값을 메소드로 전달할 때 모든 객체들이 복제된다는 것이었다. 이제 새로운 접근방식에서는 객체가 핸들에 의해 참조되고 값으로 참조되지 않는다. ( 객체식별자와 같은 핸들로 생각할 수 있을 것이다 ).

   많은 PHP 프로그래머들은 심지어는 과거의 객체모델이 멋대로 복제되는 것을 눈치채지 못했고 그랬기때문에 PHP어플리케이션의 대부분은 아주 좁은 틀을 벗어나 동작했을 것이다. 


Private and Protected Members

PHP 5 는 클래스 프로퍼티의 가시성( 可視性 : visibility )을 정의할 수 있게 하는 private 와 protected 멤버 변수를 도입했다.


Example B-4. Private and Protected Members accesibility

Protected 멤버 변수는 확장된 클래스에서 중복 선언되면 접근할 수 있는데 비해, private 멤버 변수는 단지 멤버 변수를 소유한 클래스에서만 접근이 가능하다.

<?php
class MyClass
{
  
private $Hello = "Hello, World!\n"
;
  
protected $Bar = "Hello, Foo!\n"
;
  
protected $Foo = "Hello, Bar!\n"
;

   function
printHello
() {
       print
"MyClass::printHello() " . $this->Hello
;
       print
"MyClass::printHello() " . $this->Bar
;
       print
"MyClass::printHello() " . $this->Foo
;
   }
}

class
MyClass2 extends MyClass
{
  
protected $Foo
;
            
   function
printHello
() {
      
MyClass::printHello();                         
/* Should print */
      
print "MyClass2::printHello() " . $this->Hello;
/* Shouldn't print out anything */
      
print "MyClass2::printHello() " . $this->Bar
/* Shouldn't print (not declared)*/
      
print "MyClass2::printHello() " . $this->Foo
/* Should print */
  
}
}

$obj = new MyClass
();
print
$obj->Hello
/* Shouldn't print out anything */
print $obj->Bar;   
/* Shouldn't print out anything */
print $obj->Foo;   
/* Shouldn't print out anything */
$obj->printHello();
/* Should print */

$obj = new MyClass2
();
print
$obj->Hello
/* Shouldn't print out anything */
print $obj->Bar;   
/* Shouldn't print out anything */
print $obj->Foo;   
/* Shouldn't print out anything */
$obj->printHello
();
?>
 
 

PHP 5에서는 또한 private 와 protected 메소드가 도입되었다.


Example B-5. Protected methods example

<?php
class Foo
{
  
private function aPrivateMethod
() {
       echo
"Foo::aPrivateMethod() called.\n"
;
   }

  
protected function aProtectedMethod
() {
       echo
"Foo::aProtectedMethod() called.\n"
;
      
$this->aPrivateMethod
();
   }
}

class
Bar extends Foo
{
  
public function aPublicMethod
() {
       echo
"Bar::aPublicMethod() called.\n"
;
      
$this->aProtectedMethod
();
   }
}

$o = new Bar
;
$o->aPublicMethod
();
?>

과거의 코드에서는 사용자 정의된 클래스나 함수가 "public", "protected" 또는 "private"를 명기하지 않고 실행했을 것이다.


Abstract Classes and Methods

PHP 5는 또한 추상클래스라는 것과 추상메소드라는 것이 도입되었다. 추상메소드는 단지 메소드의 특징적인 사항을 선언하고 수행사항을 제공하지는 않는다. 다음 예시에서 클래스는 abstract로 선언하는 것을 필요로 하는 추상 메소드를 포함한다.


Example B-6. Abstract class example

<?php
abstract
class AbstractClass
{
  
abstract public function test
();
}

class
ImplementedClass extends AbstractClass
{
  
public function test
() {
       echo
"ImplementedClass::test() called.\n"
;
   }
}

$o = new ImplementedClass
;
$o->test
();
?>

요약클래스는 명시화될 수 없다. 과거의 코드에서는 사용자 정의된 클래스나 함수에 "abstract"를 명기하지 않고 실행했을 것이다.


Interfaces

PHP 5 에서 interface라는 새로운 객체지향 개념이 도입되었다. 클래스는 인터페이스의 임의의 목록을 수단으로 삼을 것이다.


Example B-7. Interface example

<?php
interface Throwable
{
  
public function getMessage
();
}

class
MyException implements Throwable
{
  
public function getMessage
() {
      
// ...
  
}
}
?>

과거에는 사용자정의된 클래스나 함수에 "interface"나 "implements"를 붙이지 않고 실행했을 것이다.


Class Type Hints

 느슨한 유형이 남아있는 PHP5는 클래스 타입 힌트를 사용하여 파라미터로부터 메소드로 값을 전달하는 개체의 요청된 클래스를 선언하는 능력을 도입하였다.


Example B-8. Class type hinting example

<?php
interface Foo
{
   function
a(Foo $foo
);
}

interface Bar
{
   function
b(Bar $bar
);
}

class
FooBar implements Foo, Bar
{
   function
a(Foo $foo
) {
      
// ...
  
}

   function
b(Bar $bar
) {
      
// ...
  
}
}

$a = new FooBar
;
$b = new FooBar
;

$a->a($b
);
$a->b($b
);
?>

이러한 클래스 타입 힌트는 보통 유형화된 언어에서와 같이 컴파일 할 때에는 체크하지 않는다. 그러나 실행 도중에 체크한다. 이것은 다음을 의미한다:

<?php
function foo(ClassName $object
) {
  
// ...
}
?>


는 다음과 같다 :

<?php
function foo($object
) {
   if (!(
$object instanceof ClassName
)) {
       die(
"Argument 1 must be an instance of ClassName"
);
   }
}
?>
 

PHP 5 는 최종 멤버와 메소드를 선언하기 위해 "final" 키워드를 도입하였다. final을 붙인 메소드와 멤버는 하위클레스에 의해 오버라이드 되지 않는다.


Example B-9. final method

<?php
class Foo
{
  
final function bar
() {
      
// ...
  
}
}
?>

이것은 더군다나 최종적인 클래스를 만드는데 가능하다. 이것은 클래스가 특별화 되는 것을 막는다. (다른 클래스에 의해 '절대' 상속될 수 없다.). final 클래스는 자신들의 메소드를 final 로 선언할 필요가 없다.


Example B-10. final class

<?php
final
class Foo
{
  
// class definition
}

// the next line is impossible
// class Bork extends Foo {}
?>

프로퍼티는 final 속성을 가질 수 없다..

과거에는 사용자정의된 클래스나 함수에 "final"을 붙이지 않고 실행했을 것이다.


Objects Cloning

   PHP 4 에서는 객체가 복제되었을 때 복제된 생성자를 실행하기 위한 결정을 사용자가 할 수 없는 그런 방법을 제공했었다. 복제하는 동안에는 PHP 4 에서는 모든 객체의 프로퍼티에 대한 이상적 복제물을 만들기 위해 비트복사를 하는 단역을 수행하였다.  

   전체적으로 복제된 프로퍼티와 함께 복제된 객체를 만드는 것은 항상 원하는 행동이 아니다. 생성자 복제를 위해 필요한 것에 대한 좋은 예는 만약 GTK 윈도우를 묘사하는 객체를 소유하고 있고 객체는 이 객체를 복제할때의 GTK 윈도우의 리소스로 유지될 때, 아마 같은 프로퍼티를 가진 새로운 윈도우를 생성하길 원할것이고 새 윈도우의 리소스를 새 객체가 포함하길 원할 것이다. 다른 예로는 만약 객체가 다른 객체를 사용하는 참조자를 붙들어매고 있고, 개발자는 부모객체를 복제할때, 이 다른 객체의 새로운 인스턴스를 생성하길 원할 것이고 그래서 복제된 개체는 그 자신의 분산된 복제물을 가지고 있을 것이다.

복제되는 객체는 clone 키워드를 사용하여 생성된다. ( 가능하다면 객체의 __clone() 메소드를 호출한다 ). 객체의 __clone() 메소드는 직접적으로 호출될 수는 없다.

개발자들이 객체의 새로운 복제물을 생성하기 위해 요청할때, PHP 5 는 __clone() 메소드가 정의 되었는지 아닌지의 여부를 체크할 것이다. 만약 정의되지 않았다면 모든 객체의 프로퍼티를 복제할 기본적인 __clone() 을 호출할 것이다. __clone() 메소드가 정의되었다면 생성된 객체 안에 필요한 프로퍼티를 정할 의무가 있을 것이다. 편의를 위해 엔진은 소스객체로부터 모든 프로퍼티를 임포팅하는 함수를 공급해서 그것들이 소스 오브젝트의 값에 의한 복제물 과 함께 시작할 수 있도록 할 것이고 변경할 필요가 있는 프로퍼티를 단지 오버라이드 할 것이다.


Example B-11. Objects cloning

<?php
class MyCloneable
{
   static
$id = 0
;

   function
MyCloneable
() {
      
$this->id = self::$id
++;
   }

   function
__clone
() {
      
$this->address = "New York"
;
      
$this->id = self::$id
++;
   }
}

$obj = new MyCloneable
();

$obj->name = "Hello"
;
$obj->address = "Tel-Aviv"
;

print
$obj->id . "\n"
;

$obj_cloned = clone $obj
;

print
$obj_cloned->id . "\n"
;
print
$obj_cloned->name . "\n"
;
print
$obj_cloned->address . "\n"
;
?>
 

PHP 5 는 개발자로 하여름 클래스를 위해 생성자 메소드를 선언할 수 있게 한다. 생성자 메소드를 가진 클래스들은 새롭게 생성된 객체에서 이 메소드를 초기화 하는데 적당하게 호출해서 객체가 사용되기 전에 필요로 하지 않게 할 것이다.

PHP 4 에서 생성자 메소드는 클래스 자신의 이름과 같은 이름을 가진 클래스 메소드였다. 파생된 클래스로부터 부모 생성자를 호출하는 것이 매우 일반적일 때, PHP 4는 거대한 클래스 계층 주변으로 클래스를 옮기는 성가신 부분을 만들어내는 방법을 택해 작업했다. 만약 클래스가 다른 부모클래스 아래로 귀속하기 위해 옮겨졌을 때, 부모클래스 생성자의 잘 바뀌는 이름과 부모클래스 생성자를 호출하는 파생된 클래스의 코드는 수정될 것이다.

PHP 5 는 __construct()라는 이름으로 불리우는 생성자 메소드를 선언하는 표준방법을 도입하였다. 


Example B-12. using new unified constructors

<?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() 라는 이름을 가진 메소드를 가진 경우 이것이 다른 의미론을 위해 쓰일것이라는 의미를 가지고 있는데 호환성 문제를 가진 경우에 한해서만 해당한다.

Destructors

객체를 위해 파괴자를 정의하는 능력을 소유하는 것은 매우 유용할 수 있다. 파괴자는 디버깅을 위해, 데이터베이스의 연결을 끊을 때,기타 다른 여러가지 일을 마무리할 때 로그 메세지를 남길 수 있다. PHP 4에선느 객체 파괴자를 위한 기술이 존재하지 않았지만, PHP가 셧다운을 요청하는 도중에 실행될 등록함수를 위해 이미 지원했다. 

PHP 5 는 자바와 같은 다른 객체지향언어에서와 유사한 개념을 가진 파괴자를 도입하였다. : 객체의 파괴자를 파괴한 객체가 최종적으로 참조되었을때,  어떤 파라미터 값도 받지 않는 __destruct() 라고 이름 붙여진 클래스 메소드는 메모리에서 객체가 해제되기 전에 호출된다.

Example B-13. Destructor

<?php
class MyDestructableClass
{
   function
__construct
() {
       print
"In constructor\n"
;
      
$this->name = "MyDestructableClass"
;
   }

   function
__destruct
() {
       print
"Destroying " . $this->name . "\n"
;
   }
}

$obj = new MyDestructableClass
();
?>

생성자와 같이 부모클래스의 파괴자는 엔진에 의해 명시적으로 호출되지는 않을 것이다. 부모클래스의 파괴자를 실행하기 위해 파생된 클래스에서는 명확하게 파괴자 본문에 parent::__destruct() 를 적어 호출하여야 한다.

Constants

PHP 5 는 완전한 클래스 상수를 도입하였다:

Example B-14. Class constant example

<?php
class Foo
{
   const
constant = "constant"
;
}

echo
"Foo::constant = " . Foo::constant . "\n"
;
?>

과거에는 사용자정의된 클래스나 함수에 "const"를 붙이지 않고 실행했을 것이다.


Exceptions

PHP 4 는 예외사항 조정에 대한 요소가 없었다. PHP 5 에서는 다른 프로그래밍 언어와 유사한 예외모델을 도입하였다. "catch all"을 위해 지원하지만, "finally"조항을 위한 것이 아님을 주의하여라.

Exception 은 catch 블록에서 다시 제시될 수 있다. 또한 다양한 catch 블록에서 소유하고 있는것도 가능하다. 이러한 경우에서 잡힌 exception 은 꼭대기부터 바닥까지의 각각의 catch 블록의 클래스타입과 비교되고, 'instanceof'를 지닌 첫 블록의 매치는 실행될 것이다. catch 블록이 끝날때 실행사항은 마지막 catch 블록까지 지속된다. 만약 어떤 catch 블록도 'instanceof' 매치를 지니고 있지 않은경우, 그 다음 try/catch block이 다음 try/catch 블록이 존재하지 않고 사용가능하지 않을때까지 검색될 것이다. 이러한 경우 exception 은 exception 절을 발견하지 못하고 프로그램은 예외사항을 보여주면서 중단한다.


Example B-15. Exception creation example

<?php
try
{
  
throw new Exception('Hello'
);
}
catch (Exception $exception
) {
   echo
$exception
;
}
?>

과거에는 사용자정의된 클래스나 함수에 "catch","throw" 또는 "try"를 붙이지 않고 실행했을 것이다.

Dereferencing objects returned from functions

PHP 4 에서는 함수에 의해 반환되는 객체들의 값을 부분참조하기란 불가능했고, 더 이상의 메소드를 만드는 것은 이러한 객체를 호출하였다. PHP 5에서는 다음과 같은 것들이 가능하다 :


Example B-16. Dereferencing example

<?php
class Circle
{
   function
draw
() {
       print
"Circle\n"
;
   }
}
    
class
Square
{
   function
draw
() {
       print
"Square\n"
;
   }
}

function
ShapeFactoryMethod($shape
) {
   switch (
$shape
) {
       case
"Circle"
:
           return new
Circle
();
       case
"Square"
:
           return new
Square
();
   }
}

ShapeFactoryMethod("Circle")->draw
();
ShapeFactoryMethod("Square")->draw
();
?>

Static member variables initialization

정적 클래스의 정적 멤버 변수가 이제 초기화될 수 있다.


Example B-17. Static variable initialization example

<?php
class foo
{
   static
$my_static = 5
;
  
public $my_prop = 'bla'
;
}

print
foo::$my_static
;
$obj = new foo
;
print
$obj->my_prop
;
?>
 

PHP 5 는 메소드를 정적으로 선언하기 위해 'static' 키워드를 도입하였다. 그래서 객체의 외부 전후에서 호출할 수 있다.


Example B-18. Static Methods example

<?php
class Foo
{
  
public static function aStaticMethod
() {
      
// ...
  
}
}

Foo::aStaticMethod
();
?>

가상변수 $this 는 static으로 선언된 메소드 안에서는 사용할 수 없다.


instanceof

PHP 5 는 객체가 클래스의 인스턴스건 아니건간에 그것을 조사하고 클래스를 확장하고 인터페이스조건을 제시하게 하기 위한 instanceof  키워드를 도입하였다.


Example B-19. instanceof example

<?php
class baseClass
{ }

$a = new baseClass
;

if (
$a instanceof baseClass
) {
   echo
"Hello World"
;
}
?>
 

Static은 개발자로 하여금 참조의 방식으로 변수의 값을 상수로 전달하도록 하는 컴파일 도중에 다루어진다. 이러한 변화는 또한 그들의 성능을 엄청나게 향상시켰지만 상수로의 우회적 참조가 더이상의 일을 할 수 없음을 의미한다.


Parameters passed by reference

참조에 의해 함수로 전달된 파라미터값은 아마 이제부터 기본값을 가질 수 있을 것이다.


Example B-20.

<?php
function my_function(&$var = null
) {
   if (
$var === null
) {
       die(
"$var needs to have a value"
);
   }
}
?>
 

__autoload() 요격실행 함수는 선언되지 않은 클래스가 명시화되었을 때, 자동적으로 호출될 것이다. 해당 클래스의 이름은 __autoload() 요격실행 함수로 인자처럼 전달될 것이다.


Example B-21. __autoload() example

<?php
function __autoload($className
) {
   include_once
$className . ".php"
;
}

$object = new ClassName
;
?>
 

메소트 호출과 프로퍼티 접근은 __call(), __get() 그리고 __set() 메소드에 의해 오버로드 될 수 있다.


Example B-22. __get() and __set()

<?php
class Setter
{
  
public $n
;
  
public $x = array("a" => 1, "b" => 2, "c" => 3
);

   function
__get($nm
) {
       print
"Getting [$nm]\n"
;

       if (isset(
$this->x[$nm
])) {
          
$r = $this->x[$nm
];
           print
"Returning: $r\n"
;
           return
$r
;
       } else {
           print
"Nothing!\n"
;
       }
   }

   function
__set($nm, $val
) {
       print
"Setting [$nm] to $val\n"
;

       if (isset(
$this->x[$nm
])) {
          
$this->x[$nm] = $val
;
           print
"OK!\n"
;
       } else {
           print
"Not OK!\n"
;
       }
   }
}


$foo = new Setter
();
$foo->n = 1
;
$foo->a = 100
;
$foo->a
++;
$foo->z
++;
var_dump($foo
);
?>

Example B-23. __get() example

<?php
class Caller
{
  
private $x = array(1, 2, 3
);

   function
__call($m, $a
) {
       print
"Method $m called:\n"
;
      
var_dump($a
);
       return
$this->x
;
   }
}

$foo = new Caller
();
$a = $foo->test(1, "2", 3.4, true
);
var_dump($a
);
?>
 

객체는 아마 foreach와 같은 방식을 사용하였을때의 오버로딩하는 방법으로 반복될 수 있을 것이다. 기본적인 행동은 모든 프로퍼티를 반복한다.


Example B-24. Object iteration example

<?php
class Foo
{
  
public $x = 1
;
  
public $y = 2
;
}

$obj = new Foo
;

foreach (
$obj as $prp_name => $prop_value
) {
  
// using the property
}
?>

인스턴스의 각각의 클래스는 Traversable이라는 빈 인터페이스를 실행할 foreach로 반복될 수 있다. 따가서 적합하게 실행되는 몇몇 객체들은 foreach와 합께 사용될 수 있다.

IteratorAggregate 와 Iterator 인터페이스는 PHP 코드에서 반복사용되는 방법을 상술할 수 있도록 한다. 그것들에 있어 첫번째는 Iterator 인터페이스를 이행하거나 반복가능한 내부 클래스에서 명시회되는 배열이나 객체를 반드시 리턴해야 하는 getIterator() 라는 메소드를 포함한다.


Example B-25. Iterator creation example

<?php
class ObjectIterator implements Iterator
{

  
private $obj
;
  
private $num
;

   function
__construct($obj
) {
      
$this->obj = $obj
;
   }
   function
rewind
() {
      
$this->num = 0
;
   }
   function
valid
() {
       return
$this->num < $this->obj->max
;
   }
   function
key
() {
       return
$this->num
;
   }
   function
current
() {
       switch(
$this->num
) {
           case
0: return "1st"
;
           case
1: return "2nd"
;
           case
2: return "3rd"
;
           default: return
$this->num."th"
;
       }
   }
   function
next
() {
      
$this->num
++;
   }
}

class
Object implements IteratorAggregate
{

  
public $max = 3
;

   function
getIterator
() {
       return new
ObjectIterator($this
);
   }
}

$obj = new Object
;

// this foreach ...
foreach($obj as $key => $val
) {
   echo
"$key = $val\n"
;
}

// matches the following 7 lines with the for directive.
$it = $obj->getIterator
();
for(
$it->rewind(); $it->valid(); $it->next
()) {
  
$key = $it->current
();
      
$val = $it->key
();
         echo
"$key = $val\n"
;
}
unset(
$it
);
?>
 

새로운 __METHOD__ 가상 상수는 현재 클래스와 메소드 내부에서 메소드가 사용될 때의 메소드를 보여주고, 클래스 밖에서 사용될때의 함수를 보여준다.


Example B-26. __METHOD__ use example

<?php
class Foo
{
   function
show
() {
       echo
__METHOD__
;
   }
}

class
Bar extends Foo
{
}

Foo::show();
// outputs Foo::show
Bar::show();
// outputs Foo::show either since __METHOD__ is
             // compile-time evaluated token

function test
() {
   echo
__METHOD__
;
}

test();     
// outputs test
?>
 

새로운 __toString() 기술 메소드는 객체를 문자열 변환객체로 오버로드 하도록 한다.


Example B-27. __toString() example

<?php
class Foo
{
   function
__toString
() {
       return
"What ever"
;
   }
}

$obj = new Foo
;

echo
$obj;
// call __toString()
?>
 

PHP 5 는 재설계한 클래스와 인터페이스, 함수와 메소드를 확장요소들과 같은 기능들을 추가한 완벽한 Reflection API 와 함께 출시되었다. 

Reflection API 는 또한 함수와 클래스 그리고 메소드를 위한 도큐먼트 해설을 얻는 방법을 제공한다.

거의 모든 객체지향코드의 외관모습은 개별적으로 상세히 기록된 Reflection API를 사용함에 의해 반영될 수 있다.


Example B-28. Reflection API use example

<?php
class Foo
{
  
public $prop
;
   function
Func($name
) {
       echo
"Hello $name"
;
   }
}

reflectionClass::export('Foo'
);
reflectionObject::export(new Foo
);
reflectionMethod::export('Foo', 'func'
);
reflectionProperty::export('Foo', 'prop'
);
reflectionExtension::export('standard'
);
?>

========================================================================================

2007/05/18 19:25 2007/05/18 19:25
이 글에는 트랙백을 보낼 수 없습니다
웅쓰:웅자의 상상플러스
웅자의 상상플러스
전체 (379)
게임 (5)
영화 (2)
기타 (23)
맛집 (5)
영어 (2)
대수학 (3)
형태소 (5)
Hacking (9)
Linux (112)
HTML (48)
Application_developing (48)
Web_developing (102)
Window (11)
«   2024/04   »
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30        
  1. 2016/01 (1)
  2. 2015/12 (3)
  3. 2015/10 (3)
  4. 2015/03 (2)
  5. 2015/01 (4)