こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

ログイン後・・・

こんにちは。サイトを作っているperl初心者です。

TOPページからログインして、メイン画面を表示させたいのですが、つまづいてます。

使用している言語はperl5、データベースはmysql4です。
今「TOPページのcgiのログインフォームからデータを取り、mysqlに接続してデータベースのデータ(id、パスワード)を検索し、
一致するデータがあれば仮にテーブルにして表示させる」ところまではできています。
このテーブルを表示せずに、メイン画面を表示させるためにはどうすればよいのでしょうか?

くだらない質問でしょうが、よろしければ回答を。
よろしくお願いします。

投稿日時 - 2005-12-19 16:00:21

QNo.1848153

すぐに回答ほしいです

質問者が選んだベストアンサー

> すみません!ちょっと伺いたいんですけど。
> phpのheaderっていう関数と同じの機能のものって、perlにもありますか?

ないとは思いますが、単にANo.12で挙げたとおり、出力の順番を考慮したうえで
printすればいいと思うのですが、それだとまずいのですか?

Perlでも何でもそうですが、実際のHTML送出前にヘッダをprintしてあげれば
それで解決すると思うのですが…。
今回の件では、認証の結果如何で出力しなければならないHTTPヘッダがあるのにも関わらず、
認証判断前にHTTPヘッダもHTMLも出力してしまっているのが問題なわけですから、
判断後に状況に合わせた出力方法に変更するだけで対応可能です。

Googleで「CGI HTTPヘッダ」で検索した中で、そこそこ解りやすそうだったサイトを提示しておきます。

参考URL:http://www.rfs.jp/sb/perl/03/03.html,http://hp.vector.co.jp/authors/VA014833/CGI/header.html

投稿日時 - 2005-12-22 14:49:01

お礼

回答ありがとうございます。
なんとかできました!(下手なりにですが・・・)

locationを記述してもできなかったのでなぜだろうとなやんでいましたが、
どうやらエラーメッセージのところでひっかかっていたようです。
そりゃそうですよね、上部のヘッダ情報は消してるのに<font>って書いて
しまっているのだからf(..)

ふぅ~本当に助かりました。ありがとうございました。

投稿日時 - 2005-12-23 00:12:04

このQ&Aは役に立ちましたか?

8人が「このQ&Aが役に立った」と投票しています

回答(14)

ANo.14

いったい何がやりたいのか・・・???
PHPがわかるなら、PHPで作ればいいものを・・・。

>> phpのheaderっていう関数と同じの機能のものって、
>>perlにもありますか?
ありません。

単純にレスポンスヘッダ(と空行)を出力してから、実際のHTMLを出せばいいだけなのに・・・。
CGIで出力するべきレスポンスヘッダは、
print "Content-Type: text/html", "\n\n";
たったこれだけ。
足りない分はサーバーが補填して出力してくれる(別に自力で出しても構わないが・・・)。

だんだん本題からズレてしまっているようだ・・・。

投稿日時 - 2005-12-22 14:58:21

お礼

サンプルソースが他になかったもので、このサンプルソースが使っている
perl言語を学ぼうとしているだけです。
ちなみにphpはもっとわかりません。
回答ありがとうございます。

投稿日時 - 2005-12-22 23:36:41

ANo.12

Perlやmysqlの認証というより、CGIからHTMLを出力する時の流儀について、もう少し理解されないとちょっと難しいかもしれませんね…。

> print <<header;
> Content-Type:text/html
>
> <html>
> <head>
> <meta http-equiv="Content-Type" content="text/html";charset=Shift_JIS">
> <title>★○○○★</title>
> </head>
> <body bgdolor="#ffffff" text="#000000">
> header

ヒアドキュメントで共通するHTML部分まで既に出力しちゃっているため、後からLocationヘッダを出力しても、
単なるHTML内の内容として出力されてしまっているために「表示されるだけ」になっています。
上記では、ちょうと「Content-type: text/html」の部分がHTTPヘッダになってますから、
ここに追加する形(じゃないな、リダイレクトだけならContent-typeは要らないか)でLocationが
入らないと意味がないです。
従って、認証の可否分岐前にここまで出力しちゃうのがダメだと思います。

以下、構造だけ。(概念だけとらえて、実際のコーディングはやってみてください)

if (データが与えられてない) {
# 上記の出力+エラーメッセージ
} elsif (認証が通らない) {
# 上記の出力+エラーメッセージ
} else {
# 通ったのでリダイレクト
print "Location: index.cgi\n\n";
}

