単純なログインスクリプトを作成するためのいくつかの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
ユーザー名が指定されていません
コードが変数を提供していないことを確認できますが、変数が見つからないことを意味するものと想定されるエラーが発生します。誰かがこれを明確にしてくれますか?
PHPでは、設定されていない変数または配列要素は、値がnull
;であるものとは異なります。そのようなnset値にアクセスしようとすると、ランタイムエラーになります。
それがあなたが実行していることです:配列$_POST
はキー"username"
に要素を持たないため、インタープリターはプログラムが無効テストに到達する前に中止します。
幸いなことに、実際にアクセスしようとせずに、変数または配列要素の存在をテストできます。それが特別な演算子isset
が行うことです:
if (isset($_POST["username"]))
{
$user = $_POST["username"];
echo $user;
echo " is your username";
}
else
{
$user = null;
echo "no username supplied";
}
これは、PHPが$_POST["username"]
の値を取得して関数isset()
の引数として渡そうとすると、コードとまったく同じように爆発するようです。ただし、isset()
は実際には関数ではなく、評価段階の前に認識される特別な構文なので、PHPインタープリターは実際に値を取得しようとせずに値の存在をチェックします。
また、実行時エラーが発生すると、欠落している配列要素はマイナーなものと見なされることにも注意してください(E_NOTICE
レベルが割り当てられます)。 error_reporting
レベルを変更して通知を無視する場合、元のコードは実際に書かれたとおりに機能し、配列アクセスを試みるとnull
が返されます。しかし、それは、特に本番コードの場合、悪い習慣と見なされます。
サイドノート:PHPは文字列補間を行うため、echo
ブロック内のif
ステートメントは1つに結合できます。
echo "$user is your username";
つかいます:
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
}
消毒と検証。
あなたのコード仮定何かの存在:
$user = $_POST["username"];
PHPは、$_POST
配列に「ユーザー名」がないことを知らせています。この場合、値にアクセスしようとする前に、値isset()
を確認する方が安全です。
if ( isset( $_POST["username"] ) ) {
/* ... proceed ... */
}
または、||
演算子をハイジャックしてデフォルトを割り当てることもできます。
$user = $_POST["username"] || "visitor" ;
ユーザーの名前がfalsyの値でない限り、この方法はかなり信頼できると考えることができます。 default-assignmentへのより安全なルートは、三項演算子を使用することです。
$user = isset( $_POST["username"] ) ? $_POST["username"] : "visitor" ;
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番目の引数を使用すると、さまざまな filters ( validating 、 sanitizing 、 filtering または その他 )、たとえばFILTER_SANITIZE_SPECIAL_CHARS
、FILTER_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>";
?>
構文は次のとおりです。
mixed
filter_input
(int $ type、string $ variable_name [、int $ filter = FILTER_DEFAULT [、mixed $ options]])(PHP 5> = 5.2.0、PHP 7)
isset()
の代わりに、エラーをミュートする短いものを使用できます。それは@$_POST['field']
です。次に、フィールドが設定されていない場合、ページにエラーが出力されません。
これを試して:
私はこれを$ _POSTリクエストがあるすべての場所で使用します。
$username=isset($_POST['username']) ? $_POST['username'] : "";
これは単なる短いブール値です。issetの場合は$ _POST ['username']に設定され、そうでない場合は空の文字列に設定されます。
使用例:
if($username===""){ echo "Field is blank" } else { echo "Success" };
あなたが言う時:
$user = $_POST["username"];
PHPインタープリターに$user
のキー(またはインデックス)がusername
である$_POST
配列の値を割り当てるように要求しています。存在しない場合、PHPは適合します。
isset($_POST['user'])
を使用して、その変数の存在を確認します。
if (isset($_POST['user'])) {
$user = $_POST["username"];
...
私はこれが古い投稿であることを知っていますが、誰かが助けることができます:
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.";
}
また、POSTがアクティブでないかコンテンツが存在しない場合にデフォルト値を定義できる$default
文字列を追加しました。
echo "<h1>".POST("title", "Stack Overflow")."</h1>";
それで遊びます。
試してみる
if(isset($_POST['username']))
echo $_POST['username']." is your username";
else
echo "no username supplied";