너의 개발은/PHP

PHP: 매직 메서드

매직 메서드

매직 메서드는 특수한 메서드로서 클래스에서 특별한 동작을 하게되는데, 그 중에는 PHP: 상속에서 이야기한 생성자소멸자도 포함하고 있습니다. 대체로 __ 로 시작하는 메서드 명이 그러하며 이는 사용자가 직접 호출하는 것이 아니고, 특정 행동을 취했을 경우 호출되는 콜백함수같은 것입니다. 따라서 인터페이스 규격이 정해져 있으며 그에 따라 정의해야 하고, 리턴 값또한 그러해야 합니다. 대부분 리턴값은 없는 경우가 많으나 일부 매직 메서드의 경우 존재합니다.

 

매직 매서드는 종류가 많은데, 전부 다 할 수는 없으니 임의로 몇 가지 토픽으로 나누어서 해보고자 합니다. 주제는 세 가지로, 각각 Method, Property, Serialize. 그 외에 __toString() 과 같은 것들도 있으나 생략하도록 할 것입니다.

Method

메서드와 관련된 매직 메서드는 __call(), __callStatic(), __invoke() 가 존재합니다.

__call(string, array)

클래스 내부에 정의되지 않은 메서드를 호출했을 경우 해당 매직 메서드를 호출하게 됩니다. 따라서 동적인 메서드를 호출하여 런타임 중에 새로운 메서드를 만들거나 할 경우에 유용합니다.

class A
{
    public function __call($name, $args)
    {
        var_dump(__METHOD__);
    }
}

$a = new A();
$a->foo();

__callStatic(string, array)

클래스 내부에 정의되지 않은 정적 메서드를 호출했을 경우 마찬가지로 해당 매직 메서드를 호출하게 됩니다. 활용하는 것은 __call() 과 비슷하며 차이점은 정적 메서드에 대응한다는 점입니다.

class A
{
    public static function __callStatic($name, $args)
    {
        var_dump(__METHOD__, $args);
    }
}

$a = new A();
A::foo();

__invoke(array)

인스턴스 자체를 호출할 경우에 호출되는 매직 메서드입니다. 다른 언어에서는 찾기 드문 특이한 기능 중에 하나입니다.

class A
{
    public function __invoke(...$args)
    {
        var_dump(__METHOD__, $args);
    }
}

$a = new A();
$a();

Property

프로퍼티와 관련된 매직 메서드는 __set(), __get(), __isset(), __unset() 이 있습니다. 대강 이름만 보더라도 감이 오시겠죠?

__set(string, mixed), __get(string)

프로퍼티의 값을 설정하고 얻을 때 호출되는 매직 메서드입니다. setter, getter 라고 부르기도 합니다. 하지만 값을 프로퍼티에 할당하는 행위는 매직 메서드 내부에서 해야합니다. 외부에서 할당하거나, 얻겠다고 해서 즉시 리턴되지는 않습니다.

class A
{
    // private $message = 'Hello, world';

    public function __set($name, $value)
    {
        $this->$name = $value;
    }

    public function __get($name)
    {
        $this->$name;
    }
}

$a = new A();

// -> __set
$a->message = 'Hello, world';
// -> __get
var_dump($a->message);

__isset(string): bool, __unset(string)

각각 객체를 대상으로 언어구조 isset(), unset() 을 호출했을 경우 호출되는 매직 메서드입니다. 마찬가지로 매직 메서드 내부에서 검사, 해제 로직을 별도로 구현해야 합니다.

class A
{
    private $message = 'Hello, world';

    public function __isset($name)
    {
        return isset($this->$name);
    }

    public function __unset($name)
    {
        unset($this->$name);
    }
}

$a = new A();

// -> __isset
isset($a->message);
// -> __unset
unset($a->message);

Serialize

직렬화와 관련된 매직 메서드로는 __sleep(), __wakeup() 이 있습니다. 각각 serizlie(), unserialize() 호출시 호출됩니다. 사실 직렬화는 매직 메서드, 그리고 Serializable 인터페이스를 구현, 이렇게 두 가지의 방법으로 할 수 있습니다. 둘 다 보여드리도록 하겠습니다.

__sleep(): array, __wakeup()

__sleep() 매직 메서드는 리턴 값이 정해져 있는데, 직렬화할 프로퍼티를 지정해줄 수 있습니다.

class A
{
    private $sayHello = 'Hello, world';

    public function __sleep()
    {
        return [ 'sayHello' ];
    }

    public function __wakeup()
    {
        var_dump(__METHOD__);
    }
}

Serializable

Serializable 인터페이스를 구현하여 직렬화를 처리할 수 있습니다. 해당 포스팅은 매직 메서드와 관련된 이야기를 하고 있지만, 직렬화를 이야기 하는겸 같이 언급하기로 했습니다.

class A implements Serializable
{
    private $sayHello = 'Hello, world';

    public function serialize()
    {
        return serialize($this->sayHello);
    }

    public function unserialize($serialized)
    {
        $this->sayHello = unserialize($serialized);
    }
}

$a = new A();
$serialized = serialize($a);

var_dump(unserialize($serialized));

 

 

PHP 7+ 프로그래밍: 리부트 - 인프런

기초 문법부터 내장 함수, 웹 보안, 게시판 만들기까지 PHP 언어를 시작하는 분들을 위해 바이블이 될 수 있게 만들어보고자 하는 마음으로 이번 강좌를 만들어보았습니다. 입문 웹 개발 프로그��

www.inflearn.com

 

PHP 7+ 프로그래밍: 객체지향 - 인프런

PHP 객체지향, 내장 클래스, PSR, Composer, MVC(Model, View, Controller)까지 모던 PHP를 익히기 위한 근간을 이야기합니다. 초급 프로그래밍 언어 알고리즘 PHP 객체지향 알고리즘 온라인 강의 모던 PHP 프로��

www.inflearn.com