[php] 내 PHP 코드에서 assert를 사용해야합니까?

동료가 if 문을 사용하고 예외를 던졌을 때 라이브러리 내 에서 assert 명령을 몇 번 추가했습니다 . (이전에 assert에 대해 들어 본 적이 없습니다.) 다음은 그가 어떻게 사용했는지에 대한 예입니다.

assert('isset($this->records); /* Records must be set before this is called. */');

나는했을 것이다 :

if (!isset($this->records)) {
    throw new Exception('Records must be set before this is called');
}

assert에 대한 PHP 문서를 읽으면 assert가 활성화되어 있는지 확인하고 assert를 사용하기 전에 핸들러를 추가하는 것이 좋습니다. 그가이 일을 한 곳을 찾을 수 없습니다.

그래서, 제 질문은 위와 같은 좋은 아이디어를 사용하고 있으며 if 및 예외 대신에 더 자주 사용해야합니까?

또 다른 메모는 우리가 참여하지 않을 수도있는 프로젝트 (라이브러리는 오픈 소스 임)를 포함하여 다양한 프로젝트 및 서버에서 이러한 라이브러리를 사용할 계획입니다. 이것이 assert를 사용하는 데 차이가 있습니까?



답변

대부분의 언어에 적용 할 수있는 경험 법칙 (내가 모호하게 알고있는 모든 것)은 an assert은 조건이 항상 참 이라고 주장하는 데 사용되는 반면 an if은 때때로 실패 할 것이라고 생각할 수있는 경우 적절하다는 것입니다.

이 경우 주어진 메서드가 호출되기 전에 항상 설정 되어야 assert하므로 상황에 대한 나의 약한 이해를 바탕으로 적절 하다고 말할 수 있습니다. 따라서 레코드 설정 실패는 런타임 조건이 아니라 프로그램의 버그입니다. 여기서는 로 보호되고있는 코드를 야기 할 수 없음 가능한 프로그램 실행 경로가 없다는 것을 (충분한 테스트를) 확인하는 데 도움이되는 없이 호출 될 수 있었다 세트를 가지고.recordsassertassertrecords

사용하는 이점 assert등은 대향 ifassert일반적으로 생산 코드 따라서 오버 헤드 감소 해제 할 수있다. 가장 잘 처리되는 상황 if은 프로덕션 시스템에서 런타임 중에 발생할 수 있으므로이를 끌 수 없어도 손실되는 것은 없습니다.


답변

주장을 “권한 의견”으로 생각하십시오. 다음과 같은 댓글보다는

// Note to developers: the parameter "a" should always be a number!!!

사용하다:

assert('is_numeric(a) /* The parameter "a" should always be a number. */');

의미는 정확히 동일하고 정확히 동일한 청중을 대상으로하지만 첫 번째 주석은 쉽게 잊거나 무시됩니다 (느낌표 수에 관계없이). 반면 “파워 주석”은 사람이 읽고 이해할 수있을뿐만 아니라 또한 개발 중에 지속적으로 머신 테스트를 거치며 코드 및 작업 습관에서 어설 션 처리를 잘 설정하면 무시되지 않습니다.

이렇게 보면 어설 션은 if (error) … 및 예외와 완전히 다른 개념이며 공존 할 수 있습니다.

예, 코드에 주석을 달아야하며 가능할 때마다 “강력한 주석”(어설 션)을 사용해야합니다.


답변

그것은 전적으로 개발 전략에 달려 있습니다. 대부분의 개발자는 assert()다운 스트림 단위 테스트를 인식하지 못하고 사용합니다. 그러나 사전 예방적이고 내장 된 테스트 체계가 때때로 유리할 수 있습니다.