…という感じでしょうか。要は成功するのかしないのか判別できるまではHTTPヘッダを出力しないことがポイントです。

CGIを使用する際にHTTPヘッダをどうやって出力するのか、という部分について勉強してみてください。
これはCGIにPerl以外の言語を使っていても同じ知識ですので。
(恐らくHTTPヘッダとHTMLの出力についての切り分けができていない気がします)

投稿日時 - 2005-12-21 18:46:48

補足

すみません!ちょっと伺いたいんですけど。
phpのheaderっていう関数と同じの機能のものって、perlにもありますか?

投稿日時 - 2005-12-22 12:18:20

お礼

回答ありがとうございます。

そうですね、やっぱりまだ理解してない部分が多いのだと思います。

ネットなどでhttpについてもう少し調べてみます。

投稿日時 - 2005-12-21 20:05:17

ANo.11

う~ん・・・。
こういう言い方はなんだが、
もう少しPerlを理解してからでないと難しそう・・・。
index.cgi
の中身は、何が書いてあるの???

投稿日時 - 2005-12-21 18:22:01

お礼

いやぁ実は卒論でオークションサイト作っていて、しかも取り組み
を始めたのがとても遅かったので、もう勉強する時間ないんですよね~(^^;)
それで、ここで質問したってわけなんですけど、やっぱ理解してない部分が
多すぎてなかなか難しいですね。。

index.cgiには出品一覧を作成してするためのcgiプログラムが、480行にまたがって
ずらずらと記述されております。

回答ありがとうございます。

投稿日時 - 2005-12-21 19:44:51

ANo.10

> 一応このように記述したのですが・・・
> →print "Location:<A href=\"./index.cgi>\n\n";
> このまま文が表示されるだけなんです。

HTMLとして出力するのではなく、HTTPヘッダとして出力する必要があります。
上記のprintをする前に既にヘッダ部分の出力をしていませんか?
恐らくContent-type等のヘッダ情報を出力するルーチンが認証プログラムにあるはずですので、そこの改造が必要です。

また、あくまでHTTPヘッダですから、HTMLでの記述ではなく、

print "Location: /index.cgi\n\n";

といった表現になります。

なお、HTTPヘッダの出力セクションにおいて空行を用意してしまう(print "ヘッダ\n\n";と\nで2回改行する等)と、
その時点でヘッダは終了と認識されます。ご注意ください。

mysqlの認証というより、これはCGIでの出力やHTTPの仕組み&流儀にかかってくる部分ですので、
まずはCGIの作り方について詳しく調べられるとよいと思います。がんばってください。

投稿日時 - 2005-12-21 17:26:17

補足

回答ありがとうございます。
実はheader文省略としたところに以下のような記述がしてあります。

print <<header;
Content-Type:text/html

<html>
<head>
<meta http-equiv="Content-Type" content="text/html";charset=Shift_JIS">
<title>★○○○★</title>
</head>
<body bgdolor="#ffffff" text="#000000">
header

この部分がおかしいのでしょうか?

投稿日時 - 2005-12-21 17:51:47

ANo.9

index.cgi
に飛ばしたいのなら、
print "Location: /index.cgi"."\n\n";
でしょ???

投稿日時 - 2005-12-21 17:20:41

お礼

回答ありがとうございます。

指摘されたように書き直してみましたが、できないみたいです(T_T)
うぅ・・・

投稿日時 - 2005-12-21 17:25:29

ANo.8

なんか少し判った気がします。
認証を通過した後、別のプログラムを呼びたいということなんですね。

であれば、直接的にプログラムを呼ぶのではなく、taka451213さんの言われるようにLocationヘッダでリダイレクトをすればいいでしょう。
あるいは究極的には認証構造自体をメインのプログラムに組み込んでしまい、2段階でやらずに1本のプログラムでできるようにしてしまうか、ですね。

CGIの場合、外部のプログラムに制御自体を丸ごと渡すというのは色々やばそうな気がしますので、統合するか、分ける必要があるならリダイレクトして別のファイルを読み直させる方法しかないでしょう。
(LocationにはCGIを指定しても大丈夫です)

ただし、リダイレクトをした場合はANo.4でも挙げましたが、飛び先のURLが判ってしまえば認証は完全に不要になってしまいます。
もしそれでも認証したかどうかを確認するならば、飛び先側のプログラムで認証済みか否かを知るための仕組が別途必要です。
それはCookieなのかPOSTやGETによるものなのかはサイトの構築方法次第となるので、ここでは言いようがありませんが…。

