너의 개발은/PHP

PHP: Static (정적 변수, 정적 메서드, 늦은 정적 바인딩)

Static

static 키워드는 PHP 언어에서 대략 세 가지의 의미로 쓰이는데 정적 변수 선언, 정적 메서드, 늦은 정적 바인딩입니다.  특히나 늦은 정적 바인딩의 경우 조금 헷갈리는 요소도 있으니 주의해야 합니다.

정적 변수 선언

함수 내부에서 일반적으로 변수를 사용하면 함수 호출이 끝나고 스택에서 로컬 변수가 사라져야 하지만, static 변수쓰면 값을 유지할 수 있도록 해주는데, 이에 관한 이야기는 이번 포스팅에서는 크게 언급하지 않을 것이고, 자세한 사항은 PHP: 변수를 참고해주시기 바랍니다.

정적 메서드

메서드 선언 시 static 키워드를 함께 적음으로서 정의합니다. 클래스 로드시 정적 공간 메모리에 할당되므로 this 에 바로 접근할 수 없으며 self:: 와 같은 문맥 키워드를 적어야 합니다. 정적인 것은 상태가 아니므로 객체가 이를 공유하게 됩니다. 또한 객체에서도 접근할 수 있습니다. 정적 메서드를 사용하는 경우라면, 상태를 사용할 필요가 없거나 유틸리티의 특성을 가진 클래스라면 주로 정적 메서드로 구성되어 있습니다.

class A
{
    public static $message = 'Hello, world';

    public static function foo()
    {
        // return $this->message;
        return self::$message;
    }
}

$classname = 'A';

$a = new $classname();
echo $a->foo();

// echo $classname::foo();

늦은 정적 바인딩

클래스의 메서드 내부에서 static 으로 메서드를 호출하려면 늦은 정적 바인딩을 할 수 있습니다. 상속 관계에서 이를 활용하는 경우가 많으며 코드를 보면 다음과 같습니다.

class A
{
    public static function foo()
    // public function foo()
    {
        static::who();
    }

    public static function who()
    // public function who()
    {
        var_dump(__CLASS__);
    }
}

class B extends A
{
    public static function test()
    // public function test()
    {
        A::foo(); // -> A

        parent::foo(); // -> B
        self::foo(); // -> B
    }

    public static function who()
    // public function who()
    {
        var_dump(__CLASS__);
    }
}

$b = new B();
$b->test();

현재 클래스의 메서드들은 정적 메서드의 형태로 정의되어 있으며, B::test() 메서드에서 foo() 메서드를 호출하고 있는데, PHP: 클래스에서 이야기한 문맥 키워드들을 사용하고 있습니다. 가장 애매한 A::foo() 이외에 다른 것들을 먼저 살펴보죠.

parent::foo()

부모 클래스, A::foo() 를 호출하고, static::who() 를 호출하고 있으므로 B::who() 가 호출되어 결과 값으로 B 가 나옵니다.

self::foo()

현재 자식 클래스에 A::foo() 메서드가 재정의 되어 있지 않으므로 A::foo() 가 현재 스코프입니다. 따라서 마찬가지로 결과값이 B가 나옵니다. 그러나 B::foo() 메서드가 정의되어 있다면, 여기서 self::foo()B::foo() 가 되므로 주의해주십시오.

A::foo()

이 녀석은 정적 메서드일 때와 비정적 메서드의 상황에서 다른 결과를 초래합니다. 위의 코드에서 정적인 상황에서는 결과값으로 A 가 나오는데, parent::foo() 와 결과가 다른 것을 보고 이상하다는 생각이 들 것입니다.

 

결과적으로 이야기하자면, A::foo() 형태로 호출하면 호출 정보가 전달되지 않아서 생기는 결과입니다. 물론 비정적인 상황에서 저렇게 호출되면 결과값으로 B 가 나오게 됩니다.

Late static bindings' resolution will stop at a fully resolved static call with no fallback. On the other hand, static calls using keywords like parent:: or self:: will forward the calling information.

 

 

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

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

www.inflearn.com

 

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

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

www.inflearn.com