49

簡単なログイン スクリプトを作成するための PHP の基本を再学習しようとしていますが、以前に受け取ったことのないエラーが表示されます (1 年ちょっと前に同じスクリプトを作成しましたが、このエラーは発生しませんでした。コードをできるだけ単純化しました。問題のある領域を確認するためにテストすることができました。ここに問題があります。

<?php
$user = $_POST["username"];
if($user != null)
{
    echo $user;
    echo " is your username";
}
else
{
    echo "no username supplied";
}
?>

変数をスクリプトに送信すると、このコードは正常に機能しますが、変数が指定されていない場合はエラーが発生します。ユーザー名/パスが指定されていない場合はエラーが予想されるため、理論的にはこれで問題ありません。コードがスクリプトに送信される前にこれを確認する予定ですが、どういうわけか空の文字列が漏れて未知のエラーが吐き出されるのではないかと心配しています. これが私が得るエラーです:

( ! ) Notice: Undefined index: username in C:\wamp\www\verify_login.php on line 2

Call Stack

    Time    Memory  Function    Location
1   0.0003  668576  {main}( )   ..\verify_login.php:0

ユーザー名が指定されていません

ご覧のとおり、変数が提供されていないことをコードが記録していますが、変数が見つからなかったことを意味すると思われるエラーが発生します。誰かが私のためにこれを明確にしてもらえますか?

4

10 に答える 10

73

nullPHP では、一度も設定されていない変数または配列要素は、値が;である要素とは異なります。このような未設定の値にアクセスしようとすると、実行時エラーが発生します。

配列$_POSTの key に要素がない"username"ため、無効性テストに到達する前にインタープリターがプログラムを中止します。

さいわい、実際にアクセスを試みることなく、変数または配列要素の存在をテストできます。それが特別な演算子issetが行うことです:

if (isset($_POST["username"]))
{
  $user = $_POST["username"];
  echo $user;
  echo " is your username";
} 
else 
{
  $user = null;
  echo "no username supplied";
}

$_POST["username"]これは、PHPが function に引数として渡すの値を取得しようとすると、コードとまったく同じように爆発するように見えますisset()。ただし、実際にisset()はまったく関数ではなく、評価段階の前に認識される特別な構文であるため、PHP インタープリターは実際に値を取得しようとせずに値の存在をチェックします。

E_NOTICEまた、実行時エラーが発生すると、欠落している配列要素はマイナーなものと見なされる (レベルが割り当てられる) ことにも言及する価値があります。通知が無視されるようにレベルを変更するerror_reportingと、元のコードは実際には記述どおりに機能し、試行された配列アクセスは を返しnullます。しかし、それは、特に製品コードの場合、悪い習慣と見なされています。

補足: PHP は文字列補間を行うためecho、ブロック内のステートメントifを 1 つにまとめることができます。

echo "$user is your username";
于 2012-05-30T04:23:29.397 に答える
7

使用する:

if (isset($_POST['user'])) {
   //do something
}

しかし、おそらくもっと適切な検証を使用する必要があります。単純な正規表現、または Zend Framework または Symfony からの堅牢な実装を試してください。

http://framework.zend.com/manual/en/zend.validate.introduction.html

http://symfony.com/doc/current/book/validation.html

または、組み込みのフィルター拡張機能でさえ:

http://php.net/manual/en/function.filter-var.php

ユーザーの入力を決して信用しないでください。賢く行動してください。何も信用しないでください。あなたが受け取るものが本当にあなたが期待するものであることを常に確認してください. 数値でなければならない場合は、数値であることを確認してください。

大幅に改善されたコード:

$user = filter_var($_POST['user'], FILTER_SANITIZE_STRING);
$isValid = filter_var($user, FILTER_VALIDATE_REGEXP, array('options' => array('regexp' => "/^[a-zA-Z0-9]+$/")));

if ($isValid) {
    // do something
}

サニタイズと検証。

于 2012-05-30T04:22:47.417 に答える
5

PHP 5.2.0 より前のバージョンfilter_input()では、特定の外部ユーザー入力 (get、post、cookie 変数など) を名前で取得するために特別に作成されたものを使用し、必要に応じてそれをフィルター処理して、サイトへの XSS/インジェクション攻撃を回避する必要があります。例えば:

$user = filter_input(INPUT_POST, 'username');

INPUT_GET、INPUT_POST、INPUT_COOKIE、INPUT_SERVER、または INPUT_ENV のいずれかを使用できます。

オプションの 3 番目の引数を使用することで、さまざまなフィルター(検証サニタイズフィルタリングなど)によって拡張できます(例: 、など) 。FILTER_SANITIZE_SPECIAL_CHARSFILTER_SANITIZE_ENCODED

例えば:

<?php
$search_html = filter_input(INPUT_GET, 'search', FILTER_SANITIZE_SPECIAL_CHARS);
$search_url = filter_input(INPUT_GET, 'search', FILTER_SANITIZE_ENCODED);
echo "You have searched for $search_html.\n";
echo "<a href='?search=$search_url'>Search again.</a>";
?>

構文は次のとおりです。

混合filter_input( int $type , string $variable_name [, int $filter = FILTER_DEFAULT [, mixed $options ]] )

(PHP 5 >= 5.2.0、PHP 7)

参照:なぜ filter_input() を使用する方が良いのですか?

于 2016-03-22T08:06:20.433 に答える
5

isset()エラーをミュートする短いものを使用する代わりに、@$_POST['field']. 次に、フィールドが設定されていない場合、ページにエラーが出力されません。

于 2014-12-23T22:29:47.200 に答える
3

あなたのコードは何かの存在を前提としています:

$user = $_POST["username"];

$_POSTPHP は、配列に「ユーザー名」がないことを知らせています。この場合、値isset()にアクセスする前に値を確認する方が安全です。

if ( isset( $_POST["username"] ) ) {
    /* ... proceed ... */
}

または、オペレーターをハイジャックし||てデフォルトを割り当てることもできます。

$user = $_POST["username"] || "visitor" ;

ユーザー名がの値でない限り、この方法はかなり信頼できると考えることができます。default-assignment へのはるかに安全なルートは、三項演算子を使用することです。

$user = isset( $_POST["username"] ) ? $_POST["username"] : "visitor" ;
于 2012-05-30T04:25:08.117 に答える
2

これを試して:

$_POST リクエストがあるところならどこでもこれを使用します。

$username=isset($_POST['username']) ? $_POST['username'] : "";

これは単純なブール値です。設定されている場合は $_POST['username'] に設定され、設定されていない場合は空の文字列に設定されます。

使用例:

if($username===""){ echo "Field is blank" } else { echo "Success" };
于 2015-10-04T09:42:24.533 に答える
2

これは古い投稿であることは知っていますが、誰かが助けることができます:

function POST($index, $default=NULL){
        if(isset($_POST[$index]))
        {
            if(!empty(trim($_POST[$index])))    
                return $_POST[$index];
        }
        return $default;
    }

上記のコードは、私がどこでも使用する基本的な POST 関数です。ここでは、フィルター、正規表現などを配置できます。より高速でクリーンです。私の高度な POST 関数は、配列、文​​字列型、デフォルト値などを受け入れてチェックするのがより複雑です。ここで想像力を働かせましょう。

次のように簡単にユーザー名を確認できます。

$username = POST("username");
if($username!==null){
    echo "{$username} is in the house.";
}

$defaultまた、POST がアクティブでない場合やコンテンツが存在しない場合にデフォルト値を定義できる文字列を追加しました。

echo "<h1>".POST("title", "Stack Overflow")."</h1>";

それで遊びます。

于 2016-03-23T16:10:37.557 に答える
1

あなたが言う時:

$user = $_POST["username"];

のキー (またはインデックス) を持つ配列$userの値を割り当てるように PHP インタープリターに要求しています。存在しない場合、PHP は適合をスローします。$_POSTusername

isset($_POST['user'])その変数の存在を確認するために使用します。

if (isset($_POST['user'])) {
  $user = $_POST["username"];
  ...
于 2012-05-30T04:23:52.323 に答える
0

試す

if(isset($_POST['username']))
    echo $_POST['username']." is your username";
else
    echo "no username supplied";
于 2012-05-30T04:25:15.677 に答える
-2

関連する質問: PHP 通知を生成せずに未知の配列要素にアクセスする最良の方法は何ですか?

上記の質問の回答を使用すると、キーが存在しない場合に PHP 通知を生成せずに $_POST から安全に値を取得できます。

echo _arr($_POST, 'username', 'no username supplied');  
// will print $_POST['username'] or 'no username supplied'
于 2012-05-30T04:25:27.920 に答える