>  기사  >  백엔드 개발  >  PHP 7.4에서는 __toString()에서 예외 발생을 허용합니다.

PHP 7.4에서는 __toString()에서 예외 발생을 허용합니다.

藏色散人
藏色散人원래의
2019-11-30 14:41:322839검색

PHP 7.4 __toString()에서 예외 허용

Introduction

__toString()에서 예외를 발생시키는 것은 현재 금지되어 있으며 치명적인 오류가 발생합니다. 이로 인해 임의 코드 호출이 위험해지고 문제가 있는 범용 API가 됩니다. 이 RFC는 이러한 제한을 제거하는 것을 목표로 합니다.

현재 동작의 이론적 근거는 문자열 변환이 엔진과 표준 라이브러리 전체의 여러 위치에서 수행되지만 모든 곳에서 예외를 "올바르게", 즉 가능한 빨리 처리할 준비가 되어 있지 않다는 것입니다.

복구 가능한 오류를 예외로 변환하는 오류 처리기에 의해 문자열 변환 중 예외가 여전히 트리거될 수 있으므로 기술적인 관점에서 볼 때 이 제한은 궁극적으로 효과가 없습니다.

set_error_handler(function() {
    throw new Exception();
});
 
try {
    (string) new stdClass;
} catch (Exception $e) {
    echo "(string) threw an exception...\n";
}

사실 Symfony는 이 취약점을 악용하여 현재 제한을 우회했습니다. 불행하게도 이는 PHP 8에서 사라진 $errcontext 매개변수에 의존합니다.

그럼에도 불구하고 이 코드베이스에서 문자열 변환에 대한 전체 검토를 수행할 때까지 과거에 이 주제에 대한 논의는 중단되지 않았습니다. . 이는 첨부된 구현 요청에서 수행되었습니다.

는 __toString()에서 예외가 발생하도록 허용하도록

을 제안했으며 이는 평소대로 작동합니다. 치명적인 오류가 더 이상 발생하지 않습니다.

또한 "문자열로 변환할 수 없음" 및 "__toString()은 문자열 값을 반환해야 함" 복구 가능한 치명적인 오류를 PHP 7에 설정된 오류 정책에 따라 올바른 오류 예외로 변환합니다.

확장 지침

문자열 변환에서 예외를 적절하게 처리하려는 확장 작성자는 다음 지침을 고려해야 합니다.

● zval_get_string(), Convert_to_string() 및 친구들이 예외를 생성하는 경우 여전히 하나의 문자열을 생성합니다. 이 문자열은 일시적인 것으로 보장됩니다. 즉, 해제할 필요는 없지만 해제하는 것은 가능합니다. 상황에 따라 더 편리한 옵션을 선택할 수 있습니다.

● 객체에서 문자열로의 변환이 실패하면 문자열 변환 결과는 빈 문자열이 됩니다. 또는 배열이 문자열로 변환되고 오류 핸들러가 결과 알림을 예외로 발생시키는 경우 "배열"이 됩니다. (동작은 이전과 동일합니다.)

● 일반적으로 일반적인 if (EG(Exception)) 확인을 사용하여 예외가 발생했는지 확인하는 것으로 충분합니다:

zend_string *str = zval_get_string(val);
if (EG(exception)) {
    // Possibly free other resources here.
    return;
}

이 외에도 일부 도움말 API, 모델링 변환 오류가 발생하기 쉬운 작업:

// Like zval_get_string() but returns NULL on conversion failure.
zend_string *str = zval_try_get_string(val);
if (!str) {
    // Possibly free other resources here.
    return;
}
// Main code.
zend_string_release(str);
 
 
// Like zval_get_tmp_string() but returns NULL on conversion failure.
zend_string *tmp, *str = zval_try_get_tmp_string(val, &tmp);
if (!str) {
    // Possibly free other resources here.
    return;
}
// Main code.
zend_tmp_string_release(tmp);
 
 
// Like convert_to_string() but returns a boolean indicating conversion success/failure.
if (!try_convert_to_string(val)) {
    // Possibly free other resources here.
    return;
}
// Main code.

변환이 실패하면 try_convert_to_string()은 원래 값을 수정하지 않습니다. 따라서 이를 사용하는 것이 Convert_to_string() 및 예외 검사를 사용하는 것보다 안전합니다.

모든 문자열 변환을 확인하면 안전할 수 있지만 이러한 확인을 무시하면 일반적으로 몇 가지 불필요한 계산이 발생하고 중복 경고가 발생할 수 있습니다. 주의해야 할 주요 사항은 영구 구조(예: 데이터베이스)를 수정하는 작업입니다.

이전 버전과 호환되지 않는 변경

복구 가능한 치명적인 오류에서 오류 예외로의 전환은 기술적으로 BC 위반입니다.

번역: https://wiki.php.net/rfc/tostring_Exceptions

위 내용은 PHP 7.4에서는 __toString()에서 예외 발생을 허용합니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
이전 기사:PHP 7.4의 약한 참조다음 기사:PHP 7.4의 약한 참조