PHP를 사용한 "알림 : 정의되지 않은 변수", "알림 : 정의되지 않은 색인"및 "알림 : 정의되지 않은 오프셋"


1173

PHP 스크립트를 실행 중이며 다음과 같은 오류가 계속 발생합니다.

통지 : 정의되지 않은 변수 : my_variable_name in C : \ wamp \ www \ mypath \ index.php 10 행

통지 : 정의되지 않은 색인 : my_index C : \ wamp \ www \ mypath \ index.php 11 행

10 행과 11 행은 다음과 같습니다.

echo "My variable value is: " . $my_variable_name;
echo "My index value is: " . $my_array["my_index"];

이 오류 메시지의 의미는 무엇입니까?

왜 갑자기 나타 납니까? 이 스크립트를 몇 년 동안 사용해 왔으며 아무런 문제가 없었습니다.

어떻게 고치나요?


사람들이 반복해서 문제를 설명하는 대신 중복 된 것으로 연결 하는 일반적인 참조 질문 입니다. 이 문제에 대한 대부분의 실제 답변이 매우 구체적이기 때문에 이것이 필요하다고 생각합니다.

관련 메타 토론 :



3
변수가 초기화되지 않았을 수 있습니다. 게시물이나 가져 오기 또는 배열에서 변수를 초기화하고 있습니까? 이 경우 해당 배열에 필드가 없을 수 있습니다. 당신의 접근.
Anish Silwal

3
@Pekka 웃- "및"알림 : 정의되지 않은 오프셋 ""을 추가 한 편집을 발견했습니다. "PHP :"정의되지 않은 변수 ","정의되지 않은 색인 ","정의되지 않은 오프셋 "주의 사항"을 사용하는 것이 더 의미가 없습니까? PHP는 "php"로 태그되어 있기 때문에 URL을 차단합니다. 또한 URL이 잘리지 and-notice-undef않도록 제안에서 URL이 잘립니다. 또는 너무 많은 따옴표를 제거 할 수도 있습니다.PHP: “Undefined variable/index/offset” notices
Funk Forty Niner

2
@Fred 두 가지 변형 모두에 대해 논쟁을 할 수 있다고 생각합니다. TNews가 "Notice :"를 포함한 전체 줄을 검색 쿼리에 입력 할 가능성이 있습니다.이 질문에 대한 주요 트래픽 생성기는 확실합니다. 메시지가 가득 차면 검색 엔진의 가시성이 향상 될 것입니다.
Pekka

2
@Pekka 웃 이해합니다. 나는 단지 URL이 잘리지 않았기 때문에 지금은 URL에서하지 않는다고 말했다 and-notice-undef. 그것은 단지 몇 가지 제안이었습니다. 그것은 또한 스스로 반복된다 Notice: Undefined.
Funk Forty Niner

답변:


1066

통지 : 정의되지 않은 변수

PHP 매뉴얼 의 광대 한 지혜에서 :

초기화되지 않은 변수의 기본값에 의존하는 것은 하나의 파일을 같은 변수 이름을 사용하는 다른 파일에 포함시키는 경우 문제가됩니다. 또한 주요 인 보안 위험register_globals가 켜져. 초기화되지 않은 변수로 작업하는 경우 E_NOTICE 레벨 오류가 발생하지만 초기화되지 않은 배열에 요소를 추가하는 경우에는 발생하지 않습니다. 변수가 이미 초기화되었는지 여부를 감지하기 위해 isset () 언어 구문을 사용할 수 있습니다. 또한 변수가 초기화되지 않은 경우 경고 또는 오류 메시지를 생성하지 않으므로 empty () 솔루션이 더 이상적입니다 .

에서 PHP 문서 :

변수가 존재하지 않으면 경고가 생성되지 않습니다. 즉, empty () 는 본질적으로 ! isset ($ var) || $ var == false .

만 사용할 수 있음이 수단이 empty()변수가 설정되어 있는지 확인하기 위해, 또한 그 다음에 변수를 확인, 0, 0.0, "", "0", null, false또는 [].

예:

$o = [];
@$var = ["",0,null,1,2,3,$foo,$o['myIndex']];
array_walk($var, function($v) {
    echo (!isset($v) || $v == false) ? 'true ' : 'false';
    echo ' ' . (empty($v) ? 'true' : 'false');
    echo "\n";
});

3v4l.org 온라인 PHP 편집기 에서 위의 스 니펫을 테스트하십시오.

PHP는 변수 선언을 필요로하지 않지만 나중에 스크립트에서 사용될 변수에 값을 제공하는 것을 잊어 버린 일부 보안 취약점이나 버그를 피하기 위해 권장합니다. 선언되지 않은 변수의 경우 PHP가하는 일은 E_NOTICE기본적으로보고 되지 않은 매우 낮은 수준의 오류가 발생 하지만 매뉴얼 개발 중에 허용하도록 권장합니다 .

문제를 해결하는 방법 :

  1. 권장 사항 : 정의되지 않은 변수에 문자열을 추가 할 때와 같이 변수를 선언하십시오. 또는 다음과 같이 isset()/ !empty() 를 사용 하여 참조하기 전에 선언되었는지 확인하십시오.

    //Initializing variable
    $value = ""; //Initialization value; Examples
                 //"" When you want to append stuff later
                 //0  When you want to add numbers later
    //isset()
    $value = isset($_POST['value']) ? $_POST['value'] : '';
    //empty()
    $value = !empty($_POST['value']) ? $_POST['value'] : '';
    

    이것은 PHP 7.0부터 훨씬 더 깨끗해졌습니다. 이제 null 병합 연산자를 사용할 수 있습니다 .

    // Null coalesce operator - No need to explicitly initialize the variable.
    $value = $_POST['value'] ?? '';
    
  2. E_NOTICE에 대한 사용자 정의 오류 처리기 를 설정 하고 메시지를 표준 출력에서 ​​로그 파일로 리디렉션하십시오.

    set_error_handler('myHandlerForMinorErrors', E_NOTICE | E_STRICT)
  3. 보고에서 E_NOTICE를 비활성화하십시오. 제외하는 빠른 방법 E_NOTICE은 다음과 같습니다.

    error_reporting( error_reporting() & ~E_NOTICE )
  4. @ 연산자로 오류를 억제하십시오 .

