PHP 치명적 오류 : 객체 컨텍스트에 없을 때 $ this 사용


137

문제가 있습니다 :

프레임 워크없이 새로운 WebApp을 작성하고 있습니다.

index.php에서 나는 다음을 사용하고있다 :require_once('load.php');

그리고에 load.php 내가 사용하고 require_once('class.php');내로드 class.php을 .

class.php 에서이 오류가 발생했습니다 :

치명적인 오류 : class.php의 객체 컨텍스트에 없을 때 $ this 사용 ... (이 예제에서는 11입니다)

class.php 를 작성 하는 방법의 예 :

class foobar {

    public $foo;

    public function __construct() {
        global $foo;

        $this->foo = $foo;
    }

    public function foobarfunc() {
        return $this->foo();
    }

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

index.php에서foobarfunc() 다음과 같이 로드 하고 있습니다.

foobar::foobarfunc();

하지만 또한

$foobar = new foobar;
$foobar->foobarfunc();

왜 오류가 발생합니까?


2
우연히 나는 어제 약 3 시간 동안이 오류로 어려움을 겪고있었습니다! :)
Jack

답변:


184

내 index.php에서 다음과 같이 foobarfunc ()을로드하고 있습니다.

 foobar::foobarfunc();  // Wrong, it is not static method

하지만 또한

$foobar = new foobar;  // correct
$foobar->foobarfunc();

정적 메소드가 아니기 때문에이 방법으로 메소드를 호출 할 수 없습니다.

foobar::foobarfunc();

대신 다음을 사용해야합니다.

foobar->foobarfunc();

그러나 정적 메소드를 작성한 경우 다음과 같습니다.

static $foo; // your top variable set as static

public static function foo() {
    return self::$foo;
}

그런 다음 이것을 사용할 수 있습니다 :

foobar::foobarfunc();

1
이름이 같은 변수는 문제가되지 않습니다. $this->foo는 클래스 멤버이며 $foo함수 범위 (글로벌 범위에서 가져옴)의 변수 일뿐입니다. 멤버와 이름이 같은 함수 이름도 문제가되지 않습니다.
Gordon

157
$this정적 메서드 에는 사용할 수 없습니다 .
Yacoby

5
그럼에도 불구하고 완전히 틀린 대답이 어떻게 공감을 얻는지는 재미있다. $이 클래스 컨텍스트에서 사용할 수 없습니다. 위의 예에서 OP는 동일한 오류를 얻습니다.
Gordon

4
@Sarfraz 위법 행위는 없지만 여전히 잘못되었습니다. 로 인스턴스 메소드를 호출 있습니다:: . 그것은 반대 E_STRICT하지만, 하지 긴 메소드 본문이, 예를 들어, 사용하는 인스턴스 범위를 참조하지 않는 한 일을 $this. 또한을 self::foo가리 키지 않습니다 $this->foo. 클래스 상수를 참조합니다 . 둘, self::foo그리고 self::$foo치명적 오류가 발생합니다.
Gordon

3
@Sarfraz 이제는 더 나아졌습니다. 당신을 괴롭히는 것에 대해 유감스럽게 생각하지만, 이것이 대답으로 받아 들여지면서 다음 사항을 지적해야한다고 생각했습니다.
Gordon

27

정적이 아닌 메소드를 호출하고 있습니다.

public function foobarfunc() {
    return $this->foo();
}

정적 호출 사용 :

foobar::foobarfunc();

정전기 전화를 사용하는 경우, 함수가 호출됩니다 (으로 선언되지 않더라도 static) 객체의 어떤 인스턴스가 없기 때문에,하지만, 전혀 없다 $this.

그래서 :

  • 비 정적 메소드에 정적 호출을 사용해서는 안됩니다.
  • 정적 메서드 (또는 정적으로 호출되는 메서드)는 정적 호출을 사용할 때 클래스 인스턴스가 없기 때문에 일반적으로 클래스의 현재 인스턴스를 가리키는 $ this를 사용할 수 없습니다.


여기에서 클래스의 메서드는 클래스의 $foo속성에 액세스해야하므로 클래스의 현재 인스턴스를 사용하고 있습니다.

즉, 메소드에는 클래스의 인스턴스가 필요합니다. 즉, 정적 일 수 없습니다.

이것은 정적 호출을 사용해서는 안된다는 것을 의미합니다. 클래스의 인스턴스를 작성하고 객체를 사용하여 마지막 코드 부분에서와 같이 메소드를 호출해야합니다.

