PHPを使用した「通知:未定義の変数」、「通知:未定義のインデックス」、および「通知:未定義のオフセット」


1173

PHPスクリプトを実行していますが、次のようなエラーが発生し続けます。

通知:未定義の変数:10行目のC:\ wamp \ www \ mypath \ index.phpのmy_variable_name

通知:未定義のインデックス: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られないようにするための提案です。引用符を削除しすぎている場合もあります。またはPHP: “Undefined variable/index/offset” notices
Funk Forty Niner

2
@Fred両方のバリエーションについて議論ができると思います。これは、初心者が "Notice:"を含む行全体を検索クエリに入力する可能性があるため、この質問の主要なトラフィックジェネレータであると確信しています。メッセージが完全にそこにある場合、検索エンジンでの視認性が向上する可能性があります
Pekka

2
@Pekka웃わかりました。私は、理由だけでURLが途中でカットされませんでしたし、今それがでないことを言いましたand-notice-undef。それは(ほんの)提案でした。それだけでも繰り返されNotice: Undefinedます。
Funk Forty Niner 2017年

回答:


1066

通知:未定義の変数

PHPマニュアルの広大な知識から:

初期化されていない変数のデフォルト値に依存することは、同じ変数名を使用する別のファイルに1つのファイルを含める場合に問題になります。また、register_globalsをオンにした場合の主要なセキュリティリスクでもあります。E_NOTICEレベルのエラーは、初期化されていない変数を操作する場合に発行されますが、初期化されていない配列に要素を追加する場合には発行されません。isset()言語構造を使用して、変数がすでに初期化されているかどうかを検出できます。さらに、より理想的なのは、変数が初期化されていない場合に警告またはエラーメッセージを生成しないため、empty()のソリューションです。

PHPのドキュメントから:

変数が存在しない場合、警告は生成されません。つまり、 empty()は基本的に!isset($ var)||と同等の簡潔なものです。$ var == false