참고 : 포인트 1 만 구현하는 것이 좋습니다.

통지 : 정의되지 않은 인덱스 / 정의되지 않은 오프셋

이 알림은 사용자 (또는 PHP)가 정의되지 않은 배열의 인덱스에 액세스하려고 할 때 나타납니다.

문제를 해결하는 방법 :

  1. 액세스하기 전에 색인이 존재하는지 확인하십시오. 이를 위해 isset()또는 사용할 수 있습니다 array_key_exists():

    //isset()
    $value = isset($array['my_index']) ? $array['my_index'] : '';
    //array_key_exists()
    $value = array_key_exists('my_index', $array) ? $array['my_index'] : '';
    
  2. list()존재하지 않는 배열 인덱스에 액세스하려고 시도 할 때 언어 구성에서 이를 생성 할 수 있습니다.

    list($a, $b) = array(0 => 'a');
    //or
    list($one, $two) = explode(',', 'test string');
    

두 배열 변수에 액세스하는 데 두 개의 변수가 사용되지만 index 배열 요소는 하나뿐 0이므로 다음과 같이 생성됩니다.

통지 : 정의되지 않은 오프셋 : 1

$_POST/ $_GET/ $_SESSION변수

위의 통지 $_POST$_GET또는로 작업 할 때 자주 나타납니다 $_SESSION. for $_POST$_GET인덱스를 사용하기 전에 인덱스가 있는지 확인해야합니다. 들어 $_SESSION당신이 할 필요가 있는지 당신은 시작 세션이 session_start()인덱스도 존재합니다.

또한 3 개의 변수는 모두 슈퍼 글로벌 이며 대문자입니다.

관련 :


7
@ dieselpower44 몇 가지 생각 : "종료 연산자"( @)에는 몇 가지 성능 문제가 있습니다. 또한 특정 범위 내에서 모든 오류를 억제하므로 주의를 기울이지 않고 사용하면 원하는 메시지를 숨길 수 있습니다.
IMSoP

6
문제를 숨기는 것은 문제를 다루는 방법이 아닙니다. 품목 # 2 ... # 4는 일반적으로 프로덕션 서버에서만 사용할 수 있습니다.
Salman A

1
사용자 지정 오류 처리기가 사용될 때 메시지를 인라인으로 처리 할 수 ​​있습니까 (핸들러가 아님)? $var = @$_GET['nonexisting'];아직도 통지합니다 ..
Alph.Dev

18
$value = isset($_POST['value']) ? $_POST['value'] : '';4 를 사용하는 대신 1.를 사용하는 것이 좋습니다 . $value = @$_POST['value'];?
forsvunnet

@twistedpixel이 4 가지 방법은 독립적이며 4 단계 안내서가 아닙니다. 따라서 방법 4를 사용하기로 선택한 경우 처음 3 가지 방법을 구현하지 않았으므로 아직 오류를 억제하지 않았습니다.
Aycan Yaşıt

141

이것들을보십시오

Q1 :이 통지는 $ varname이 현재 스크립트 범위에 정의되어 있지 않음을 의미합니다.

Q2 : 의심스러운 변수를 사용하기 전에 isset (), empty () 조건을 사용하면 효과가 있습니다.

// recommended solution for recent PHP versions
$user_name = $_SESSION['user_name'] ?? '';

// pre-7 PHP versions
$user_name = '';
if (!empty($_SESSION['user_name'])) {
     $user_name = $_SESSION['user_name'];
}

또는 빠르고 더러운 솔루션으로 :

// not the best solution, but works
// in your php setting use, it helps hiding site wide notices
error_reporting(E_ALL ^ E_NOTICE);

세션에 대한 참고 사항 :


구성 파일 E_NOTICE에서 사용 하는 경우php.inierror_reporting = (E_ALL & ~E_NOTICE)
ahmd0


위의 답변에서 isset, array_key_exists를 시도했지만 작동하지 않았습니다. 귀하의 답변 .empty ()를 시도했는데 작동합니다. 대단히 감사합니다!
ewef

63

오류 표시 @연산자

원하지 않는 중복 통지의 경우 전용 @연산자 를 사용하여 «정의되지 않은 변수 / 인덱스 메시지를 숨길 수 있습니다.

$var = @($_GET["optional_param"]);
  • 이것은 일반적으로 권장하지 않습니다. 새로 온 사람들은 그것을 과도하게 사용하는 경향이 있습니다.
  • 함수 매개 변수 또는 루프와 같이 응용 프로그램 논리 내부의 코드 깊이 (선언해서는 안되는 선언되지 않은 변수 무시)에 매우 적합하지 않습니다.
  • 오버 거꾸로 하나있다 isset?:또는 ??그러나 슈퍼 supression. 통지는 여전히 기록 될 수 있습니다. 그리고 @다음과 같이 숨겨진 알림을 부활 시킬 수 있습니다 .set_error_handler("var_dump");
    • 또한 if (isset($_POST["shubmit"]))초기 코드에서 습관적으로 사용하거나 권장해서는 안됩니다 .
    • 새로 온 사람들은 그런 오타를 발견하지 못할 것입니다. 그것은 바로 그 경우에 대한 PHP 통지를 박탈합니다. 추가 @또는 isset전용 기능을 확인.
    • 먼저 원인을 수정하십시오. 통지가 아닙니다.

  • @$_GET/ $_POST입력 매개 변수, 특히 선택적인 경우 주로 허용됩니다 .

