PHP에서 @ 기호를 사용하는 것은 무엇입니까?


577

@다음과 같은 특정 기능 앞에서 사용하는 것을 보았습니다 .

$fileHandle = @fopen($fileName, $writeAttributes);

이 기호의 용도는 무엇입니까?


3
RichieHindle과 Aiden Bell은 모두 정답을 제시했지만 하나의 답변 만 수락 할 수 있으므로 첫 번째 답변을 선택하겠습니다. 죄송합니다 Aiden
sv_in

1
코드베이스를 유지 관리 할 때 오류를 억제하면 오류가 발생할 수 있습니다 ... stackoverflow.com/a/7116175/282343
dennismonsewicz

답변:


636

오류 메시지를 표시하지 않습니다. PHP 매뉴얼의 오류 제어 연산자 를 참조하십시오 .


46
그것은 약간의 빠른 추첨이었습니다!
Aiden Bell

6
네; 두 번째로! 누가 처음 왔는지 확인하기 위해 answer-id를 확인해야했습니다.)
Sampson

3
게시 후 철자 철자법을 수정할 시간이 있었고 ... 동시에 분노 로 링크를 향상시켜
Aiden Bell

1
멋진 기능. 오류 isset()를 피하기 위해 불필요하게 사용 undefined offset합니다.
WM

470

오류를 억제합니다.

매뉴얼의 오류 제어 연산자 를 참조하십시오 .

PHP는 하나의 오류 제어 연산자 인 at 기호 (@)를 지원합니다. PHP에서 식 앞에 추가하면 해당 식에서 생성 될 수있는 모든 오류 메시지가 무시됩니다.

set_error_handler () 로 커스텀 에러 핸들러 함수를 설정했다면 여전히 호출 될 것이지만,이 커스텀 에러 핸들러는 error_reporting () 을 호출 할 수 있고 호출해야합니다. ...


157
다른 대답은 모든 사랑을 받고 있기 때문에 upvoted.
ajacian81

10
19 뒤에 ... c'mon 사람들이 RichieHindle을 이길하자 : P
Aiden Bell

이 답변은 첫 번째 답변이었습니다 (누가 먼저 답변했는지와 관련하여).
Mohd Abdul Mujib

227

@기호는 오류 제어 연산자 (일명 "침묵"또는 "종료"연산자)입니다. PHP는 관련 표현식에 의해 생성 된 오류 메시지 (공지, 경고, 치명적 등)를 억제합니다. 단항 연산자처럼 작동합니다. 예를 들어 우선 순위와 연관성이 있습니다. 다음은 몇 가지 예입니다.

@echo 1 / 0;
// generates "Parse error: syntax error, unexpected T_ECHO" since 
// echo is not an expression

echo @(1 / 0);
// suppressed "Warning: Division by zero"

@$i / 0;
// suppressed "Notice: Undefined variable: i"
// displayed "Warning: Division by zero"

@($i / 0);
// suppressed "Notice: Undefined variable: i"
// suppressed "Warning: Division by zero"

$c = @$_POST["a"] + @$_POST["b"];
// suppressed "Notice: Undefined index: a"
// suppressed "Notice: Undefined index: b"

$c = @foobar();
echo "Script was not terminated";
// suppressed "Fatal error: Call to undefined function foobar()"
// however, PHP did not "ignore" the error and terminated the
// script because the error was "fatal"

표준 PHP 오류 처리기 대신 사용자 지정 오류 처리기를 사용하면 어떻게됩니까?

set_error_handler ()로 커스텀 에러 핸들러 함수를 설정했다면 여전히 호출 될 것이지만,이 커스텀 에러 핸들러는 error_reporting ()을 호출 할 수 있고 호출해야합니다. .

다음 코드 예제에 설명되어 있습니다.

function bad_error_handler($errno, $errstr, $errfile, $errline, $errcontext) {
    echo "[bad_error_handler]: $errstr";
    return true;
}
set_error_handler("bad_error_handler");
echo @(1 / 0);
// prints "[bad_error_handler]: Division by zero"

오류 처리기는 @기호가 유효 한지 확인하지 않았습니다 . 매뉴얼은 다음을 제안합니다.

function better_error_handler($errno, $errstr, $errfile, $errline, $errcontext) {
    if(error_reporting() !== 0) {
        echo "[better_error_handler]: $errstr";
    }
    // take appropriate action
    return true;
}

