PHP에서 :: (이중 콜론)과-> (화살표)의 차이점은 무엇입니까?


197

PHP에서 메소드에 액세스하는 두 가지 방법이 있지만 차이점은 무엇입니까?

$response->setParameter('foo', 'bar');

sfConfig::set('foo', 'bar');

->변수 ::( 부호 또는 쉐브론보다 큰 대시)가 변수의 함수에 사용되고 (더블 콜론)이 클래스의 함수에 사용 된다고 가정 합니다. 옳은?

는 IS =>할당 연산자는 배열 내 할당 데이터를 저장하는 데 사용? =변수를 인스턴스화하거나 수정하는 데 사용되는 대입 연산자 와 대조 되는가?



답변:


173

왼쪽 부분이 객체 인스턴스이면을 사용 ->합니다. 그렇지 않으면을 사용 ::합니다.

이는 ->주로 인스턴스 멤버에 액세스하는 데 사용되며 (정적 멤버에 액세스하는데도 사용할 수 있지만 이러한 사용은 권장되지 않음) ::일반적으로 정적 멤버에 액세스하는 데 사용됩니다 (특별한 경우에는 인스턴스 멤버에 액세스하는 데 사용됨) ).

일반적으로 ::사용되는 범위 해상도 , 그리고 중 하나를 가질 수있다 클래스 이름 parent, self또는 (PHP 5.3) static의 왼쪽. parent클래스가 사용되는 클래스의 수퍼 클래스 범위를 나타냅니다. self사용되는 클래스의 범위를 나타냅니다. static"범위"라고합니다 ( 늦은 정적 바인딩 참조 ).

규칙은 다음과 같은 ::경우에만 with를 호출하는 것 입니다.

  • 대상 방법은 정적으로 선언되지
  • 호출 시점에 호환 가능한 객체 컨텍스트가 있습니다. 이는 다음과 같은 사실이어야합니다.
    1. $this존재 하는 상황에서 호출
    2. 의 클래스는 $this호출되는 메소드의 클래스이거나 서브 클래스입니다.

예:

class A {
    public function func_instance() {
        echo "in ", __METHOD__, "\n";
    }
    public function callDynamic() {
        echo "in ", __METHOD__, "\n";
        B::dyn();
    }

}

class B extends A {
    public static $prop_static = 'B::$prop_static value';
    public $prop_instance = 'B::$prop_instance value';

    public function func_instance() {
        echo "in ", __METHOD__, "\n";
        /* this is one exception where :: is required to access an
         * instance member.
         * The super implementation of func_instance is being
         * accessed here */
        parent::func_instance();
        A::func_instance(); //same as the statement above
    }

    public static function func_static() {
        echo "in ", __METHOD__, "\n";
    }

    public function __call($name, $arguments) {
        echo "in dynamic $name (__call)", "\n";
    }

    public static function __callStatic($name, $arguments) {
        echo "in dynamic $name (__callStatic)", "\n";
    }

}

echo 'B::$prop_static: ', B::$prop_static, "\n";
echo 'B::func_static(): ', B::func_static(), "\n";
$a = new A;
$b = new B;
echo '$b->prop_instance: ', $b->prop_instance, "\n";
//not recommended (static method called as instance method):
echo '$b->func_static(): ', $b->func_static(), "\n";

echo '$b->func_instance():', "\n", $b->func_instance(), "\n";

/* This is more tricky
 * in the first case, a static call is made because $this is an
 * instance of A, so B::dyn() is a method of an incompatible class
 */
echo '$a->dyn():', "\n", $a->callDynamic(), "\n";
/* in this case, an instance call is made because $this is an
 * instance of B (despite the fact we are in a method of A), so
 * B::dyn() is a method of a compatible class (namely, it's the
 * same class as the object's)
 */
echo '$b->dyn():', "\n", $b->callDynamic(), "\n";

산출:

B :: $ prop_static : B :: $ prop_static 값
B :: func_static () :에서 B :: func_static

$ b-> prop_instance : B :: $ prop_instance 값
$ b-> func_static () : B :: func_static에서

$ b-> func_instance () :
B :: func_instance에서
A :: func_instance에서
A :: func_instance에서

$ a-> dyn () :
A :: callDynamic에서
동적 dyn에서 (__callStatic)

$ b-> dyn () :
A :: callDynamic에서
동적 dyn (__ call)

3
" ->대부분 인스턴스 멤버에 액세스하는 데 사용됩니다 (정적 멤버에 액세스하는데도 사용할 수 있지만 이러한 사용법은 권장되지 않습니다)". 따라서 정적 멤버에 액세스 할 때 어떤 방식으로 "기능"을 수행하는 경우-이와 같이 잘못 사용하면 동작의 차이점이 무엇입니까? 그냥 호기심.
lucideer

