以下はauth.phpというファイルです
<?php
function loginFunction($username, $status){
ユーザー定義のログインフォーム。字数の関係でコメ欄に(質問とは関係無いと思います)
}
$params = array(
"dsn" => "mysqli://aaa:aaa@localhost/test",
"table" => "authtable",
"usernamecol" => "username",
"passwordcol" => "password"
);
$authobj = new Auth("DB", $params, "loginFunction");
$authobj->start();
if ($authobj->getAuth()){
echo 'ログイン済み';
}else{
echo '未ログイン';
}
?>
これをhtaccessからrequireすると正常に作動します。その場合はログインフォームがサイトコンテンツより上に来るので実際はサイトのコンテンツ内(サイドバーなど)に表示させたいです。
そこでコンテンツ内でrequireすると「Warning: Cannot modify header information - headers already sent by」 エラーがでます。Header出力の前に出力があるからです。
この場合どうすればいいでしょうか。字数の関係でコメ欄に追記します。みなさんよろしくお願いします。
■Q. Warning: Cannot modify header information
http://pukiwiki.sourceforge.jp/?Q%EF%BC%86A%2F%E3%82%A4%E3%83%B3...
これは、関係ないとおもいますが念のため
■PearのAuthを使った認証システムを作りたいのですが
http://q.hatena.ne.jp/1132304878
このあたりも見られてるとは思いますが・・。
コメント欄がOPENされているので、とりあえずここまで
で回答します。あとはコメント欄で・・。
ob_start(); //出力をバッファリングする
ob_end_flush();//出力用バッファを送る
この二つの関数の間なら、header();があってもWarningは出ません。
どこでheader();が出されているかちょっとわからないので、ページの先頭と末尾に入れてみてください。
>これをhtaccessからrequireすると正常に作動します。
htaccessからrequireするというのがチョッとわからないのですが
loginFunction()でprintせずに文字列として格納しておいて、
出したい場所でprintするというのはどうでしょう。
最初にNULLか''で空に初期化しておけば、判定は可能だと思います。
new Auth(...)の中でsession_start()を使っているのでnew Auth()する前に出力していると指摘のWarningが出ます。ob_start()や自前でバッファリングする必要があります。あるいは明示的に先頭の方でsession_start()を呼んでおくというのも手かもしれません(未確認)。PHP4.3.3ではE_NOTICEレベルのエラーが発生するそうです。またその場合二度目のセッションスタートは単に無視されるようなのでうまくいくかもしれません。
http://jp.php.net/manual/ja/function.session-start.php
<?php $auth_lobin_form = ''; function loginFunction($username, $status){ global $auth_lobin_form; $auth_lobin_form = "<form method=\"post\" action=".$_SERVER["PHP_SELF"].">". "<table>". "<tr>". "<td>ユーザー名</td>". "<td><input type=\"text\" name=\"username\"></td>". "</tr>". "<tr>". "<td>パスワード</td>". "<td><input type=\"password\" name=\"password\"></td>". "</tr>". "<tr>". "<td colspan=\"2\"><input type=\"submit\"></td>". "</tr>". "</table>". "</form>"; } $params = array( "dsn" => "mysqli://aaa:aaa@localhost/test", "table" => "authtable", "usernamecol" => "username", "passwordcol" => "password" ); $authobj = new Auth("DB", $params, "loginFunction"); $authobj->start(); if ($authobj->getAuth()){ echo 'ログイン済み'; }else{ echo $auth_lobin_form; echo '未ログイン'; } ?>
コードは未チェックです。
みなさん回答ありがとうございました。
こちらでまとめてコメントさせてもらいます。
ob系の関数は初めて知りました。
そもそもPHPにおけるheaderの概念がイマイチわかっていないので少し勉強の必要があるようです。
今回の不具合に関しては以下の不細工な方法で回避する事ができました。
auth_con1.php(質問文のスクリプト)
auth_con2.php(質問文のスクリプトからloginFunction内を空にする)
ログインページを別個作って、そこから1を呼び出してます。もしログインしていなかったらフォームが現れます。
その他のページでは2を呼び出します。もしログインしていなかったらログインページに自動的に飛ばすようにしました。
不細工な方法ですが、ログインしないとコンテンツ部分が見られないようなサイトにしたかったのでちょうどよかったです。
ただ、ob系関数などを使ってもっとスマートに出来ると思います。勉強して出直してきます。
みなさん回答ありがとうございました。そろそろ締め切らせて頂きます。
http://q.hatena.ne.jp/1132304878
こちらはAuthに関するリンクが詰まっているのでよく参考にしています。
しかし、どのリンク先にも共通して言えることなのですが「実際のサイトに適用されているサンプル」が無いのです。質問文のauth.phpのようなサンプルを作って、それをhtaccessで呼び出すといったところまでしか書いていません。
htaccessで呼び出してしまうと、どうしてもログインフォームがコンテンツ最上部に来てしまいます。具体的には、
PEAR:AUTHのログインフォーム部分がここに来る**
<html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja">
<head>
</head>
<body>
以下コンテンツ
となってしまいます。ヘッダーより前にログインフォームが来てしまうわけです。
これを回避するにはどうすればいいのか、という質問です。質問文だけではわかりづらかったかもしれません。
>コメント欄がOPENされているので、とりあえずここまでで回答します。あとはコメント欄で・・。
もし私のポイントの事を気にしていらっしゃるのであればそれは構いませんので。回答欄に頂ければと思います。そちらの方が後で見に来る方もわかりやすいかと思います。
それではよろしくお願い致します。