그리고 이것이 그러한 질문의 대부분을 다루므로 가장 일반적인 원인을 확장 해 봅시다.

$_GET/ $_POST/ $_REQUEST정의되지 않은 입력

  • 정의되지 않은 인덱스 / 오프셋이 발생할 때 가장 먼저해야 할 일은 오타가 있는지 확인하는 것입니다.
    $count = $_GET["whatnow?"];

    • 이것은 예상 키 이름이며 페이지 요청 에 존재 합니까?
    • 변수 이름 배열 인덱스는 PHP에서 대소 문자를 구분합니다.
  • 두 번째로, 통지에 명백한 원인이없는 경우, var_dump또는 현재 컨텐츠에 대한 모든 입력 배열을 사용 하거나 print_r확인 하십시오 .

    var_dump($_GET);
    var_dump($_POST);
    //print_r($_REQUEST);
    

    둘 다 스크립트가 올바른 매개 변수 또는 임의의 매개 변수로 호출되었는지 여부를 나타냅니다.

  • 대안으로 또는 추가로 브라우저 devtools ( F12)를 사용 하고 네트워크 탭에서 요청 및 매개 변수를 검사하십시오.

    브라우저 개발자 도구 / 네트워크 탭

    POST 매개 변수와 GET 입력은 별도로 표시됩니다.

  • 를 들어 $_GET매개 변수 당신은 훔쳐도 할 수 QUERY_STRING있는

    print_r($_SERVER);

    PHP는 비표준 매개 변수 이름을 슈퍼 글로벌로 통합 하는 규칙을 가지고 있습니다 . 아파치는 재 작성도 할 수있다. 제공된 원시 $_COOKIES및 기타 HTTP 요청 헤더를 이런 방식으로 볼 수도 있습니다.

  • 더 명확하게 GET 매개 변수에 대한 브라우저 주소 표시 줄을 확인하십시오 .

    http://example.org/script.php?id=5&sort=desc

    물음표 name=value뒤 의 쌍 ?은 조회 (GET) 매개 변수입니다. 따라서이 URL은 $_GET["id"]and 만 얻을 수 있습니다 $_GET["sort"].

  • 마지막으로 매개 변수가 필요하지만 아무것도받지 않으면 선언 <form><input> 선언을 확인하십시오 .

    • 각 필수 입력에 <input name=FOO>
    • id=또는 title=속성이 충분하지 않습니다.
    • method=POST양식을 채울한다고 $_POST.
    • 반면에 method=GET(또는 제외하면) $_GET변수 가 생성 됩니다.
    • action=script.php?get=param$ _GET 및 method=POST$ _POST 의 나머지 필드와 함께 양식을 제공 할 수도 있습니다 .
    • 최신 PHP 구성 (≥ 5.6) 에서는 다시 사용할 있게되었습니다 (유행이 아님) $_REQUEST['vars']. GET 및 POST 매개 변수를 손상시킵니다.
  • mod_rewrite access.log를 사용하는 경우 RewriteLog매개 변수를 확인 하고 활성화 하지 않고 매개 변수를 모두 확인해야합니다 .

$_FILES

$_COOKIE

  • $_COOKIE배열 직후 채워되지 않습니다 setcookie()만 어떤 후속 HTTP 요청에.
  • 또한 유효 시간이 초과되면 하위 도메인이나 개별 경로에 대한 제약이 될 수 있으며 사용자와 브라우저는이를 거부하거나 삭제할 수 있습니다.

2
당신이 성능에 미치는 영향이 무엇인지 궁금 경우,이 문서는 잘 요약 derickrethans.nl/...을 .
Gajus

@GajusKuizinas 2009 년 이후 몇 가지 사항이 변경되었습니다. 특히 php.net/ChangeLog-5.php#5.4.0 은 결과를 크게 변경합니다 ( "Zend Engine, performance"및 "(silence) operator"참조).
mario

흥미로운 @mario 감사합니다. 이제 누군가가 두 가지를 벤치마킹하기에 충분하다면 ... 3v4l.org/CYVOn/perf#tabs 3v4l.org/FLp3D/perf#tabs 이 테스트에 따르면 동일한 것으로 보입니다 (규모 변경에 대한 통지).
Gajus

47

일반적으로 "나쁜 프로그래밍"으로 인해 현재 또는 나중에 실수 할 가능성이 있습니다.

  1. 실수 인 경우 먼저 변수를 올바르게 지정하십시오. $ varname = 0;
  2. 실제로 가끔 정의되는 경우 if (isset($varname))사용하기 전에 테스트하십시오.
  3. 철자가 틀 렸기 때문에 바로 수정하십시오.
  4. 어쩌면 PHP 설정 에서 경고를 켤 수도 있습니다.

5
경고를 끄지 마십시오. 더 엄격한 언어에서는 종종 "버그가있을 수 있습니다.이 줄을 두 번 확인하는 것이 좋습니다"-PHP와 같은 언어에서는 종종 "이 코드는 엉망이고 버그로 가득 차 있습니다"라는 의미입니다. 일부 의미가 있지만 최대한 빨리 수정하십시오. "

5
처음 세 가지 사항에 동의하지만 # 4는 단순히 잘못되었습니다. 문제를 숨겨도 문제가 해결되지 않으며 더 많은 문제가 발생할 수 있습니다.
Valentin Flachsel