$foobar = new foobar();
$foobar->foobarfunc();


자세한 내용은 PHP 매뉴얼에서 주저하지 말고 읽으십시오.


또한 __construct메소드 에이 줄이 필요하지 않을 수도 있습니다 .

global $foo;

global키워드 를 사용하면 $foo모든 함수와 클래스 외부에서 선언 된 변수를 해당 메소드 내부에서 볼 수있게 만들 것입니다. 그리고 아마도 그러한 $foo변수 가 없을 것입니다 .

$foo 클래스 속성에 액세스하려면 $this->foo했던 것처럼 을 사용해야 합니다.


11

해결 범위 연산자 ( ) 를 사용 foobarfunc하여 호출하는 경우 인스턴스 수준 대신 클래스 수준에서 정적으로 호출 하므로 개체 컨텍스트에 없을 때 사용하고 있습니다. 클래스 컨텍스트에 존재하지 않습니다.::$this$this

을 활성화 E_STRICT하면 PHP가 이에 대한 알림을 표시합니다.

Strict Standards: 
Non-static method foobar::foobarfunc() should not be called statically

대신에 이것을하십시오

$fb = new foobar;
echo $fb->foobarfunc();

각주에, 나는 global당신의 수업 내부 에서 사용하지 않는 것이 좋습니다 . 클래스 외부에서 무언가가 필요한 경우 생성자를 통해 전달하십시오. 이를 의존성 주입 이라고 하며 코드를 훨씬 더 유지 관리 가능하고 외부에 덜 의존적으로 만듭니다.


6

먼저 클래스 내부의 $ this현재 객체를 나타냅니다 .
그것은 클래스 함수 또는 변수를 호출하기 위해 클래스 외부에서 생성되는 것입니다.

따라서 foobar :: foobarfunc ()와 같은 클래스 함수를 호출하면 객체가 생성되지 않습니다. 그러나 그 함수 안에서 $ this-> foo ()를 반환했습니다. 이제 이건 아무것도 아닙니다. 그것이 class.php의 객체 컨텍스트에 있지 않을 때 $ this를 사용하는 이유입니다.

솔루션 :

  1. 객체를 만들고 foobarfunc ()를 호출하십시오.

  2. foobarfunc () 내부의 클래스 이름을 사용하여 foo ()를 호출하십시오.


2
또는 그냥 $ this 대신 self ::를 사용하십시오
Motassem MK

4

정적 컨텍스트에서 함수를 호출하면 $this단순히 존재하지 않습니다.

this::xyz()대신 사용해야 합니다.

함수를 정적으로 또는 객체 인스턴스에서 호출 할 수있는 상황에 대해 알아 보려면이 질문에 좋은 접근 방식이 설명되어 있습니다. 정적인지 객체인지 어떻게 알 수 있습니까?


4

빠른 방법 : (new foobar ())-> foobarfunc ();

클래스 replace를로드해야합니다.

foobar::foobarfunc();

으로 :

(new foobar())->foobarfunc();

또는 :

$Foobar = new foobar();
$Foobar->foobarfunc();

또는 사용할 정적 함수를 만듭니다 foobar::.

class foobar {
    //...

    static function foobarfunc() {
        return $this->foo();
    }
}

0

$foobar = new foobar;foobar 클래스를 객체가 아닌 $ foobar에 넣습니다 . 객체를 얻으려면 괄호를 추가해야합니다.$foobar = new foobar();

귀하의 오류가 그래서 거기, 당신은 클래스의 메소드를 호출 단순히 없습니다 $this때문에 $this개체 만 존재합니다.


0

PHP의 버그 인 것 같습니다. 오류

'치명적인 오류 : 잡히지 않는 오류 : 개체 컨텍스트에 없을 때 $ this 사용'

를 사용하여 함수에 표시 $this되지만 오류는 호출 함수가 비 정적 함수를 정적으로 사용하고 있다는 것입니다. 즉 :

Class_Name
{
    function foo()
    {
        $this->do_something(); // The error appears there.
    }
    function do_something()
    {
        ///
    }
}

오류가있는 동안 :

Class_Name::foo();

-2

이것을 사용하여 Class 메소드를 사용하십시오. foobar->foobarfunc();


2
새로 추가 할 것이 있으면 오래된 질문에만 답 하십시오.
Ajean
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.