これは、あなただけ使用できることを意味しempty()、変数が設定され、しかもそれは、次のに対して変数をチェックしているかどうかを判断するために、00.0"""0"nullfalseまたは[]

例:

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

2つの変数を使用して2つの配列要素にアクセスしますが、配列要素indexは1つしかない0ため、次のように生成されます。

通知:未定義のオフセット:1

$_POST/ $_GET/ $_SESSION変数

上記の注意事項は$_POST$_GETまたはを使用しているときによく表示され$_SESSIONます。用$_POSTして$_GET、あなたはちょうどあなたがそれらを使用する前にインデックスが存在するかどうかをチェックする必要があります。以下のために$_SESSIONあなたが作るために持っていることを確認あなたが開始されたセッション持ちsession_start()、インデックスも存在していることを。

また、3つの変数はすべてスーパーグローバルであり、大文字であることにも注意してください。

関連:


7
@ dieselpower44いくつかの考え: "シャットダウンオペレーター"(@)にはいくつかのパフォーマンスの問題があります。また、特定のスコープ内のすべてのエラーを抑制するため、注意して使用しないと、表示したいメッセージがマスクされる可能性があります。
IMSoP 2013年

6
問題を非表示にすることは、問題に対処する方法ではありません。アイテム#2 ...#4は、通常は運用サーバーでのみ使用できます。
Salman A

1
カスタムエラーハンドラーも使用されている場合、ハンドラーではなくインラインでメッセージをシャットダウンできますか?$var = @$_GET['nonexisting'];まだ通知を引き起こし...
Alph.Dev

18
$value = isset($_POST['value']) ? $_POST['value'] : '';4の代わりに1を使用することが推奨されるのはなぜ$value = @$_POST['value'];ですか?
forsvunnet 2015

@twistedpixelこれらの4つの方法は独立しており、4ステップのガイドではありません。したがって、方法4を使用することを選択した場合は、最初の3つの方法を実装していないため、まだエラーを抑制していません。
AycanYaşıt15年

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.iniようにしますerror_reporting = (E_ALL & ~E_NOTICE)
ahmd0


上記の答えから、私はisset、array_key_existsを試しましたが、うまくいきませんでした。私はあなたの答え、.empty()を試しました、そしてそれはうまくいきます。どうもありがとうございました!
ewef

63

エラー表示@演算子

望ましくない冗長な通知については、専用の@演算子を使用して» 未定義の変数/インデックスメッセージを非表示にすることができます。

$var = @($_GET["optional_param"]);
  • これは通常お勧めできません。新人はそれを使い過ぎる傾向があります。
  • 関数のパラメーターやループなど、アプリケーションロジックの深いコード(宣言してはならない変数を無視する必要がある場合は無視)には非常に不適切です。
  • オーバー逆さま1ありますisset?:??しかし超抑圧。通知は引き続きログに記録されます。そして、@隠された通知を復活させることができます: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);

    どちらも、スクリプトが正しいパラメータで呼び出されたか、またはパラメータを使用して呼び出されたかを明らかにします。

  • 別の方法として、またはさらにブラウザのdevtoolsF12を使用して、ネットワークタブでリクエストとパラメータを確認します。

    ブラウザ開発者ツール/ネットワークタブ

    POSTパラメーターとGET入力は別々に表示されます。

  • $_GETパラメータについてはQUERY_STRING

    print_r($_SERVER);

    PHPには、非標準のパラメーター名をスーパーグローバルに合体させるためのいくつかのルールがあります。Apacheもいくつかの書き換えを行う可能性があります。$_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
    • 一方、method=GET(または省略して)$_GET変数が生成されます。
    • action=script.php?get=param$ _GETおよびmethod=POST$ _POSTの残りのフィールドを介してフォームが提供することも可能です。
    • 最近のPHP構成(≥5.6)では、GETおよびPOSTパラメーターをマッシュする、再び使用することが実現可能(ファッショナブルではない)になっています$_REQUEST['vars']
  • mod_rewriteを使用している場合は、の両方をチェックし、がパラメーターがないことを理解access.logできるようにする必要がありRewriteLogます。

$_FILES

  • 同じ健全性チェックがファイルのアップロードとに適用されます$_FILES["formname"]
  • さらにチェック enctype=multipart/form-data
  • 同様method=POSTにあなたの<form>宣言で。
  • 参照:PHP未定義のインデックスエラー$ _FILES?

$_COOKIE

  • $_COOKIE配列は、右の後に読み込まれることはありませんsetcookie()が、唯一の任意のフォローHTTPリクエストに応じて、。
  • さらに、それらの有効性はタイムアウトし、サブドメインまたは個々のパスへの制約となる可能性があり、ユーザーとブラウザはそれらを拒否または削除することができます。

2
パフォーマンスへの影響に興味がある場合は、この記事で要約します(derickrethans.nl/…)
Gajus 2014

@GajusKuizinas 2009年以降、いくつかの変更があり、特にphp.net/ChangeLog-5.php#5.4.0は結果を大幅に変更します(「Zend Engine、パフォーマンス」および「(無音)演算子」を参照)。
マリオ

@mario、ありがとうございます。さて、誰かが2つをベンチマークするのに十分であった場合... 3v4l.org/CYVOn/perf#tabs 3v4l.org/FLp3D/perf#tabsこのテストによれば、同一であるように見えます(スケールの変化に注意してください)。
Gajus 2014

47

一般に、「プログラミングの誤り」、および現在または後で間違いが発生する可能性があるためです。

  1. それが誤りである場合は、最初に変数に適切な割り当てを行います。$ varname = 0;
  2. 実際に定義されていることが時々ある場合は、それをテストして if (isset($varname))から使用してください。
  3. スペルを間違えたことが原因である場合は、それを修正してください
  4. 多分あなたのPHP設定で警告を無効にする

5
警告をオフにしないでください。より厳密な言語では、「バグがある可能性があるため、この行を2回確認することをお勧めします」という意味です。PHPのように寛容な言語では、「このコードはがらくたであり、おそらくバグでおかされています。多少の感覚はありますが、できるだけ早く修正してください。」

5
私は最初の3つの点に同意しますが、#4は単に間違っています。問題を非表示にしても問題が解決するわけではなく、今後さらに問題が発生する可能性もあります。
Valentin Flachsel、2010年

1
@Freekは間違いなく真実ですが、一部のシナリオでは(スクリプトを購入し、技術的な知識がなく、明日までに実行する必要があります...)それはダクトテープソリューションです-本当に強調する必要がありますが、常に強調する必要があります
Pekka

ダクトテープがいい… 歴史的に警告は標準のPHP設定で無効にされていますが、デフォルトの設定はより厳しくなっています。あまりにも多くの人が顧客を困らせないように、古い設定に戻ります。
Erik

41

これは、まだ何も割り当てていない変数をテスト、評価、または印刷していることを意味します。これは、タイプミスがあるか、最初に変数が何かに初期化されていることを確認する必要があることを意味します。ロジックパスを確認してください。あるパスには設定されているが別のパスには設定されていない可能性があります。


34

通知は役立つので無効にしたくありませんでしたが、入力しすぎないようにしたかったのです。

私の解決策はこの関数でした:

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

したがって、$ nameを参照し、存在する場合はエコーする場合は、次のように記述します。

<?=ifexists('name')?>

配列要素の場合:

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

$ _REQUEST ['name']を参照したい場合は、ページ内:

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

2
あなたのifexists()関数は、PHP 5.3では動作しません。呼び出し側の変数は、(参照関数のローカルスコープでは利用できない変数のスコープを、彼らがない限り、)スーパーグローバルか、いじる$ GLOBALSので、$foo = "BABAR"; ifexists('foo');一般的なリターンはnullになります。(斜体はphp.netの章です。)
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、「オフ」または「syslog」に設定)。

この場合、何が起こったのかは、error_reporting(例に従って)通知も表示するように変更されたか、設定がdisplay_errors画面上に変更された(それらを抑制する/ログに記録するのではなく)ことです。

なぜ変わったのですか?

明白な/最も簡単な答えは、誰かがphp.iniでこれらの設定のいずれかを調整したか、PHPのアップグレードバージョンが以前とは異なるphp.iniを使用していることです。最初に見る場所です。

ただし、これらの設定を上書きすることもできます。

  • .htconf(vhostsとサブ構成を含むWebサーバー構成)*
  • .htaccess
  • PHPコード自体

これらのいずれも変更されている可能性があります。

また、Webサーバーの構成で.htaccessディレクティブを有効/無効にできるという複雑さが加わるため、.htaccessにディレクティブがあり、突然動作を開始/停止する場合は、それを確認する必要があります。

(.htconf / .htaccessは、Apacheとして実行していることを前提としています。コマンドラインを実行している場合、これは適用されません。IISまたは他のWebサーバーを実行している場合は、それに応じてこれらの構成を確認する必要があります)

概要

  • チェックerror_reportingdisplay_errorsphp.iniでPHPディレクティブが変更されていないか、以前と異なるのphp.iniを使用していないこと。
  • .htconf(またはvhostsなど)のチェックerror_reportingおよびdisplay_errorsPHPディレクティブは変更されていません
  • .htaccessのチェックerror_reportingおよびdisplay_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';
これは、直面する可能性のある非常に一般的なエラーです。変数を宣言して、Enjoy Codingを心配する必要はありません。


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_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 =ます。Apache、またはCGIまたはFPMを使用している場合はPHPを再起動します。「正しい」php.iniを編集していることを確認してください。正しい方法は、ApacheでPHPを実行している場合はApache、PHP-FPMを実行している場合はfpmまたはphp-fpm、PHP-CGIを実行している場合はcgiなどです。これは推奨される方法ではありませんが、編集が非常に難しい場合は、それが最善の策かもしれません。

  2. E_NOTICEファイルまたはフォルダレベルでオフにします。これは、レガシーコードがいくつかあるが、それ以外の場合は「正しい」方法で実行したい場合に適しています。これを行うには、Apache2、Nginx、または選択したサーバーが何であるかを調べてください。Apacheでは、のphp_value内部で使用します<Directory>

  3. よりクリーンになるようにコードを書き直してください。本番環境に移動させながら、これを実行する必要があるか、誰かがあなたのエラーを表示したくない場合は、必ずエラーのいずれかの表示を無効にしている、とだけ作るのロギング(参照あなたのエラーをdisplay_errorsし、log_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. PHPを新しいバージョンにアップグレードしました。これには、error_reporting、display_errors、またはその他の関連設定の他のデフォルトを設定できます。

  2. あなたは、削除または実行時に設定し、関連する設定を使用していること(依存関係でおそらく)いくつかのコードを導入しているini_set()error_reporting()(コードでこれらを検索します)

  3. ウェブサーバーの設定を変更しました(ここではapacheを想定しています)。.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

未定義のインデックス通知がスローされるもう1つの理由は、データベースクエリから列が省略されたことです。

すなわち:

$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を参照してください。


3

三項の使用はシンプルで読みやすく、クリーンです。

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

 
新しい変数を設定する必要がない場合はecho、関数の引数などを使用して、3項の戻り値を直接使用できます。

エコー:

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値を返す必要があります。

通知がエラーログに記録されないことだけに関心がある場合は、オプションとしてエラーログを単に無視することができます。


1

HTMLフォームの送信後に変数が存在しない一般的な原因の1つは、フォーム要素が<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を使用していたため、何年もの間、エラーが発生することなく動作していた理由は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。まず、それが警告の原因かどうかを確認してください。次に、それが問題である場合、値に基づいて条件を記述できないのはなぜですか?条件を記述するために必要なキーを使用する必要がありますか?

UPDATE 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せず、値がなくても通知を生成しません。

したがって、基本的に、開発のためにエラー報告をオンに設定することは常に優れています。

そして、すべてのエラーを修正します。

また、本番環境では、エラー報告をオフに設定する必要があります。


-1

これらの通知は、使用された変数がなくdefinedmy_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.