1
@Freek 절대적으로 사실이지만, 일부 시나리오 (구매 한 스크립트, 제로 기술 지식, 내일까지 실행해야 함 ...)는 덕트 테이프 솔루션입니다. 정말 나쁘고 항상 강조해야하지만 옵션
Pekka

덕트 테이프가 좋습니다 ... 때때로. 역사적으로 경고는 표준 PHP 설정에서 해제되었지만 강력한 설정은 더욱 엄격 해졌습니다. 너무 나쁜 사람들은 고객을 성가 시게하지 않기 위해 이전 설정으로 돌아갑니다.
Erik

41

아직 할당하지 않은 변수를 테스트, 평가 또는 인쇄하고 있음을 의미합니다. 그것은 오타가 있거나 변수가 먼저 무언가로 초기화되었는지 확인해야 함을 의미합니다. 논리 경로를 확인하십시오. 한 경로에는 설정되어 있지만 다른 경로에는 설정되어 있지 않을 수 있습니다.


34

도움이 되었기 때문에 알림을 사용 중지하고 싶지 않지만 너무 많은 입력을 피하고 싶었습니다.

내 해결책은이 기능이었습니다.

function ifexists($varname)
{
  return(isset($$varname)?$varname:null);
}

따라서 $ name 및 echo를 참조하려면 다음과 같이 작성하십시오.

<?=ifexists('name')?>

배열 요소의 경우 :

function ifexistsidx($var,$index)
{
  return(isset($var[$index])?$var[$index]:null);
}

페이지에서 $ _REQUEST [ 'name']을 (를) 참조하려는 경우 :

<?=ifexistsidx($_REQUEST,'name')?>

2
PHP 5.3에서 ifexists () 함수가 작동하지 않습니다. 호출자의 변수는 수퍼 글로벌 이거나 $ GLOBALS로 바이올린을 사용 하지 않는 한 함수의 로컬 범위 ( 변수 범위 참조)에서 사용할 수 없으므로 일반적으로 null을 반환합니다. (기울임 꼴은 php.net의 장입니다.)$foo = "BABAR"; ifexists('foo');
skierpage

이제 당신은 "안녕하세요"를 얻을 것입니다 ... 요점은 무엇입니까? 그냥 값을 확인하십시오if( !empty($user) and !empty($location) ) echo "hello $user ..."
gcb

27

입력 문자열 을 얻는 가장 좋은 방법 은 다음과 같습니다.

$value = filter_input(INPUT_POST, 'value');

이 원 라이너는 거의 다음과 같습니다.

if (!isset($_POST['value'])) {
    $value = null;
} elseif (is_array($_POST['value'])) {
    $value = false;
} else {
    $value = $_POST['value'];
}

문자열 값 을 절대로 원한다면 다음과 같이하십시오.

$value = (string)filter_input(INPUT_POST, 'value');

25

변수 '$ user_location'이 정의되지 않았기 때문입니다. 내부에서 '$ user_location'변수를 선언하는 if 루프를 사용하는 경우 else 루프가 있고 동일하게 정의해야합니다. 예를 들면 다음과 같습니다.

$a=10;
if($a==5) { $user_location='Paris';} else { }
echo $user_location;

위의 코드는 if 루프가 충족되지 않고 else 루프 '$ user_location'이 정의되지 않았으므로 오류를 생성합니다. 여전히 PHP는 변수를 에코하라는 요청을 받았습니다. 따라서 코드를 수정하려면 다음을 수행해야합니다.

$a=10;
if($a==5) { $user_location='Paris';} else { $user_location='SOMETHING OR BLANK'; }
echo $user_location;

25

""왜 대답이 갑자기 나타 납니까? 이 스크립트를 몇 년 동안 사용해 왔는데 아무런 문제가 없었습니다. "

대부분의 사이트는 "모든 오류 표시 ( '알림'및 '더 이상 사용되지 않음'은 표시하지 않음")의 "기본"오류보고에 따라 작동하는 것이 매우 일반적입니다. 이것은 php.ini에 설정되며 서버의 모든 사이트에 적용됩니다. 즉, 예제에서 사용 된 "알림"은 억제 (숨겨 짐)되는 반면, 더 중요한 것으로 간주되는 다른 오류는 표시 / 기록됩니다.

다른 중요한 설정은 오류를 숨길 수 있다는 것입니다 (예 : display_errors"off"또는 "syslog"로 설정).

이 경우에 발생할 수있는 일은 error_reporting(예제에 따라) 알림을 표시하도록 변경되었거나 설정 display_errors을 화면에 표시 하도록 변경 한 것 입니다 ( 예제 / 기록과는 반대로).

왜 바뀌 었습니까?

가장 명백하고 간단한 대답은 누군가 php.ini에서 이러한 설정 중 하나를 조정했거나 업그레이드 된 PHP 버전이 이전과 다른 php.ini를 사용하고 있다는 것입니다. 그것이 가장 먼저 볼 곳입니다.

그러나이 설정을 무시할 수도 있습니다.

  • .htconf (vhost 및 하위 구성을 포함한 웹 서버 구성) *
  • .htaccess
  • PHP 코드 자체에서

이 중 하나도 변경되었을 수 있습니다.

또한 웹 서버 구성이 .htaccess 지시문을 활성화 / 비활성화 할 수 있다는 복잡한 문제가 있으므로, .htaccess에 지시문이 있으면 갑자기 작동을 시작 / 중지하는 경우이를 확인해야합니다.

(.htconf / .htaccess는 아파치로 실행한다고 가정합니다. 명령 행을 실행하면 적용되지 않습니다 .IIS 또는 다른 웹 서버를 실행하는 경우 해당 구성을 적절히 확인해야합니다)