assert는 활성화 및 비활성화가 가능하기 때문에 유용합니다. 그러한 어설 션 처리기가 정의되지 않으면 성능이 저하되지 않습니다. 동료에게는 하나가 없으므로 개발 환경에서 임시로 활성화하는 코드를 고안해야합니다 (E_NOTICE / E_WARNING이 켜져 있으면 어설 션 처리기가 있어야 함). 내 코드가 혼합 변수 유형을 위장 할 수없는 경우 가끔 사용합니다. 일반적으로 약한 유형의 PHP에서는 엄격한 유형을 사용하지 않지만 무작위 사용 사례가 있습니다.

 function xyz($a, $b) {
     assert(is_string($a));
     assert(is_array($b));

예를 들어 유형 지정자의 부족을 보상합니다 string $a, array $b. PHP5.4는이를 지원하지만 확인하지는 않습니다.


답변

Assert는 if개발 중 디버깅에만 사용되기 때문에 예외 와 같은 일반적인 흐름 제어를 대체하지 않습니다 .


답변

7 이전의 PHP에서 assert와 관련된 중요한 참고 사항입니다. assert 구문을 사용하는 다른 언어와 달리 PHP는 assert 문을 완전히 던지지 않습니다.이를 함수로 처리합니다 (assertion에 의해 호출 된 함수에서 debug_backtrace () 수행). 어설 션을 끄는 것은 엔진에서 아무 일도하지 않도록 함수를 핫 와이어하는 것처럼 보입니다. PHP 7은 더 일반적인 값인 1 (on) 또는 -1 (off) 대신 zend.assertions를 0으로 설정하여이 동작을 에뮬레이션하도록 만들 수 있습니다.

문제는 assert가 임의의 인수를 취한다는 점에서 발생합니다.하지만 인수가 문자열이 아니면 assert는 assert가 켜져 있든 꺼져 있든 식의 결과를 가져옵니다. 다음 코드 블록으로이를 확인할 수 있습니다.

<?php
  function foo($a) {
    echo $a . "\n";
    return TRUE;
  }
  assert_options(ASSERT_ACTIVE, FALSE);

  assert( foo('You will see me.'));
  assert('foo(\'You will not see me.\')');

  assert_options(ASSERT_ACTIVE, TRUE);

  assert( foo('Now you will see'));
  assert('foo(\'both of us.\')');

assert의 의도를 감안할 때 이것이 버그이며 assert가 PHP 4에서 다시 도입 된 이후로 언어에 있었기 때문에 오랫동안 지속되어 왔습니다.

assert에 전달 된 문자열은 그와 함께 제공되는 모든 성능 영향 및 위험과 함께 평가되지만 PHP에서 필요한 방식으로 작동하도록 assert 문을 얻는 유일한 방법입니다 (이 동작은 PHP 7.2에서 사용되지 않음).

편집 : PHP 7 및 7.2의 변경 사항을 기록하도록 위 변경


답변

Assert는 디버깅에 유용하므로 개발에만 사용해야합니다. 따라서 원하는 경우 웹 사이트 개발에 사용할 수 있지만 라이브 웹 사이트에는 예외를 사용해야합니다.


답변

아니요, 동료는이를 범용 오류 처리기로 사용해서는 안됩니다. 설명서에 따르면 :

어설 션은 디버깅 기능으로 만 사용해야합니다. 항상 TRUE 여야하는 조건을 테스트하고 그렇지 않은 경우 일부 프로그래밍 오류를 나타내는 온 전성 검사에 사용하거나 확장 기능이나 특정 시스템 제한 및 기능과 같은 특정 기능의 존재 여부를 확인할 수 있습니다.

입력 매개 변수 검사와 같은 일반적인 런타임 작업에는 어설 션을 사용하면 안됩니다. 일반적으로 어설 션 검사가 활성화되지 않은 경우 코드가 항상 올바르게 작동 할 수 있어야합니다.

자동화 된 테스트 스위트에 익숙한 경우 일반적으로 “assert”동사를 사용하여 일부 메서드 또는 기능의 출력을 확인합니다. 예를 들면 :

function add($a, $b) {
    return $a + $b;
}

assert(add(2,2) == 5, 'Two and two is four, dummy!');
assert(is_numeric(add(2,2)), 'Output of this function to only return numeric values.');

동료는이를 범용 오류 처리기로 사용해서는 안되며이 경우 입력 확인으로 사용해서는 안됩니다. 라이브러리의 일부 사용자가 레코드 필드를 설정하지 않을 수있는 것 같습니다.