2012-02-16 3 views
1

簡単なログインページの作成。ユーザーが一致しないパスワードとパスワードの確認を入力すると、登録フォームをリセットしてメッセージを印刷します。現在、メッセージは印刷されませんが、スクリプトを実行します。これは、エラーが発生したときにSESSION変数を設定し、リロード時に、この変数を示すの仕方によって、私が試したものです:PHPで更新メッセージを表示するには?

registration.php:

<?php 
    session_start(); 
    if (isset($_SESSION['errmsg'])) { 
     print($_SESSION['errmsg']); 
     unset($_SESSION['errmsg']); 
    } 
?> 

<form name="register" action="register.php" method="post"> 
    <label>Username</label><input type="text" name="username" maxlength="20" /> 
    <label>Password</label><input type="password" name="pass" /> 
    <label>Password Again</label><input type="password" name="pass_confirm" /> 
    <input type="submit" value="Register" /> 
</form> 

register.php:

<?php 
function create_salt() { 
    $string = md5(uniqid(rand(), true)); 
    return substr($string, 0, 3); 
} 

session_start(); 
$username = $_POST['username']; 
$pass = $_POST['pass']; 
$pass_confirm = $_POST['pass_confirm']; 

if ($pass != $pass_confirm) { 
    $_SESSION['errmsg'] = "Passwords do not match."; 
    header('Location: registration.php'); 
} 

if (strlen($username) > 20) { 
    header('Location: registration.php'); 
} 

$hash = hash('sha256', $pass); 
$salt = create_salt(); 
$hash = hash('sha256', $salt . $hash); 

$conn = mysql_connect('localhost', 'test4', 'test4'); 
mysql_select_db('test4', $conn); 

$username = mysql_real_escape_string($username); 

$query = "INSERT INTO users (username, password, salt) VALUES ('$username', '$hash', '$salt');"; 

mysql_query($query); 
mysql_close(); 
header('Location: index.php'); 
?> 

重要な部分は、if ($pass != $pass_confirm) { ...です。現在のところ、パスワードが一致しない場合、この条件は満たされますが、header(Location: registration.php)でリロードするのではなく、スクリプトを実行します。私は、データが送信された後にheader()を呼び出すことができないことを認識しています。これはおそらく問題を引き起こしています。

もしそうなら、これをPHPで行うより良い方法がありますか、私は代替案を検討していますか?

+0

あなたは 'register.php'に' 'タグがあり、それらのタグの外側には他のデータがない場合、あなたのコードはうまくいくはずです。 PHPでエラー出力が有効になっていますか?このスクリプトはエラーを生成しますか? – talereader

+0

申し訳ありませんが、私は上記のものを拒否しました。今編集されました。 'register.php'にphpタグがあります。 – persepolis

答えて

2

die();またはexit;が問題を解決します。

header('Location: registration.php'); 
die(); 
+0

なぜこれが「健全な」解決策であるのか分かりません。ありがとう! – persepolis

+1

はい、それは健康的な解決策です。また、ヘッダー(位置)の振る舞いはスクリプトを終了させないことが期待されます。単にヘッダーに書き込むだけです。スクリプトは、停止するよう指示するまで続きます。スクリプトが終了すると、ヘッダーがブラウザに送信され、リダイレクトするように指示されます。 – talereader

2

一部のデータを出力し、リダイレクトする可能性がある場合は、出力バッファリングを使用できます。これにより、生成した出力がユーザーに送信されるのではなく、バッファーに置かれます。リダイレクトする必要がある場合は、まだデータが送信されていないため動作します。リダイレクトしないと、バッファに入っているものを使い、スクリプトが完了したら出力します。

PHPの出力バッファリングについてずっとよりリーンするために、このPHPマニュアルページを参照してください: http://www.php.net/manual/en/intro.outcontrol.php

また、エラーがあれば、あなたが二回header()を呼んでいることに注意してください - 「場所を有する第二のヘッダー呼び出しを'型は最初のものを上書きしてindex.phpに送ります。

上記の@ talereaderの答えを参照してください - キーはあなたがエラー状態にあることを確認し、ヘッダーを呼び出してからすぐにスクリプトを終了することです。

+0

さらに説明できますか?セッション変数コードを取り出しても、2つのパスワードが一致しないと、 'header( 'Location:registration.php');が呼び出されず、スクリプトが続行されるので混乱します。なぜ、 'registration.php'に戻ってほしくないのですか? – persepolis

+1

@talereaderはそれを持っています - あなたのスクリプトはregistration.phpにリダイレクトするためのヘッダを設定していましたが、スクリプトは最初のリダイレクトを上書きしていたindex.phpにもリダイレクトしていました。 2番目のパラメータをfalseに指定しない限り、 'header()'呼び出しはデフォルトで同様の 'header()'呼び出しを置き換えます。より大きなアイデアは、あなたのスクリプトを終了し、 'header()'で別のアドレスで別のものをキックオフしたい場合、 'die()'のようなもので現在のスクリプトを終了する必要があるということです。それ以外の場合、最初のスクリプトは実行を停止することを知らせません。 –

1

何かが失敗した場合は、すべてのチェックを行い、フラグを設定してください。すなわち$failed = true;の場合、実際に処理する前にif (!$failed) { //process }を実行してください。

+0

したがって、header()はスクリプトの最後でのみ呼び出すことができますか? – persepolis

+0

いいえ、どこでもヘッダを呼び出すことができますが、あるヘッダを別のヘッダに上書きすることができます。また、ページ出力が既に開始されている場合は、ヘッダーの出力に問題が生じる可能性があります。 –

関連する問題