요약

  • php.ini의 check error_reportingdisplay_errorsphp 지시문이 변경되지 않았거나 이전과 다른 php.ini를 사용하고 있지 않습니다.
  • .htconf (또는 vhosts 등)의 check error_reportingdisplay_errorsphp 지시문은 변경되지 않았습니다.
  • .htaccess의 check error_reportingdisplay_errorsphp 지시문은 변경되지 않았습니다.
  • .htaccess에 지시문이 있으면 .htconf 파일에서 지시문이 여전히 허용되는지 확인하십시오.
  • 마지막으로 코드를 확인하십시오. 아마도 관련이없는 도서관; 있는지 error_reportingdisplay_errorsPHP 지시어가이 설정되었습니다.


16

이 오류를 저주하는 데 사용되었지만 사용자 입력을 피하도록 상기시키는 것이 도움이 될 수 있습니다.

예를 들어, 이것이 영리하고 속기 인 줄 알았다면 :

// Echo whatever the hell this is
<?=$_POST['something']?>

...다시 생각 해봐! 더 나은 해결책은 다음과 같습니다.

// If this is set, echo a filtered version
<?=isset($_POST['something']) ? html($_POST['something']) : ''?>

(사용자 정의 html()기능을 사용하여 캐릭터를 탈출하면 마일리지가 다를 수 있습니다)


15

PHP 7.0에서는 이제 Null 통합 연산자를 사용할 수 있습니다 :

echo "My index value is: " . ($my_array["my_index"] ?? '');

다음과 같습니다.

echo "My index value is: " . (isset($my_array["my_index"]) ? $my_array["my_index"] : '');

PHP 매뉴얼 PHP 7.0


이것은 if 문에서도 잘 작동합니다. if (is_array($my_array['idontexist'] ?? '')) { dosomething(); }
코더

코드는 실제로 간과 된 버그입니다. ?? - 부울 인 isset()경우 에만을 확인하고 is_array()예기치 않은 동작이 수행됩니다.
elpiel

14

변수를 자동으로 선언 하는 모든 시간 고유의 유용한 함수 exst () 를 사용합니다.

귀하의 코드는-

$greeting = "Hello, ".exst($user_name, 'Visitor')." from ".exst($user_location);


/** 
 * Function exst() - Checks if the variable has been set 
 * (copy/paste it in any place of your code)
 * 
 * If the variable is set and not empty returns the variable (no transformation)
 * If the variable is not set or empty, returns the $default value
 *
 * @param  mixed $var
 * @param  mixed $default
 * 
 * @return mixed 
 */

function exst( & $var, $default = "")
{
    $t = "";
    if ( !isset($var)  || !$var ) {
        if (isset($default) && $default != "") $t = $default;
    }
    else  {  
        $t = $var;
    }
    if (is_string($t)) $t = trim($t);
    return $t;
}

14

매우 간단한 언어로 .
실수는 당신이 $user_location이전에 정의하지 않은 변수 사용 하고 있으며 값이 없기 때문에이 변수 사용 하기 전에 선언하는 것이 좋습니다 . 예를 들어 :


$user_location = '';
또는
$user_location = 'Los Angles';
이것은 당신이 직면 할 수있는 매우 일반적인 오류이므로 변수를 선언하고 코딩을 즐기십시오 .


8

왜 간단하게 유지하지 않습니까?

<?php
error_reporting(E_ALL); // making sure all notices are on

function idxVal(&$var, $default = null) {
         return empty($var) ? $var = $default : $var;
  }

echo idxVal($arr['test']);         // returns null without any notice
echo idxVal($arr['hey ho'], 'yo'); // returns yo and assigns it to array index, nice

?>

8

왜 이런 일이 발생합니까?

시간이 지남에 따라 PHP는 보안에 중점을 둔 언어가되었습니다. 기본적으로 꺼져 있던 설정은 이제 기본적으로 켜져 있습니다. 이것의 완벽한 예 E_STRICTPHP 5.4.0부터 기본적으로 켜져 있습니다.

또한 PHP 문서에 따르면 E_NOTICEphp.ini 에서는 기본적 으로 비활성화되어 있습니다. PHP 문서 는 디버깅을 위해 켜는 것이 좋습니다 . 그러나 우분투 리포지토리와 BitNami의 Windows 스택에서 PHP를 다운로드하면 다른 것이 보입니다.

; Common Values:
;   E_ALL (Show all errors, warnings and notices including coding standards.)
;   E_ALL & ~E_NOTICE  (Show all errors, except for notices)
;   E_ALL & ~E_NOTICE & ~E_STRICT  (Show all errors, except for notices and coding standards warnings.)
;   E_COMPILE_ERROR|E_RECOVERABLE_ERROR|E_ERROR|E_CORE_ERROR  (Show only errors)
; Default Value: E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED
; Development Value: E_ALL
; Production Value: E_ALL & ~E_DEPRECATED & ~E_STRICT
; http://php.net/error-reporting
error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT

공지 사항 error_reporting실제로 기본적으로 생산 값으로 설정하지 기본적으로 "기본"값으로 설정합니다. 이것은 다소 혼란스럽고 php.ini 외부에서 문서화되지 않았으므로 다른 배포판에서 이것을 검증 하지 않았습니다 .

그러나 귀하의 질문에 대답하기 위해이 오류는 이전에 팝업되지 않았을 때 나타납니다.

  1. PHP를 설치했고 새로운 기본 설정이 다소 문서화되어 있지 않지만 제외하지는 않습니다 E_NOTICE.

  2. E_NOTICE정의되지 않은 변수 및 정의되지 않은 인덱스와 같은 경고는 실제로 코드를 더 깨끗하고 안전하게 만드는 데 도움이됩니다. 몇 년 전, E_NOTICE활성화 상태를 유지 하면 변수를 선언해야한다고 말할 수 있습니다 . 그것은 C를 배우기가 훨씬 쉬워졌고 변수를 선언하지 않았기 때문에 귀찮은 것보다 컸습니다.

