PHP 5.4.0 이전의 익명 함수에서`$ this` 사용


86

PHP 매뉴얼 상태

$thisPHP 5.4.0 이전에는 익명 함수에서 사용할 수 없습니다.

상의 익명 함수 페이지 . 그러나 $this변수 에 할당 use하고 함수 정의에서 명령문에 변수를 전달하여 작동시킬 수 있음을 발견했습니다 .

$CI = $this;
$callback = function () use ($CI) {
    $CI->public_method();
};

이것이 좋은 습관입니까? PHP 5.3을 사용하여 익명 함수 내부
에 액세스하는 더 좋은 방법이 $this있습니까?


1
사소한 포럼 규칙 일뿐입니다. 일반적으로 선호하는 답변을 반영하도록 질문을 편집하는 것보다 답변을 수락하는 것이 좋습니다. 주로 이것은 응답이 영구적으로 의미가 있지만 물론 정답에 대한 크레딧을 제공하기위한 것입니다.
halfer

4
그 조심 $CI = $this;하고 $CI =& $this; 하지 않습니다 실제로 동일합니다. 아마도 당신의 목적을 위해, 그러나 그들은 동일하지 않습니다. $CI = 'bla'; var_dump($this);차이점을 확인하려면 두 버전을 모두 사용해보십시오 .
Rudie 2011

1
@Rudie 귀하의 의견에 대한 문서 를 추가하고 있습니다
steampowered

@steampowered 이것에 대한 온라인 어딘가에 좋은 예 / 기사가 있지만 찾을 수 없습니다 =) 죄송합니다. 차이가 보이지 않으면 시도해보십시오. 그럼 분명합니다.
Rudie 2011

답변:


67

보호 된 메서드 나 개인 메서드를 호출하려고하면 실패합니다. 그렇게 사용하는 것은 외부에서 호출하는 것으로 간주되기 때문입니다. 내가 아는 한 5.3에서는이 문제를 해결할 수있는 방법이 없지만 PHP 5.4가 나오면 예상대로 작동합니다.

class Hello {

    private $message = "Hello world\n";

    public function createClosure() {
        return function() {
            echo $this->message;
        };
    }

}
$hello = new Hello();
$helloPrinter = $hello->createClosure();
$helloPrinter(); // outputs "Hello world"

더 나아가 익명 함수 (클로저 리 바인딩)에 대해 런타임시 $ this가 가리키는 것을 변경할 수 있습니다.

class Hello {

    private $message = "Hello world\n";

    public function createClosure() {
        return function() {
            echo $this->message;
        };
    }

}

class Bye {

    private $message = "Bye world\n";

}

$hello = new Hello();
$helloPrinter = $hello->createClosure();

$bye = new Bye();
$byePrinter = $helloPrinter->bindTo($bye, $bye);
$byePrinter(); // outputs "Bye world"

사실상 익명 함수는 bindTo () 메서드를 갖게 되는데, 첫 번째 매개 변수는 $ this가 가리키는 것을 지정하는 데 사용할 수 있고 두 번째 매개 변수는 가시성 수준이 무엇이어야하는지 제어 합니다 . 두 번째 매개 변수를 생략하면 가시성은 "외부"에서 호출하는 것과 같습니다. 공용 속성에만 액세스 할 수 있습니다. 또한 bindTo가 작동하는 방식을 기록하십시오. 원래 함수를 수정하지 않고 함수를 반환합니다 .


1
답을 정답으로 표시하지만 다른 독자를 위해 명확히하기 위해 : 질문에 사용 된 규칙은를 참조하는 객체를 사용하는 공용 메서드에서 작동합니다 $this.
steampowered dec.

5
리플렉션을 사용하여 비공개 메서드에 액세스 할 수 있습니다. 비효율적이고 약간 사악하지만 작동합니다.
outis

7

참조로 객체를 전달하기 위해 항상 PHP에 의존하지 마십시오. 참조 자체를 할당 할 때 동작은 원래 포인터가 수정 된 대부분의 OO 언어와 동일하지 않습니다.

당신의 예 :

$CI = $this;
$callback = function () use ($CI) {
$CI->public_method();
};

해야한다:

$CI = $this;
$callback = function () use (&$CI) {
$CI->public_method();
};

참고 참조 "&"및 $ CI는 최종 호출이 완료된 후 할당되어야합니다. 그렇지 않으면 예상 할 수없는 출력이 발생할 수 있습니다. 그렇지 않으면 PHP에서 참조에 액세스하는 것이 항상 원래 클래스에 액세스하는 것과 같지는 않습니다.

http://php.net/manual/en/language.references.pass.php


6

그것이 정상적인 방법입니다.
btw, &객체가 어떤 식 으로든 ref를 통과하므로 이것이없이 작동 해야하는 것을 제거하십시오 .


1

참조로 통과하는 것이 올바른 방법이라면 괜찮아 보입니다. PHP 5를 사용하는 경우 항상 참조에 관계없이 전달되므로 &이전 에 기호 가 필요하지 않습니다 $this.


2
4.x는 익명 기능을 지원하지 않았으므로 OP는 5.3 이상을 사용해야합니다. :-)
halfer

1

이건 괜찮아. 나는 당신도 이것을 할 수 있다고 생각해야합니다.

$CI = $this;

... 객체와 관련된 할당은 항상 전체 객체가 아닌 참조를 복사하기 때문입니다.

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