Programing

PHP를 사용한“주의 : 정의되지 않은 변수”,“주의 : 정의되지 않은 인덱스”,“주의 : 정의되지 않은 오프셋”

lottogame 2020. 9. 27. 12:40
반응형

PHP를 사용한“주의 : 정의되지 않은 변수”,“주의 : 정의되지 않은 인덱스”,“주의 : 정의되지 않은 오프셋”


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

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

알림 : 정의되지 않은 인덱스 : my_index C : \ wamp \ www \ mypath \ index.php on line 11

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

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

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

왜 갑자기 나타나나요? 나는이 스크립트를 수년간 사용 해왔고 전혀 문제가 없었습니다.

어떻게 수정합니까?


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

관련 메타 토론 :


주의 : 정의되지 않은 변수

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. 의 경우 $_POST$_GET그냥 인덱스가 존재 여부를 당신이 그들을 사용하기 전에 있는지 확인해야합니다. 들어 $_SESSION당신이 할 필요가 있는지 당신은 시작 세션이 session_start()인덱스도 존재합니다.

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

관련 :


이것을 시도하십시오

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);

세션에 대한 참고 사항 :


오류 표시 @연산자

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

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

  • @$_GET/ $_POSTinput 매개 변수, 특히 선택 사항 인 경우 주로 허용됩니다 .

그리고 여기에는 이러한 질문의 대부분이 포함되므로 가장 일반적인 원인에 대해 확장 해 보겠습니다.

$_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"]$_GET["sort"].

  • 마지막으로 매개 변수를 예상하지만 수신하지 않는 경우 <form><input> 선언을 확인하십시오 .

    • 각 필수 입력에 <input name=FOO>
    • id=또는 title=속성이 충분하지 않습니다.
    • method=POST양식을 채울한다고 $_POST.
    • 반면 a 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 요청에.
  • 또한 유효성 시간이 초과되면 하위 도메인 또는 개별 경로에 대한 제약이 될 수 있으며 사용자와 브라우저는이를 거부하거나 삭제할 수 있습니다.

일반적으로 "나쁜 프로그래밍"과 지금 또는 나중에 실수 할 가능성이 있기 때문입니다.

  1. 실수라면 먼저 변수에 적절한 할당을하십시오. $ varname = 0;
  2. 가끔 만 정의되는 경우 if (isset($varname))사용하기 전에 테스트하십시오.
  3. 철자가 틀 렸기 때문이라면 바로 수정하세요
  4. PHP 설정 에서 경고를 해제 할 수도 있습니다.

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


도움이되기 때문에 알림을 비활성화하고 싶지 않았지만 너무 많은 입력을 피하고 싶었습니다.

내 솔루션은 다음과 같습니다.

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')?>

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

$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');

변수 '$ 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;

""에 대한 대답으로 그들은 왜 갑자기 나타나나요? 몇 년 동안이 스크립트를 사용해 왔는데 문제가 없었습니다. "

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

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

이 경우에 일어난 일은 error_reporting알림을 표시하도록 변경 되었거나 (예제에 따라) 설정이 display_errors화면 에서 변경된 것 입니다 ( 설정 을 억제 / 로깅하는 대신).

왜 변경 되었습니까?

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

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

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

이 중 어떤 것도 변경되었을 수 있습니다.

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

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

요약

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

빠른 수정은 코드 상단에서 변수를 null에 할당하는 것입니다.

$user_location = null;

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

예를 들어 이것이 영리하다고 생각했다면 속기 코드 :

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

...다시 생각 해봐! 더 나은 솔루션은 다음과 같습니다.

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

(사용자 지정 html()기능을 사용하여 문자를 이스케이프합니다. 마일리지가 다를 수 있습니다.)


나는 항상 변수를 자동으로 선언하는 유용한 함수 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;
}

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


$user_location = '';
또는
$user_location = 'Los Angles';
이것은 직면 할 수있는 매우 일반적인 오류이므로 변수를 선언하고 Enjoy Coding 만 걱정하지 마십시오 .


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


일을 단순하게 유지하는 것이 어떻습니까?

<?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

?>

왜 이런 일이 발생합니까?

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

또한 PHP 문서에 따르면 기본적 E_NOTICE으로 php.ini에서 비활성화되어 있습니다. PHP 문서 는 디버깅 목적으로 사용 하도록 권장 합니다 . 그러나 Ubuntu 저장소와 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를 배우는 것이 훨씬 더 쉬워졌습니다.

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

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

  2. E_NOTICE파일 또는 폴더 수준을 끕니다 . 레거시 코드가 있지만 그렇지 않은 경우 "올바른"방식으로 작업하려는 경우이 방법이 더 좋습니다. 이렇게하려면 Apache2, Nginx 또는 원하는 서버를 참조해야합니다. 아파치에서는 사용하는 것이 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요즘 사람에 가깝다. :).

정의되지 않은 색인은 사용할 수없는 배열 색인을 요청한 배열을 의미합니다.

<?php 

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

?>

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

<?php print_r($myvar); ?>

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

php> echo array_key_exists(1, $myarray);

질문의이 부분과 관련하여 :

왜 갑자기 나타나나요? 나는이 스크립트를 수년간 사용 해왔고 전혀 문제가 없었습니다.

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

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

  2. ini_set()또는 error_reporting()(코드에서 검색)을 사용하여 런타임에 관련 설정을 설정하는 일부 코드 (종속성에있을 수 있음)를 제거하거나 도입 했습니다.

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

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


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

class Person
{
    protected $firstName;
    protected $lastName;

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

        // Incorrect
        $lastName = $last;

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

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

즉 :

$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에서는 대소 문자를 구분한다는 것입니다.

Stack에 대한 다음 Q & A를 참조하십시오.


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

PHP 7 이전
변수가 설정된 경우 다른 변수의 값에 할당하고 그렇지 않으면 할당null(또는 필요한 기본값 ) :

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

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

$newVariable = $thePotentialData ?? null;

둘 다 OP 질문의 통지를 중지하며 둘 다 다음과 정확히 동일합니다.

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

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

에코:

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
    }
}

위의 내용은 세션 등을 포함하여 배열과 동일하게 작동하며 검사되는 변수를 eg :
$_SESSION['checkMe']
또는 필요한 수준의 깊이로 대체합니다 .
$clients['personal']['address']['postcode']


 

억압:

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

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

알림이 오류 로그에없는 것에 관심이 있다면 옵션으로 오류 로그를 무시할 수 있습니다.


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


파일을 처리 할 때 적절한 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>";

?>

참고:


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>

이에 대해 질문을했고 다음 메시지와 함께이 게시물을 참조했습니다.

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

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)){

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

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

오류보고를 설정하려면 :

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으로 설정하는 것이 항상 좋습니다.

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

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


당신이 사용 된 변수가 없기 때문에 이러한 통지는 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)

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";
}

참고 URL : https://stackoverflow.com/questions/4261133/notice-undefined-variable-notice-undefined-index-and-notice-undefined

반응형