IT에 대해 무엇을 할 수 있습니까?

  1. E_NOTICE"기본값"을 복사 E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED하고 등호 로그인 후 현재 주석 처리되지 않은 값으로 바꾸어 끄십시오 error_reporting =. CGI 또는 FPM을 사용하는 경우 Apache 또는 PHP를 다시 시작하십시오. "옳은"php.ini를 편집하고 있는지 확인하십시오. PHP-FPM을 실행하는 경우 Apache, fpm 또는 php-fpm, PHP-CGI를 실행하는 경우 cgi 등을 사용하여 PHP를 실행하는 경우 올바른 방법은 Apache입니다. 권장되는 방법은 아니지만 레거시 코드가있는 경우 편집하기가 매우 어려우면 최선의 방법 일 수 있습니다.

  2. E_NOTICE파일 또는 폴더 레벨을 끄십시오 . 레거시 코드가 있지만 "올바른"방식으로 작업을 수행하려는 경우이 방법이 더 좋습니다. 이를 위해서는 Apache2, Nginx 또는 선택한 서버가 무엇이든 상담해야합니다. Apache에서는 php_value내부를 사용 <Directory>합니다.

  3. 깔끔하게 코드를 다시 작성하십시오. 당신은 프로덕션 환경으로 이동하는 동안이 작업을 수행해야하거나, 당신의 오류를보고 사람을 하시겠습니까 오류의 표시를 해제하고, 만하지 않으면 로그인 (참조하여 오류 display_errorslog_errorsphp.ini 파일과 서버 설정) .

옵션 3을 확장하려면이 방법이 이상적입니다. 이 길을 갈 수 있다면해야합니다. 처음에이 경로를 사용하지 않는 경우 개발 환경에서 코드를 테스트하여이 경로를 이동하는 것이 좋습니다. 당신이 그것에있는 동안 , 미래에 무엇이 잘못 될 수 있는지 제거 ~E_STRICT하고 ~E_DEPRECATED보십시오. 익숙하지 않은 오류가 많이 있지만 앞으로 PHP를 업그레이드해야 할 때 불쾌한 문제가 발생하는 것을 막을 수 있습니다.

오류는 무엇을 의미합니까?

Undefined variable: my_variable_name-사용하기 전에 변수를 정의하지 않았을 때 발생합니다. PHP 스크립트가 실행될 때 내부적으로는 null 값을 가정합니다. 그러나 어떤 시나리오에서 변수를 정의하기 전에 확인해야합니까? 궁극적으로 이것은 "느슨한 코드"에 대한 논쟁입니다. 개발자는 변수가 정의 될 수있는 범위 내에서 변수가 높은 것으로 정의 된 오픈 소스 프로젝트를 볼 때이를 좋아한다고 말할 수 있습니다. 앞으로 어떤 변수가 나타날지 쉽게 알 수 있으며 코드를 쉽게 읽고 배울 수 있습니다.

function foo()
{
    $my_variable_name = '';

    //....

    if ($my_variable_name) {
        // perform some logic
    }
}

Undefined index: my_index-배열의 값에 액세스하려고하는데 존재하지 않는 경우에 발생합니다. 이 오류를 방지하려면 조건부 검사를 수행하십시오.

// verbose way - generally better
if (isset($my_array['my_index'])) {
    echo "My index value is: " . $my_array['my_index'];
}

// non-verbose ternary example - I use this sometimes for small rules.
$my_index_val = isset($my_array['my_index'])?$my_array['my_index']:'(undefined)';
echo "My index value is: " . $my_index_val;   

또 다른 옵션은 함수 맨 위에 빈 배열을 선언하는 것입니다. 항상 가능하지는 않습니다.

$my_array = array(
    'my_index' => ''
);

//...

$my_array['my_index'] = 'new string';

(추가 팁)

  • 이 문제와 다른 문제가 발생했을 때 NetBeans IDE (무료)를 사용 하여 많은 경고와 통지를 받았습니다. 그들 중 일부는 매우 유용한 팁을 제공합니다. 이것은 요구 사항이 아니며 대규모 프로젝트를 제외하고는 더 이상 IDE를 사용하지 않습니다. 나는 요즘 더 많은 vim사람입니다 :).

6

정의되지 않은 인덱스는 예를 들어 사용할 수없는 배열 인덱스를 요청한 배열을 의미합니다.

<?php 

$newArray[] = {1,2,3,4,5};
print_r($newArray[5]);

?>

정의되지 않은 변수는 기존 변수를 완전히 사용하지 않았거나 해당 이름으로 정의되거나 초기화되지 않은 것을 의미합니다.

<?php print_r($myvar); ?>

정의되지 않은 오프셋은 존재하지 않는 키를 요청한 배열을 의미합니다. 이에 대한 해결책은 사용하기 전에 확인하는 것입니다

php> echo array_key_exists(1, $myarray);

4

질문 의이 부분에 관해서 :

왜 갑자기 나타 납니까? 이 스크립트를 몇 년 동안 사용해 왔으며 아무런 문제가 없었습니다.

