new self ();는 무엇을합니까? PHP에서 의미합니까?


110

다음과 같은 코드는 본 적이 없습니다.

public static function getInstance()
{
    if ( ! isset(self::$_instance)) {
        self::$_instance = new self();
    }
    return self::$_instance;
}

과 동일 new className()합니까?

편집하다

클래스가 상속인 경우 어떤 클래스를 가리 킵니까?



@stereofrog, 싱글 톤 패턴을 버려야한다는 뜻인가요?하지만 모든 것에는 이유가 있습니다.
user198729 2010 년

오, 저는이 점에 동의하는 경향이 있습니다 : 싱글 톤은 공장으로 교체되어야합니다
user198729

@stereofrog Singleton은 단위 테스트에 독이 있으며 한 호출에서 다음 호출로 상태를 변경하는 무언가에 대해 불변 테스트를 만드는 것은 매우 어렵습니다.
David

불행히도이 방법은 확장되지 않습니다. 항상이 함수가 정의 된 클래스의 새 개체를 제공합니다.
아레스

답변:


211

self 작성되는 클래스를 가리 킵니다.

따라서 getInstance 메서드가 클래스 이름 MyClass에있는 경우 다음 줄은 다음과 같습니다.

self::$_instance = new self();

다음과 같은 작업을 수행합니다.

self::$_instance = new MyClass();



편집 : 주석 후 몇 가지 추가 정보.

서로 확장하는 두 개의 클래스가있는 경우 두 가지 상황이 있습니다.

  • getInstance 자식 클래스에 정의되어 있습니다.
  • getInstance 부모 클래스에 정의되어 있습니다.

첫 번째 상황은 다음과 같습니다 (이 예제에서는 필요하지 않은 모든 코드를 제거했습니다. 싱글 톤 동작을 얻으려면 다시 추가해야합니다) * :

class MyParentClass {

}
class MyChildClass extends MyParentClass {
    public static function getInstance() {
        return new self();
    }
}

$a = MyChildClass::getInstance();
var_dump($a);

여기에서 얻을 수 있습니다.

object(MyChildClass)#1 (0) { } 

어떤 의미 self수단을 MyChildClass- 즉 성경에 기록되어있는 클래스입니다.


두 번째 상황의 경우 코드는 다음과 같습니다.

class MyParentClass {
    public static function getInstance() {
        return new self();
    }
}
class MyChildClass extends MyParentClass {

}

$a = MyChildClass::getInstance();
var_dump($a);

그리고 이런 종류의 출력을 얻을 수 있습니다.

object(MyParentClass)#1 (0) { }

어떤 수단의 self수단 MyParentClass- 즉, 현재도 이 기록 된 클래스 .




PHP <5.3에서는 "작성되는 클래스"가 중요하며 때때로 문제를 일으킬 수 있습니다.

이것이 바로 PHP 5.3에서 static키워드에 대한 새로운 사용법을 도입 한 이유입니다 . 이제 self해당 예제에서 사용한 곳에서 정확히 사용할 수 있습니다 .

class MyParentClass {
    public static function getInstance() {
        return new static();
    }
}
class MyChildClass extends MyParentClass {

}

$a = MyChildClass::getInstance();
var_dump($a);

그러나 static대신을 사용 self하면 다음을 얻을 수 있습니다.

object(MyChildClass)#1 (0) { } 

즉 , 작성된 클래스가 아니라 사용 된 (우리가 사용한 ) 클래스를static 가리 킵니다 .MyChildClass::getInstance()

물론 self기존 애플리케이션을 손상시키지 않도록 의 동작은 변경되지 않았습니다. PHP 5.3은 새로운 동작을 추가하여 static키워드를 재활용했습니다 .


그리고 PHP 5.3에 대해 말하면 PHP 매뉴얼 의 Late Static Bindings 페이지를 살펴볼 수 있습니다.


@Paul : heu ...는 "self는 별칭 역할을한다", 또는 "self 일종의 지적"을 의미합니다. 프랑스어로 된 "designer"동사를 사용할 수 있습니다. 그게 상황 중 하나라고 생각합니다. 있는 영어로 같은 단어를 사용하는 것은 좋은 생각하지 ;-( 나는이; 감사 :-) 해결하기 위해 내 대답은 편집 할 수 있습니다
파스칼 MARTIN

이 경우 어떻게 baseclass, class그것은 어떤 일을하는 포인트는 무엇입니까?
user198729 2010 년