58

또한 오류가 숨겨져 있음에도 불구하고 모든 사용자 정의 오류 처리기 (로 설정 됨 set_error_handler)는 계속 실행됩니다!


34

이미 일부 답변과 같이 : @운영자는 공지, 경고 및 중대한 오류를 포함하여 PHP의 모든 오류를 억제합니다.

그러나 실제로 @연산자를 사용하지 마십시오 .

왜?

글쎄, @당신이 오류 억압을 위해 연산자를 사용할 때, 오류가 발생할 때 시작할 곳이 전혀 없습니다. 나는 이미 일부 개발자들이 @연산자를 자주 사용하는 레거시 코드로 "재미"를 가지고있었습니다 . 특히 파일 작업, 네트워크 호출 등과 @같은 경우에 오류가 발생하면 (예 : 타사 API에 도달 할 수없는 경우 등) 많은 개발자가 운영자 의 사용을 권장 하는 경우가 있습니다. ).

그러나 여전히 그것을 사용하지 않는 요점은 무엇입니까? 두 가지 관점에서 살펴 보자.

개발자로서 :@ 사용될때어디서부터 시작해야할지 전혀 모릅니다. @오류가있는수백 또는 수천 개의 함수 호출이 있으면 모든 것과 같을 수 있습니다. 이 경우 합리적인 디버깅이 불가능합니다. 그리고 그것이 단지 제 3 자 오류 일지라도-그것은 훌륭하고 빨리 끝났습니다. ;-) 또한 오류 로그에 충분한 세부 정보를 추가하는 것이 좋습니다. 따라서 개발자는 로그 항목이 추가로 확인해야하는 것인지 또는 개발자의 범위를 벗어난 타사 오류인지 여부를 쉽게 결정할 수 있습니다.

사용자로서 : 사용자는 오류의 원인이 무엇인지 전혀 신경 쓰지 않습니다. 소프트웨어가 작동하고 특정 작업을 완료하는 등의 작업을 수행 할 수 있습니다. 소프트웨어가 개발자의 결함인지 또는 타사의 문제인지는 신경 쓰지 않습니다. 특히 사용자의 경우 범위를 벗어난 경우에도 모든 오류를 기록하는 것이 좋습니다. 특정 API가 자주 오프라인 상태 인 것을 알 수 있습니다. 당신은 무엇을 할 수 있나요? API 파트너와 대화 할 수 있으며 API 파트너를 안정적으로 유지할 수없는 경우 다른 파트너를 찾아야합니다.

한마디로 : 당신은 @(지식이 항상 좋다)와 같은 것이 있지만 그것을 사용하지 않아야 한다는 것을 알아야 합니다 . 많은 개발자들 (특히 다른 사람들의 디버깅 코드)은 매우 감사 할 것입니다.


1
@ (예 : fopen (), 결과를 예측하려는 시도가 경쟁 조건에 종속되는 경우)를 사용하여 일부 경고를 안정적으로 억제 할 수 있습니다. 오류 조건을 더 깔끔하게 처리하는 코드 @가있는 경우 usuig 가 올바른 방법입니다 이 기능은 특히 text/html클라이언트 로 돌아 오지 않는 경우 특히 유용합니다 . (어쩌면 반환 image/png"JSON을"또는)
Jasen

1
당신은 경고를 억제해서는 안됩니다-그들은 당신이 뭔가 잘못했다고 말하고 있습니다. 상태를 제대로 확인하거나 처리 할 수없는 경쟁 조건은 없습니다.
Ryan Rentfro 2012

1
몇 가지 장소에서 내 코드에 다음이 있습니다. if( session_status() == PHP_SESSION_NONE ) session_start(); 그것은 내가 상속받은 레거시 응용 프로그램이며 설정 스크립트가 여러 번 호출되는 곳이 있으므로 테스트해야합니다. 단순히 사용하는 데 무엇이 문제가 @session_start();있습니까?
Stephen R

당신이하고있는 일을 알고 그것을 아껴서 / 전략적으로 사용한다면, 그만한 가치가 있습니다. @$this->stats['device_os'][$date][$creative_id][$device_id][$operating_system]['clicks']++;각 수준에서 isset 검사를 수행하고 그렇지 않은 경우 채우는 대안보다 훨씬 낫습니다.
dtbarne

