アプリ版:「スタンプのみでお礼する」機能のリリースについて

PHPに関しては知識に乏しい為、質問の仕方も悪いかもしれませんが、ご教授の程お願いします。
 
現在、http://php.s3.to/bbs/bbs2.phpにて配布されているp++BBSをindex.phpにインクルードさせて使用しています。
しかし、クッキーの発行と、リダイレクトが上手くいかず困っています。

// クッキー保存
$cookvalue = implode(",", array($name,$email,$url,$c_pass,$color));
setcookie ("pppbbs", $cookvalue,time()+14*24*3600);

ここと

header("Location: http://$HTTP_HOST$PHP_SELF");

ここでエラーが帰ってきます。
エラーの内容は
Warning: Cannot modify header information - headers already sent by (outputs started at ~~~~)
となっています。
インクルードしているので、もともとのヘッダー情報を書き換えられないということなのでしょうか。
解決方法はありますでしょうか?
別の方法で書き込みボタンが押されたらリロードするということはできますでしょうか
 
ちなみに、書き込み自体は上手くいっているようで、
リロードすると書き込みは表示されます。

A 回答 (2件)

> headers already sent by (outputs started at ~~~~


 惜しい! このatの後ろが重要なんだな。まぁきっとソースの内部の話なのでふせてあるんやろうけど。
 症状としては、そのウォーニングが出るという2つの行の前に、HTTPレスポンスヘッダが出力されるような何かが行われているようだ。なので、先頭からトレースしてみて、そのインクルードファイルがやはりまずいようであるなら、インクルードの前にその2行を持ってこよう。
 重ねて言うが、インクルードが悪いのではなく(原因にはなっているかも知れないけど)、HTTPレスポンスヘッダの出力が開始された後にHTTPレスポンスヘッダの内容を変更しようとした事に問題がある(一旦開始しちゃったらもう変更できない場合がほとんどだからね)。CookieもLocation:(というかheader関数そのもの)もHTTPレスポンスヘッダの一部なのでね。で、実際は変更されなかったのでCookieの書き込みもされてないしリダイレクトもうまくいかなかったという訳だ。
 PHPでHTTPレスポンスヘッダをごにょごにょしたい場合は必ず先頭で行う事が肝要だ。何は無くともHTTPレスポンスヘッダの生成、その後でできる事は後まわし。ね。

この回答への補足

なるほど、そういうことだったのですね。
詳しいご回答ありがとうございます。
という訳で、早速ですがクッキーに関して…
 
$cookvalue = implode(",", array($name,$email,$url,$c_pass,$color));
setcookie ("pppbbs", $cookvalue,time()+14*24*3600);
 
上記部分をindex.phpの一番先頭にもって行きました。
しかしそれだけだと上手くクッキーが保存されませんでした。これは推測ですが、新しくアクセスした際に空の値でも書き込んでいたせいでしょうか?
なので以下の文を追加しました。

if(phpversion()>="4.1.0"){
extract($_GET);
extract($_POST);
extract($_COOKIE);
extract($_SERVER);
} 
if(isset($name)){
$cookvalue = implode(",", array($name,$email,$url,$c_pass,$color));
setcookie ("pppbbs", $cookvalue,time()+14*24*3600);
}
 
これでクッキーは上手くいきました。
結果オーライなのかも知れませんが、変な書き方でしょうか?
 
 
次に、リダイレクトですが、書き込みボタンを押したら~という条件の元の動作なので、場所を変えてみるのは違うと思い、

echo "<META HTTP-EQUIV=\"refresh\" content=\"0;URL=$PHP_SELF?\">";

上記のように記載することで、無理やり移動するようにしました。(これも動く理由がよく分かっていません。)
実際に書き込みがあった後、一瞬白い画面になるのがかっこ悪いですが…
 
今回補足にさせて頂いたのは、動いてはいるものの、自分の中で理解がしっかりできていなかったので。。
もし宜しければ、if(isset($name))を書かない場合は空の値がクッキーに保存されていたのか等、考えられる原因を教えていただけないでしょうか。
わがままをいって申し訳ないですが、ご教授の程よろしくお願いいたします。

補足日時:2006/02/11 04:41
    • good
    • 0

> 結果オーライなのかも知れませんが、変な書き方でしょうか?


 _GETなどを展開するかどうかは好みの問題なので良いと思う。ちなみに私は($_GET['hoge']などと)そのまま使う派。
 ただ、もう少し細かい制御をしてあげた方が良いかも知れないね。メソッドはGETかPOSTか。COOKIEはあるか無いか。これも、どちらが良いでは無く、設計(ページのスクリプト上 何が必要か)の問題。
 また、これをBtoCの業務やインターネットの掲示板などで使う場合は、「悪意のあるHTTPクライアント」を見越して全変数を最初にチェックしてあげる方が良いだろうね。想定しない変数が来てないか。変数内の文字数が多くないか。数字が想定される変数に不正な文字が入っていないか。クロスサイトスクリプティングなどはしっかり封じ込めよう。

> 場所を変えてみるのは違うと思い、
 何度も言うが、場所を変える変えないというのは、アルゴリズム設計(フローチャート)によるものだ。
 フローというのは「最初にあれして、次にこれして」という順番を決めるという事だ。その中で、場所を変える必然性というものが出てくれば変える。例えば変数チェックが一番最後に来たらおかしいよね? 使う前にチェックせんといけんから。PHPというかWebアプリは非常に綺麗なフローチャートで表現できるので、まずプログラムを組み立ててみる(コードではなく、「あれしてこれして」と日本語で流れを書く)と良いだろう。

> if(isset($name))を書かない場合は空の値がクッキーに保存されていたのか等
 書かない場合というのがちょっとよく分かんなかったごめん。これも、ifを書かないのが原因ではなくって、その前でname変数を誰がどう設定するかがあやふやな事に問題がある。

 インクルードも含めてフローを設計し直すのが一番の早道だと思うよ。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!