@user : 나는 self상속 에 대한 더 많은 정보를 제공하기 위해 내 대답을 편집했습니다 . 그리고 staticPHP 5.3 에 대한 몇 가지 정보도 포함 시켰습니다 ;; 이것이 도움이되기를 바랍니다 :-)
Pascal MARTIN

10

이것은 Singleton 패턴 의 구현 인 것 같습니다 . 이 함수는 정적으로 호출되고 정적 클래스에 변수 $_instance세트 가 있는지 확인합니다 .

그렇지 않은 경우 자체 인스턴스 ( new self())를 초기화하고 $_instance.

호출 className::getInstance()하면 모든 호출에서 하나의 동일한 클래스 인스턴스를 얻게 되는데, 이는 싱글 톤 패턴의 포인트입니다.

나는 이것이 이런 식으로 한 것을 본 적이 없으며 솔직히 그것이 가능하다는 것을 몰랐다. $_instance클래스에서 선언 된 것은 무엇입니까 ?


1
$_instance로 선언public static $_instance;
ATIF

7

이것은 생성자가 인스턴스화되는 것을 피하기 위해 private로 정의되는 싱글 톤 디자인 패턴에서 가장 많이 사용되며, 이중 콜론 (::)연산자는 클래스 내에서 정적으로 선언 된 멤버에 액세스 할 수 있으므로 정적 멤버가있는 경우 의사 변수 $ 이것은 사용할 수 없으므로 대신 자체 코드를 사용합니다. Singletons는 데이터베이스 커넥터 처리기와 같은 개체의 인스턴스 하나만 허용하는 좋은 프로그래밍 관행입니다. 클라이언트 코드에서 해당 인스턴스에 액세스하는 것은 단일 액세스 포인트를 생성하여 수행됩니다.이 경우 그는 이름을 지정했습니다 getInstance(). getInstance 자체는 기본적으로 new 키워드를 사용하여 생성자 메서드가 의미하는 객체를 생성하는 객체를 생성 한 함수였습니다. 또한 호출됩니다.

라인 if(!isset(self::instance))은 객체가 이미 생성되었는지 확인합니다. 코드가 조각 일 뿐이므로 상단 어딘가에 정적 멤버가 있어야합니다.

private static $_instance = NULL; 

일반 클래스에서는 간단하게이 멤버에 액세스했을 것입니다.

$this->_instance = 'something';

하지만 정적으로 선언되었으므로 대신 사용하는 $ this 코드를 사용할 수 없습니다.

self::$_instance

이 정적 클래스 변수에 저장된 객체가 있는지 확인하여 클래스는 단일 인스턴스를 만들지 여부를 결정할 수 있으므로, 설정되지 않은 경우! isset (정적 멤버 $ _instance에 객체가 없음을 의미 함) 새 개체를 생성 $_instance하고 명령에 의해 정적 멤버 에 저장합니다.

self::$_instance = new self();

클라이언트 코드로 반환했습니다. 그러면 클라이언트 코드는 공용 메서드와 함께 개체의 단일 인스턴스를 즐겁게 사용할 수 있지만 클라이언트 코드에서는 단일 액세스 포인트를 호출합니다. 즉, getInstance()메서드도 까다롭기 때문에 다음과 같이 호출해야합니다.

$thisObject = className::getInstance();

그 이유는 함수 자체가 정적으로 선언되기 때문입니다.


2

예, new className()(해당 메서드를 포함하는 클래스를 참조 함) 생성자가 private 인 Singleton 패턴에서 사용되는 것과 같습니다.


왜 누군가 PHP에서 Singleton 패턴을 사용합니까? 데몬과 같은 프로그램에서 사용하지 않는 한 싱글 톤은 스크립트가 실행되는 동안에 만 존재하고 프로그램과 함께 사라집니다.
ILikeTacos 2013 년

4
초조 전역 변수에 액세스 할 글로벌 선언 피하기 위해
샘 Adamsh

0

클래스가 상속 된 경우 자식에서 getInstance ()를 호출하면 자식 인스턴스가 제공되지 않습니다. 부모 인스턴스의 인스턴스 만 반환합니다. 이는 new self ()를 호출하기 때문입니다.

자식 클래스가 자식 클래스의 인스턴스를 반환하도록하려면 getInstance ()에서 new static ()을 사용하고 자식 클래스 인스턴스를 반환합니다. 이것을 후기 바인딩이라고합니다 !!

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.