2013-01-19 2 views
0

누군가가 PHP에서이 오류를보고 나에게 가장 일반적인 이유를 말할 수 파괴 할 수 없습니다활성 람다 함수는

어디 선가 같은데요에서 ...

활성 람다 함수를 파괴 할 수 없습니다 거기에 자체에 대한 참조를 포함하는 폐쇄를 파괴하려고하는 코드가 있고 컴파일러는 이것에 짜증이났다.

우리는 내가 원했던 것보다 더 자주 이것들을 얻었습니다. 우리가 어떤 패턴을 사용하고 있는지 궁금합니다. 그것이 원인 일 가능성이 있습니다.

코드 스 니펫을 첨부 하겠지만 오류는 일반적으로 힌트를 제공 할 수있는 파일의 줄이 아닌 파일을 가리 킵니다.

답변

1

동일한 버그가 php.net에 게시 된 비슷한 버그가 있습니다. 아래는 링크입니다.

희망은 도움이 될 것입니다. 치명적인 오류가 같은 코드가 발생합니다

https://bugs.php.net/bug.php?id=62452

1

같은 : 예외가 set_exception_handler()에게 주어진 콜백을 발생합니다

function destroy_handler() { 
    restore_exception_handler(); 
} 

function update_handler() { 
    destroy_handler(); 
} 

set_exception_handler(function ($e) { 
     echo "My exception handler"; 

     update_handler(); 

     throw new Exception("Throw this instead."); 
}); 
throw new Exception("An exception"); 

가 실행됩니다
set_exception_handler(function ($e) { 
     echo "My exception handler"; 

     restore_exception_handler(); 

     throw new Exception("Throw this instead."); 
}); 
throw new Exception("An exception"); 

또는 같은

restore_exception_handler()이 호출 되 자마자 치명적인 오류가 발생합니다. 그 이유는 해당 클로저에 대한 동일한 참조가 자체 범위 내에서 스트로크 (또는 재 할당)됩니다 (동일한 내용은 Sameer K에 게시 된 링크의 hanskrentel at yahoo dot de의 예입니다).

두 번째 예제에서 중첩 된 범위를 사용하더라도 동일하게 나타납니다. 이것은 restore_exception_handler이 마지막 세트 예외 처리기를 파괴하고 복사하지 않기 때문입니다 (변수를 다시 할당하거나 변수에 초기 값을 제공하는 표현식을 평가하는 동안 설정을 해제하는 것과 같습니다).

코드의 오류가 다른 파일을 가리키고 있다고 말하면 람다의 모든 호출을 검사하여 다른 파일의 함수 및 메소드에서 "점프"하고 코드를 다시 할당하거나 람다 자체에 대한 참조를 파괴합니다.

1

set_exception_handler 이전 예외 핸들러를 반환합니다

오류에 이전에 정의 된 예외 핸들러, 또는 NULL의 이름을 돌려줍니다. 이전 핸들러가 정의되지 않은 경우 NULL도 리턴됩니다.

throw new MyException("Exception one", 1); 

출력 : New handler:Exception one

throw new Exception("Exception two", 1); 

출력 : Old handler:Exception two

<?php 

class MyException extends Exception {} 

set_exception_handler(function(Exception $e){ 
    echo "Old handler:".$e->getMessage(); 
}); 

$lastHandler = set_exception_handler(function(Exception $e) use (&$lastHandler) { 
    if ($e instanceof MyException) { 
     echo "New handler:".$e->getMessage(); 
     return; 
    } 

    if (is_callable($lastHandler)) { 
     return call_user_func_array($lastHandler, [$e]); 
    } 

    throw $e; 
}); 

트리거 예외 핸들러 php.net: set_exception_handler