명확한 답변은 없지만 설정이 '갑자기'변경 될 수있는 이유에 대한 설명은 다음과 같습니다.

  1. error_reporting, display_errors 또는 기타 관련 설정에 대한 다른 기본값을 가질 수있는 최신 버전으로 PHP를 업그레이드했습니다.

  2. 당신은 제거하거나 실행시 설정 관련 설정을 사용하는 것이 (종속성에서 가능) 일부 코드를 도입 ini_set()하거나 error_reporting()(코드에서 이러한 검색)

  3. 웹 서버 구성을 변경했습니다 (여기서 아파치 가정) : .htaccess파일 및 호스트 구성도 PHP 설정을 조작 할 수 있습니다.

  4. 일반적으로 알림이 표시 /보고되지 않으므로 ( PHP 설명서 참조 ) 서버를 설정할 때 php.ini 파일을 어떤 이유로로드 할 수없고 (파일 권한 ??) 기본 설정에있을 수 있습니다. . 나중에 '버그'가 우연히 해결되었으며 이제는 알림을 표시하도록 error_reporting이 설정된 올바른 php.ini 파일을로드 할 수 있습니다.


3

클래스로 작업하는 경우 $this다음을 사용하여 멤버 변수를 참조해야합니다 .

class Person
{
    protected $firstName;
    protected $lastName;

    public function setFullName($first, $last)
    {
        // Correct
        $this->firstName = $first;

        // Incorrect
        $lastName = $last;

        // Incorrect
        $this->$lastName = $last;
    }
}

3

정의되지 않은 인덱스 알림이 발생하는 또 다른 이유는 데이터베이스 쿼리에서 열이 생략 되었기 때문입니다.

즉 :

$query = "SELECT col1 FROM table WHERE col_x = ?";

그런 다음 루프 내에서 더 많은 열 / 행에 액세스하려고합니다.

즉 :

print_r($row['col1']);
print_r($row['col2']); // undefined index thrown

또는 while루프에서 :

while( $row = fetching_function($query) ) {

    echo $row['col1'];
    echo "<br>";
    echo $row['col2']; // undefined index thrown
    echo "<br>";
    echo $row['col3']; // undefined index thrown

}

주목해야 할 사항은 * NIX OS 및 Mac OS X에서 대소 문자를 구분한다는 것입니다.

스택의 다음 Q & A를 참조하십시오.


3

삼항을 사용하는 것은 간단하고 읽기 쉽고 깨끗합니다.

Pre PHP 7
변수가 설정되어 있으면 다른 변수의 값에 변수를 할당하고, 그렇지 않으면null(또는 필요한 기본값)을 할당하십시오.

$newVariable = isset($thePotentialData) ? $thePotentialData : null;

PHP 7+ Null Coalescing Operator
사용을 제외하고 동일 합니다. 이것이 내장되어 있으므로 더 이상 호출 할 필요가 없으며 검사중인 변수의 값을 반환한다고 가정 할 때 반환 할 변수를 제공 할 필요가 없습니다. isset()

$newVariable = $thePotentialData ?? null;

둘 다 OP 질문에서 통지를 중지하며 둘 다 정확히 다음과 같습니다.

if (isset($thePotentialData)) {
    $newVariable = $thePotentialData;
} else {
    $newVariable = null;
}

 
새 변수를 설정할 필요가 없으면 with echo, function arguments 등 삼항의 반환 값을 직접 사용할 수 있습니다 .

에코:

echo 'Your name is: ' . isset($name) ? $name : 'You did not provide one';

함수:

$foreName = getForeName(isset($userId) ? $userId : null);

function getForeName($userId)
{
    if ($userId === null) {
        // Etc
    }
}

위의 내용은 세션 등을 포함하여 배열과 동일하게 작동하며 검사중인 변수를 예를 들어 다음과 같이 대체합니다
$_SESSION['checkMe']
.
$clients['personal']['address']['postcode']


 

억압:

@오류보고 수준으로 PHP 공지를 표시하지 않거나 줄일 수 있지만 문제를 해결하지는 않으며 오류 로그에보고 되지 않습니다 . 이는 코드에서 설정되지 않은 변수를 사용하려고 시도했지만 누락 된 값이 얼마나 중요한지에 따라 의도 한대로 작동하지 않을 수도 있음을 의미합니다.

실제로이 문제를 확인하고 적절하게 처리하여 다른 메시지를 제공하거나 정확한 상태를 식별하기 위해 다른 모든 항목에 대해 null 값을 반환해야합니다.

통지가 오류 로그에없는 것을 신경 쓰면 옵션으로 오류 로그를 무시할 수 있습니다.


1

HTML 양식이 제출 된 후 존재하지 않는 변수의 일반적인 원인 중 하나 는 양식 요소가 <form>태그 내에 포함되어 있지 않기 때문입니다 .

예 : 안에 포함되지 않은 요소 <form>

<form action="example.php" method="post">
    <p>
        <input type="text" name="name" />
        <input type="submit" value="Submit" />
    </p>
</form>

<select name="choice">
    <option value="choice1">choice 1</option>
    <option value="choice2">choice 2</option>
    <option value="choice3">choice 3</option>
    <option value="choice4">choice 4</option>
</select>

예 : 요소가 이제 <form>

<form action="example.php" method="post">
    <select name="choice">
        <option value="choice1">choice 1</option>
        <option value="choice2">choice 2</option>
        <option value="choice3">choice 3</option>
        <option value="choice4">choice 4</option>
    </select>
    <p>
        <input type="text" name="name" />
        <input type="submit" value="Submit" />
    </p>
</form>

0

아마 당신은 이전 PHP 버전을 사용하고 있었고 지금은 PHP를 업그레이드했기 때문에 몇 년 전부터 오류없이 작동했습니다. PHP4까지는 변수를 정의하지 않고 변수를 사용하는 경우 오류가 없었지만 PHP5부터는 언급 된 코드에 대해 오류가 발생합니다.


0

