복붙노트

이중 콜론 (:)으로 비 정적 메서드 호출

PHP

이중 콜론 (:)으로 비 정적 메서드 호출

왜 정적 메서드 (class :: method)의 구문과 함께 정적이 아닌 메서드를 사용할 수 없습니까? 구성 문제일까요?

class Teste {

    public function fun1() {
        echo 'fun1';
    }
    public static function fun2() {
        echo "static fun2" ;
    }
}

Teste::fun1(); // why?
Teste::fun2(); //ok - is a static method

해결법

  1. ==============================

    1.PHP는 정적 인 방법과 비 정적 인 방법이 매우 유사합니다. 여기에 언급되지 않은 한 가지는 정적이 아닌 메서드를 호출하면 클래스 C의 비 정적 메서드 내에서 정적으로 ns를 호출하면 n이 n의 내부에서 C의 인스턴스를 참조한다는 것입니다.

    PHP는 정적 인 방법과 비 정적 인 방법이 매우 유사합니다. 여기에 언급되지 않은 한 가지는 정적이 아닌 메서드를 호출하면 클래스 C의 비 정적 메서드 내에서 정적으로 ns를 호출하면 n이 n의 내부에서 C의 인스턴스를 참조한다는 것입니다.

    class A 
    {
        public function test()
        {
            echo $this->name;
        }
    }
    
    class C 
    {
         public function q()
         {
             $this->name = 'hello';
             A::test();
         }
    }
    
    $c = new C;
    $c->q();// prints hello
    

    이것은 엄격한 오류보고 기능이있는 경우 실제로는 오류가 있지만 그렇지 않은 경우에는 오류입니다.

  2. ==============================

    2.이것은 PHP의 "기발한"것으로 알려져 있습니다. 그것은 의도적으로 객체를 인스턴스화했는지 여부를 알아 내기위한 역 전파 (back-propagation)를 막기위한 것입니다 (PHP가 해석되고 컴파일되지 않음을 기억하십시오). 그러나 객체가 인스턴스화되지 않은 경우 비제 정적 멤버를 통해 비 스코프 범위 분석 연산자에 액세스하면 치명적인 오류가 발생합니다.

    이것은 PHP의 "기발한"것으로 알려져 있습니다. 그것은 의도적으로 객체를 인스턴스화했는지 여부를 알아 내기위한 역 전파 (back-propagation)를 막기위한 것입니다 (PHP가 해석되고 컴파일되지 않음을 기억하십시오). 그러나 객체가 인스턴스화되지 않은 경우 비제 정적 멤버를 통해 비 스코프 범위 분석 연산자에 액세스하면 치명적인 오류가 발생합니다.

    PHP.net의 의례 :      클래스 사용자 {     const GIVEN = 1; // 클래스 상수는 정적 또는 할당 된 가시성으로 레이블 될 수 없습니다.     public $ a = 2;     public static $ b = 3;     public function me () {         echo "print me";     }      공공 정적 함수 당신 () {         echo "print you";     } } class myUser는 사용자 { } // 클래스의 객체에 인스턴스화 된 속성 및 메소드는 액세스 할 수 있습니까? // $ object1 = 새 사용자 (); // 다음 줄마다 개별적으로 주석 처리를 해제하십시오. // echo $ object1-> GIVEN. ""; // 아무것도 산출하지 않는다. // echo $ object1-> GIVE. ""; // 의도적으로 이름을 잘못 지정했지만 여전히 아무것도 산출하지 않습니다. // echo $ object1-> User :: GIVEN. ""; // 아무것도 산출하지 않는다. // echo $ object1-> a. ""; // 2를 산출한다. // echo $ object1-> b. ""; // 아무것도 산출하지 않는다. // echo $ object1-> me (). ""; // yields print me // echo $ object1-> you (). ""; // yields print you // 하위 클래스의 객체에 인스턴스화 된 속성 및 메서드 &는 액세스 할 수 있습니까? // $ object2 = new myUser (); // 다음 줄마다 개별적으로 주석 처리를 해제하십시오. // echo $ object2-> GIVEN. ""; // 아무것도 산출하지 않는다. // echo $ object2-> a. ""; // 2를 산출한다. // echo $ object2-> b. ""; // 아무것도 산출하지 않는다. // echo $ object2-> me (). ""; // yields print me // echo $ object2-> you (). ""; // yields print you // 속성과 메서드는 클래스에서 직접 액세스 할 수 있습니까? // echo User :: GIVEN. ""; // yields 1 // echo User :: $ a. ""; 정적이 아니기 때문에 // 치명적인 오류가 발생합니다. // echo User :: $ b. ""; // yields 3 // echo User :: me (). ""; // yields print me // echo User :: you (). ""; // yields print you // 속성과 메소드가 자식 클래스에 복사되고 액세스 할 수 있습니까? // echo myUser :: GIVEN. ""; // yields 1 // echo myUser :: $ a. ""; 정적이 아니기 때문에 // 치명적인 오류가 발생합니다. // echo myUser :: $ b. ""; // yields 3 // echo myUser :: me (). ""; // yields print me // echo myUser :: you (). ""; // yields print you ?>

  3. ==============================

    3.PHP 4는 (함수 선언 문맥에서) 정적 키워드를 가지지 않았지만, ::는 정적으로 호출 할 수있는 메소드를 허용했습니다. PHP 5에서는 하위 호환성을 위해 계속했습니다.

    PHP 4는 (함수 선언 문맥에서) 정적 키워드를 가지지 않았지만, ::는 정적으로 호출 할 수있는 메소드를 허용했습니다. PHP 5에서는 하위 호환성을 위해 계속했습니다.

  4. ==============================

    4.이것은 PHP 4 하위 호환성입니다. PHP 4에서는 객체 메소드와 정적 클래스 메소드로 작성된 전역 함수가 다를 수 없습니다. 그러므로 둘 다 일했다.

    이것은 PHP 4 하위 호환성입니다. PHP 4에서는 객체 메소드와 정적 클래스 메소드로 작성된 전역 함수가 다를 수 없습니다. 그러므로 둘 다 일했다.

    그러나 PHP 5 (http://php.net/oop5)를 사용한 객체 모델의 변경으로 정적 키워드가 도입되었습니다.

    그리고 PHP 5.1.3부터 ​​다음과 같은 것들에 대한 적절한 엄격한 표준 경고를 얻습니다 :

    그리고 / 또는 :

    개발 설정을 활성화해야합니다. 따라서 언어가 충분히 다를 수 없기 때문에 런타임에 "정의 된"시간에 대한 하위 호환성 만 있습니다.

    요즘에는 코드에서 이미 정의 할 수 있지만 여전히 "잘못"이라고 부르는 경우 코드가 손상되지 않습니다.

    일부 데모는 오류 메시지를 트리거하고 다른 PHP 버전에서 변경된 동작을 표시합니다. http://3v4l.org/8WRQH

  5. ==============================

    5.이렇게 할 수는 있지만 fun1 ()이라는 함수에서 $ this를 사용하면 코드가 잘못됩니다.

    이렇게 할 수는 있지만 fun1 ()이라는 함수에서 $ this를 사용하면 코드가 잘못됩니다.

  6. ==============================

    6.경고 PHP 7에서 정적이 아닌 메소드를 정적으로 호출하는 것은 더 이상 사용되지 않으며 E_DEPRECATED 경고를 생성합니다. 비 정적 메소드를 정적으로 호출하는 지원은 앞으로 제거 될 수 있습니다.

    경고 PHP 7에서 정적이 아닌 메소드를 정적으로 호출하는 것은 더 이상 사용되지 않으며 E_DEPRECATED 경고를 생성합니다. 비 정적 메소드를 정적으로 호출하는 지원은 앞으로 제거 될 수 있습니다.

    링크

  7. ==============================

    7.대부분의 언어에서는 인스턴스 메소드를 수행하기 위해 클래스의 인스턴스가 있어야합니다. PHP는 범위 분석 연산자를 사용하여 인스턴스 메소드를 호출 할 때 임시 인스턴스를 생성합니다.

    대부분의 언어에서는 인스턴스 메소드를 수행하기 위해 클래스의 인스턴스가 있어야합니다. PHP는 범위 분석 연산자를 사용하여 인스턴스 메소드를 호출 할 때 임시 인스턴스를 생성합니다.

  8. ==============================

    8.PHP가 이것을 허용하는 이유는 모르겠지만 습관적으로하고 싶지는 않습니다. 귀하의 예제는 클래스의 비 정적 속성에 액세스하려고 시도하지 않기 때문에 작동합니다.

    PHP가 이것을 허용하는 이유는 모르겠지만 습관적으로하고 싶지는 않습니다. 귀하의 예제는 클래스의 비 정적 속성에 액세스하려고 시도하지 않기 때문에 작동합니다.

    간단한 것 :

    <?php
    class Foo {
    
        private $color;
    
        public function bar() {
            echo 'before';
            $this->color = "blue";
            echo 'after';
        }
    }
    
    Foo::bar();
    

    치명적인 오류가 발생합니다.

  9. ==============================

    9.클래스 내에서 비 ​​정적 메서드 self :: test ()를 호출하면 Class :: test ()를 호출 할 때처럼 엄격한 표준에 대한 경고가 발행되지 않습니다. 내 수업이 연장되지 않았기 때문에 이것이 LSB와 관련이 없다고 생각합니다 (PHP 5.5에서 테스트)?

    클래스 내에서 비 ​​정적 메서드 self :: test ()를 호출하면 Class :: test ()를 호출 할 때처럼 엄격한 표준에 대한 경고가 발행되지 않습니다. 내 수업이 연장되지 않았기 때문에 이것이 LSB와 관련이 없다고 생각합니다 (PHP 5.5에서 테스트)?

  10. from https://stackoverflow.com/questions/3754786/calling-non-static-method-with-double-colon by cc-by-sa and MIT license