1
12 줄 이상의 코드를 추가하고 값을 추가하지 않고 코드의 가독성과 간결함을 줄이는 것만으로도 "일반적으로 더러워진"어딘가에서 내 마음을 바꿀 수있는 다른 곳에서 읽는 것 이외의 가치가있는 좋은 이유를 알려주십시오.
dtbarne

7

"@"연산자를 사용하지 않았다면 코드는 다음과 같습니다.

$fileHandle = fopen($fileName, $writeAttributes);

열려고하는 파일을 찾을 수 없으면 어떻게합니까? 오류 메시지가 표시됩니다.

오류 메시지를 억제하기 위해 다음과 같이 "@"연산자를 사용합니다.

$fileHandle = @fopen($fileName, $writeAttributes);

이것은 왜 PHP가 이런 종류의 @대안을 가지고 있는지에 대한 완벽한 예입니다 . 다른 프로그래밍 언어는 균일 한이 예외 처리 시나리오 이런 종류의 처리하는 stackoverflow.com/questions/1087365
dreftymac

@dreftymac 정확히!
Sujeet Kumar

5

열리지 않으면 E_WARNING 레벨의 오류가 생성됩니다. @를 사용하여이 경고를 표시하지 않을 수 있습니다.


5

@ 오류 메시지를 표시하지 않습니다.

다음과 같은 코드 스 니펫에 사용됩니다.

@file_get_contents('http://www.exaple.com');

" http://www.exaple.com " 도메인에 액세스 할 수 없으면 오류가 표시되지만 @아무것도 표시 되지 않습니다.


1

PHP는 하나의 오류 제어 연산자를 지원합니다 : at 부호 (@) 합니다. PHP에서 표현식 앞에 추가하면 해당 표현식에서 생성 될 수있는 모든 오류 메시지가 무시됩니다.

당신이 사용자 지정 오류 처리기 기능을 설정 한 경우 set_error_handler()그것은 여전히라고하지만, 얻을 것이다이 사용자 지정 오류 처리기 할 수있는 (그리고해야) 호출 error_reporting()반환 0오류를 트리거 한 통화가 앞에 때 @.

<?php
/* Intentional file error */
$my_file = @file ('non_existent_file') or
    die ("Failed opening file: error was '$php_errormsg'");

// this works for any expression, not just functions:
$value = @$cache[$key];
// will not issue a notice if the index $key doesn't exist.

?>

노트:-

1) @ 연산자는 표현식에서만 작동합니다.

2) 간단한 경험 법칙은 무엇인가의 가치를 취할 수 있다면 @ 연산자를 앞에 붙일 수 있습니다. 예를 들어 변수 앞에 변수, 함수 및 포함, 호출, 상수 등을 추가 할 수 있습니다. 함수 또는 클래스 정의 또는 if 및 foreach 등과 같은 조건부 구조 앞에 추가 할 수 없습니다.

경고:-

현재 "@"오류 제어 연산자 접두어는 스크립트 실행을 종료시키는 중대한 오류에 대한 오류보고를 비활성화합니다. 무엇보다도 이는 특정 기능의 오류를 억제하기 위해 "@"를 사용하고 사용할 수 없거나 잘못 입력 된 경우 이유에 대한 표시없이 스크립트가 바로 종료됨을 의미합니다.


1

@를 사용할 때 알아야 할 몇 가지 포인터가 있습니다.이 게시물을 완전히 보려면 http://mstd.eu/index.php/2016/06/30/php- 빠른 화재는 무엇을 위해 사용되는 PHP에서 /

  1. @ 기호가 앞에 추가 되어도 오류 처리기는 여전히 실행되며 오류 수준이 0으로 설정되어 있으면 사용자 지정 오류 처리기에서 적절하게 처리해야합니다.

  2. @에 include를 추가하면 include 파일의 모든 오류가 오류 레벨 0으로 설정됩니다.


1

@함수에 의해 발생 된 오류 메시지를 억제합니다. fopen파일이 종료되지 않으면 오류가 발생합니다. @symbol은 파일이 존재하지 않아도 실행을 다음 행으로 이동시킵니다. PHP 코드를 개발할 때 로컬 환경에서 이것을 사용하지 않을 것을 제안합니다.

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