파일을 다룰 때, 적절한 enctype과 POST 메소드가 필요합니다. 이는 양식에 포함되지 않은 경우 정의되지 않은 색인 통지를 트리거합니다.

매뉴얼에는 다음과 같은 기본 구문이 있습니다.

HTML

<!-- The data encoding type, enctype, MUST be specified as below -->
<form enctype="multipart/form-data" action="__URL__" method="POST">
    <!-- MAX_FILE_SIZE must precede the file input field -->
    <input type="hidden" name="MAX_FILE_SIZE" value="30000" />
    <!-- Name of input element determines name in $_FILES array -->
    Send this file: <input name="userfile" type="file" />
    <input type="submit" value="Send File" />
</form>

PHP

<?php
// In PHP versions earlier than 4.1.0, $HTTP_POST_FILES should be used instead
// of $_FILES.

$uploaddir = '/var/www/uploads/';
$uploadfile = $uploaddir . basename($_FILES['userfile']['name']);

echo '<pre>';
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
    echo "File is valid, and was successfully uploaded.\n";
} else {
    echo "Possible file upload attack!\n";
}

echo 'Here is some more debugging info:';
print_r($_FILES);

print "</pre>";

?>

참고:


0

나는 이것에 대해 질문을했고 메시지와 함께이 게시물에 언급되었습니다.

이 질문에는 이미 답변이 있습니다.

PHP를 사용한 "알림 : 정의되지 않은 변수", "알림 : 정의되지 않은 색인"및 "알림 : 정의되지 않은 오프셋"

내 질문과 해결책을 여기에서 공유하고 있습니다.

이것은 오류입니다.

여기에 이미지 설명을 입력하십시오

154 행이 문제입니다. 이것이 154 행에있는 것입니다.

153    foreach($cities as $key => $city){
154        if(($city != 'London') && ($city != 'Madrid') && ($citiesCounterArray[$key] >= 1)){

문제는 내가 변수 $city가 아닌 변수의 조건을 작성하고 있다는 것 입니다 $key => $city. 먼저 이것이 경고의 원인인지 확인할 수 있습니까? 둘째, 이것이 문제라면 왜 값을 기반으로 조건을 작성할 수없는 것입니까? 조건을 작성하는 데 필요한 키가 있어야합니까?

업데이트 1 : 문제는을 실행할 때 $citiesCounterArray[$key]때로는 배열에 $key존재하지 않는 키에 해당 $citiesCounterArray하지만 항상 내 루프의 데이터를 기반으로하는 것은 아닙니다. 내가 필요한 것은 $key배열에 존재 하는 경우 코드를 실행하고 그렇지 않으면 건너 뛰 도록 조건을 설정하는 것입니다.

업데이트 2 : 이것은 다음을 사용하여 수정 한 방법입니다 array_key_exists().

foreach($cities as $key => $city){
    if(array_key_exists($key, $citiesCounterArray)){
        if(($city != 'London') && ($city != 'Madrid') && ($citiesCounterArray[$key] >= 1)){

0

이러한 오류는 설정되지 않은 변수를 사용할 때마다 발생합니다.

이를 처리하는 가장 좋은 방법은 개발 중에 오류보고를 설정하는 것입니다.

오류보고를 설정하려면 다음을 수행하십시오.

ini_set('error_reporting', 'on');
ini_set('display_errors', 'on');
error_reporting(E_ALL);

프로덕션 서버에서는 오류보고가 해제되어 있으므로 이러한 오류가 발생하지 않습니다.

그러나 개발 서버에서는 오류보고를 설정할 수 있습니다.

이 오류를 없애기 위해 다음 예제를 봅니다.

if ($my == 9) {
 $test = 'yes';  // Will produce error as $my is not 9.
}
echo $test;

NULL값을 할당하거나 사용하기 전에 변수를 초기화 할 수 있습니다.

따라서 코드를 다음과 같이 수정할 수 있습니다.

$test = NULL;
if ($my == 9) {
 $test = 'yes';  // Will produce error as $my is not 9.
}
echo $test;

이것은 프로그램 논리를 방해 $test하지 않으며 가치가 없어도 통지를 생성 하지 않습니다.

따라서 기본적으로 개발시 오류보고를 ON으로 설정하는 것이 좋습니다.

그리고 모든 오류를 수정하십시오.

그리고 프로덕션에서는 오류보고를 해제로 설정해야합니다.


-1

당신이 사용 된 변수가 없기 때문에 이러한 통지는 defined하고 my_index키에 존재하지 않았다 $my_array변수입니다.

해당 통지는 귀하 code가 정확하지 않지만 통지를보고하지 않았기 때문에 매번 트리거 되었습니다.

버그를 해결하십시오.

$my_variable_name = "Variable name"; // defining variable
echo "My variable value is: " . $my_variable_name;

if(isset($my_array["my_index"])){
    echo "My index value is: " . $my_array["my_index"]; // check if my_index is set 
}

이것을 얻는 또 다른 방법 :

ini_set("error_reporting", false)

-2

PHP에서 변수를 사용하려면 변수를 정의하기 위해 주먹이 필요합니다.
변수가 매우 효율적으로 정의되어 있는지 확인할 수 있습니다!.

//If you only want to check variable has value and value has true and false value.
//But variable must be defined first.

if($my_variable_name){

}

//If you want to check variable is define or undefine
//Isset() does not check that variable has true or false value
//But it check null value of variable
if(isset($my_variable_name)){

}

간단한 설명

//It will work with :- true,false,NULL
$defineVarialbe = false;
if($defineVarialbe){
    echo "true";
}else{
    echo "false";
}

//It will check variable is define or not and variable has null value.
if(isset($unDefineVarialbe)){
    echo "true";
}else{
    echo "false";
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.