4
@lucideer 정적 메소드의 경우 좋은 연습 문제입니다 (메소드가 클래스 자체에 속함). 그러나 정적 메소드를로 호출하면 PHP는 불평하지 않습니다 ->. 물론 정적 메소드를 호출하기 위해 클래스를 인스턴스화해야 할 수도 있으므로 성능이 저하됩니다. 그러나 속성에는 더 많은 문제가 있습니다. STRICT 경고가 발생하여 작동하거나 작동하지 않을 수 있습니다 . 반대의 경우도 마찬가지입니다. 인스턴스 메소드를 정적으로 호출 할 수는 있지만 더 나쁩니다 ( $this그러한 메소드 구현 에서는 사용할 수 없습니다 ).
Artefacto

52

::정적 컨텍스트 에서 사용됩니다 . 즉 일부 메소드 또는 특성이 정적으로 선언 된 경우 :

class Math {
    public static function sin($angle) {
        return ...;
    }
}

$result = Math::sin(123);

또한 ::연산자 (Scope Resolution Operator, 일명 Paamayim Nekudotayim )는 부모 클래스의 메서드 / 속성을 호출 할 때 동적 컨텍스트에서 사용됩니다.

class Rectangle {
     protected $x, $y;

     public function __construct($x, $y) {
         $this->x = $x;
         $this->y = $y;
     }
}

class Square extends Rectangle {
    public function __construct($x) {
        parent::__construct($x, $x);
    }
}

->동적 컨텍스트 에서 사용됩니다 . 어떤 클래스의 인스턴스를 다룰 때 :

class Hello {
    public function say() {
       echo 'hello!';
    }
}

$h = new Hello();
$h->say();

그건 그렇고 : OOP 경험이없는 경우 Symfony를 사용하는 것이 좋습니다 생각하지 않습니다.


24

실제로이 기호로 정적이며 다른 초기화에 의존하지 않는 클래스 메소드를 호출 할 수 있습니다 ...

class Test {

    public $name;

    public function __construct() {
        $this->name = 'Mrinmoy Ghoshal';
    }

    public static function doWrite($name) {
        print 'Hello '.$name;
    }

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

여기서 doWrite()함수는 다른 메소드 나 변수에 종속되지 않으며 정적 메소드입니다. 그렇기 때문에이 클래스의 객체를 초기화하지 않고이 연산자로이 메소드를 호출 할 수 있습니다.

Test::doWrite('Mrinmoy'); // Output: Hello Mrinmoy.

그러나 write이런 방식으로 메서드 를 호출하려는 경우 초기화에 의존하기 때문에 오류가 발생합니다.


16

=>연산자는 결합 배열에 할당 된 키 - 값 쌍으로 사용된다. 예를 들면 다음과 같습니다.

$fruits = array(
  'Apple'  => 'Red',
  'Banana' => 'Yellow'
);

foreach문장 의 의미는 비슷 합니다 :

foreach ($fruits as $fruit => $color)
  echo "$fruit is $color in color.";

14

정적 메소드와 인스턴스화 메소드와 속성의 차이점은 PHP 5에서 OOP PHP로 시작하는 사람들에게 가장 큰 장애물 중 하나 인 것 같습니다.

이중 콜론 연산자 (히브리어의 Paamayim Nekudotayim-퀴즈)는 정적 컨텍스트 에서 객체 또는 속성을 호출 할 때 사용됩니다 . 이것은 객체의 인스턴스가 아직 생성되지 않았 음을 의미합니다.

반대로 화살표 연산자는 객체의 인스턴스를 참조하여 메소드 또는 속성을 호출합니다.

정적 메소드는 리턴 값을 삽입 된 테이블 ID로 설정 한 다음 생성자를 사용하여 행 ID로 오브젝트를 인스턴스화 할 수 있으므로 메소드 작성 및 삭제 메소드를 위해 데이터베이스에 링크 된 오브젝트 모델에서 특히 유용 할 수 있습니다.


2

예, 방금 첫 번째 공격을 받았습니다 'PHP Parse error: syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM'. 내 나쁜, 내가 가지고 $instance::method()있었어야 것을 $instance->method(). 바보 나.

이상한 점은 이것이 여전히 로컬 컴퓨터 (PHP 5.3.8 실행)에서 잘 작동한다는 것입니다-error_reporting = E_ALL의 경고조차도 없지만 테스트 서버에서는 전혀 그렇지 않습니다. 구문 오류로 폭발합니다. 브라우저의 흰색 화면. 테스트 머신에서 PHP 로깅이 꺼졌고 호스팅 회사가 너무 바쁘기 때문에 너무 명확하지 않았습니다.

따라서 경고의 말씀 : 분명히 일부 PHP 설치에서는 $ instance :: method ()를 사용할 수 있지만 다른 PHP는 그렇지 않습니다.

그 이유에 대해 아무도 확장 할 수 없다면 그렇게하십시오.

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