投稿日時 - 2005-12-20 19:53:47

補足

回答ありがとうございます。そうなんです、別プログラムを呼びたいんです。

taka451213さんのおっしゃったようにprint文でやってみましたが、
文がまちがっているのかできませんでした(>_<;)
一応このように記述したのですが・・・
→print "Location:<A href=\"./index.cgi>\n\n";
このまま文が表示されるだけなんです。

初心者で何をいじっていいのやら全くわかってなくてすみません。
何が間違ってますかねぇ??

投稿日時 - 2005-12-21 16:57:58

ANo.7

だったら、すでにあるメイン画面の
print
って書いてあるあたりをゴッソリコピーして、
print "Location: xxxx.html\n\n";
の部分に書けばいいのでは?

投稿日時 - 2005-12-20 19:40:25

お礼

回答ありがとうございます。

なんかmainページには複雑なプログラムが書かれていて、
ご指摘のようにはいかないようです。

すみません。。。

投稿日時 - 2005-12-21 16:50:13

ANo.6

>>※元々テーブルで検索結果を表示していました。
>>この部分が知りたいんですが・・・
ここにメイン画面を書けばいいのでは???
タグを書くのが面倒なら、メイン画面のHTMLを作っておいて、
print "Location: xxxx.html\n\n";
とかなんとか、書いてしまえばいい・・・。
(^^ゞ

投稿日時 - 2005-12-20 18:38:36

補足

これサンプルソース使っていて、main画面はすでにあるのですが、それもcgiで書かれているんですよ~(^^;)
print "Location: xxxx.html\n\n";のhtmlの部分をcgiに直してもできますかね?

投稿日時 - 2005-12-20 19:11:44

お礼

すみません、一言お礼が言いたくて古い回答のお礼フォームに
書いてます。

おかげさまで解決いたしました。ご迷惑おかけしました。
認証時のエラーメッセージが原因だったので、サブルーチンで飛ばしました。

助かりました。ありがとうございました。

投稿日時 - 2005-12-23 00:15:34

ANo.5

MySQL接続ページって何???
それもひとつのHTMLですか?
それは接続と認証のルーチンを持っているわけではなく、単にDBの取得結果を表示しているだけのHTMLですよね?
なので、それがいらないです・・・。
実際にDBにconnectして、TOP画面で入力されたパラメーターでDB検索して、IDとパスワードが存在するかどうかをチェックしているのはCGIでしょ?
今は取得するまでがプログラムで、認証結果いかんにかかわらず結果表示画面のHTMLに行ってるんですよね?
そこに、あった時となかった時の振り分けを書いて、それぞれ違うページ(HTML)に行くように変更すればいいのでは?
という事が言いたかったのですが・・・。
(^^ゞ

投稿日時 - 2005-12-20 09:14:00

補足

どうも私は言葉で説明する事がうまくないようです。
すみません(^^;)以下にMysql接続ページなるものの内容を載せます。
間違いがあればまたご指摘よろしくお願いします。

#!/usr/local/bin/perl

use CGI qw(:standard);
use DBI;

$dbn = "DBI:mysql:sample1:localhost";
$user = "*****";
$pw = "*****";

$i_id = param("s_id"); #パラメータ取得
$i_pw = param("s_pw"); #   〃

print ※header情報省略

$dbh = DBI->connect($dbn,$user,$pw); #データベースハンドル生成
$dbh->do("SET NAMES sjis");

$sth = $dbh->prepare("select * from list where id =" .$i_id);
#ステートメントハンドルの生成

if($sth->execute() == 0) {
print "<font color=blue>idがまちがっていませんか?<br>データがありません!</font>";
#実行後、結果が0ならエラー表示
} else {
@row = $sth->fetchrow_array(); #そうじゃなければ、データを取り出して格納
if ($row[1] ne $i_pw) {
print "<font color=red>pwがまちがっていませんか?<br>データがありません!</font>";
#パスワードが合致しなければエラー表示
} else {
※元々テーブルで検索結果を表示していました。この部分が知りたいんですが・・・
}
}

$sth->finish();
$dbh->disconnect();

print ※footer情報省略
exit;

投稿日時 - 2005-12-20 17:40:51

ANo.4

他の方も指摘していますが、テーブルを表示するルーチンではなく、そのまま認証OKになったら
メインのコンテンツを出力するように仕向ければいいと思います。

ANo.1の補足質問で書かれていることから、mysql認証プログラムが通った後、
メインコンテンツ表示プログラムに制御を移したい、ということだと思うのですが
合っていますでしょうか。

とすると、mysql認証プログラムとメインコンテンツ表示プログラムは別のものであるわけですから、
いきなりmysql認証プログラム上で別のファイルのサブルーチンを呼んでも呼べないと思います。

もしやるのであれば、mysql認証プログラムで認証OKになった後、
<META http-equiv="Refresh" content="0; URL=*メインページURL*">などと出力すれば解決できる気がします。

が、これだとメインページのURLが判ってしまうとmysql認証を通らなくてもいけるようになってしまいますから、
mysql認証OKの段階でCookieを食わせるとかで認証完了済みかどうかのステータスを保持させ、
以後のコンテンツでこのCookieを確認して未認証状態なら強制的に認証をさせ構造を作る必要が出てくるものと思います。

どのようなサイト構成をお考えかが判らないので何とも言えないのですが、
単にメインページの表示だけ認証が必要なのであれば、mysql認証プログラム内にメインコンテンツを
出力するようなルーチンを書いてしまえば楽になるように思います。


やられようとしていることに合致しているかどうかちょっと自信ないのですが…参考になれば幸いです。

投稿日時 - 2005-12-19 22:16:01

お礼

回答ありがとうございます。
>mysql認証プログラム内にメインコンテンツを
>出力するようなルーチンを書いてしまえば楽になるように思いま>す。
そうなんですよ、それがやりたいんですができないんですよね~これが(^^;)
Cookieの使い方も良くわからないので調べてみます。ありがとうございます。

投稿日時 - 2005-12-20 17:23:52

ANo.3

TOPページ(入力)
 ↓
submit
 ↓
CGIプログラム(パラメーター受け取り)
 ↓
DB接続&認証処理
 ↓OK  ↓NG ←ここまではプログラム
メイン  TOP

では???
(^^ゞ

投稿日時 - 2005-12-19 19:16:12

補足

今私のプログラムでは、
TOPページ(入力):TOPぺーじ
 ↓
submit     :TOPページ
 ↓
CGIプログラム(パラメーター受け取り):Mysql接続ページ
 ↓
DB接続&認証処理          :Mysql接続ページ
 ↓OK  ↓NG ←ここまではプログラム
 ↓  エラー表示         :Mysql接続ページ
メイン(ここができていないんですけど・・・)
となっています。
ごめんなさい、意味がわからないでしょうか?(^^;)

投稿日時 - 2005-12-19 19:25:05

ANo.2

???
その
>>Mysql接続ページ
って必要?
処理が終われば「mainページ」でいいのでは?
(^^ゞ

投稿日時 - 2005-12-19 18:47:35

補足

回答ありがとうございます。

うーんと、初心者なのでよくわからなくて本を見ながら、TOPページとは別にページ作ったんですけど・・・
TOPページのフォームからactionでとばしてます。
つまりMysqlに接続するプログラムはTOPには記述していないってことなんですが・・・
これって、TOPかmainのどっちかに、このMysql接続ページの内容を組み込めばいいってことでしょうか?

よくわかってなくてすみません(>_<;)

投稿日時 - 2005-12-19 18:58:31

ANo.1

え?
そこまでできているんなら、
その仮のテーブルをメイン画面に差し替えれば言いだけではないのですか?

もし何かに躓いているときは具体的な質問をしましょう。

投稿日時 - 2005-12-19 17:48:57

補足

回答ありがとうございます。

失礼しました。えっとですね、topページ、mysql接続ページ、mainページという風に
それぞれ別のファイル(プログラム)になっているんですね。で、TOPページ→Mysql接続ページ→mainページって
流れでジャンプしたいんですけど、Mysql接続ページ→mainページの部分ができていない状態なんです。
今はMysql接続ページ内で、HTMLでテーブル表示させているんですけど、ここをどのように書き換えればいいのでしょうか?
とりあえず、Mainページの本文がサブルーチンの形で書かれているので、
&○○○;と記述してみましたがだめでした。

具体的になっていますでしょうか?

投稿日時 - 2005-12-19 18:16:40

お礼

一番最初の回答ありがとうございました。

投稿日時 - 2005-12-22 23:38:24

あなたにオススメの質問