CGI講座 ≫ 基礎知識
基礎知識も必要
CGIを使うためのとりあえずの基礎知識です。
右端の単語をクリックするとそれぞれ詳細説明が出ます。
注)このサイトではPerlとPHP両方の場合をCGIで使う方法について説明します。特に注意書きのない部分は、PerlでもPHPでも両方当てはまることだと考えてください。
必要ない人は次へGo!
CGIの仕組みを理解しよう
CGIについて
ホームページ作成指南のほうで少しふれましたが、CGIとはCommon Gateway Interfaceの略でサーバ側でプログラムを実行する機能のインターフェースを提供します。
インターフェース?
つまり、Webサーバと、CGIプログラムのやりとりをする口だと思って下さい。
一般的にCGI,CGIと言うと、実行するプログラムそのものを言う場合が多いですが、正確にはCGIとはインターフェースです。
ここで普通のWebページを見る時の仕組みを思い出してみましょう。

でしたよね?
ブラウザがWebサーバに「このデータをちょうだい」って言ったら、Webサーバはそのデータをそのままクライアントに送り返しました。
しかし、CGIの場合はそこに一ステッププラスされます。

更にサーバの中の仕組みを見てみると、WebサーバとPerlプログラムのやり取りする口がCGIとなります。

こうなってます。
うおー!ちょっとまった。
まず「プログラム」なんて出てこられるとわからない!という人の為に、CGIで使うことだけメモしておきます。

まず、perlという言語があります。
非常に簡単な言語です。
さて、このperl言語で書いたソースコードをperlスクリプトといいます。
で、このperlスクリプトは単体ではただのファイル・文字の羅列です。
これを思う通りに動かすためには、perlを実行します。
perlスクリプトはperlによって実行されます。

なんだかな~と思うかもしれませんが、perlはこのコードを一行一行実行します。こういう風に実行される言語をインタープリタ型言語といいます。
これと対象にそれ自体が実行プログラムになっていて単独で実行することができるものがあります。
が、とりあえず当サイトではperlのみを扱うので、この話題は置いておきましょう。
正確には、私達が書くのはperlスクリプトと言いますが、
面倒なのでCGIとかプログラムという言葉で片づけてしまう場合があります。
ここでは、Perlで書いたものをPerlスクリプトまたはCGIスクリプト、PerlそのものはただのPerl、PerlスクリプトとPerlをセットでPerlプログラムやCGIプログラムと言いましょう。
この説明はすべてPHPでも当てはまります!
ここでは、PHPで書いたものをPHPスクリプトまたはCGIスクリプト、PHPそのものはただのPHP、PHPスクリプトとPHPをセットでPHPプログラムやCGIプログラムと言いましょう。
実際CGIスクリプトってどんなのよ?(Perl編)
実物を見る
実際にPerl言語で書いたCGIスクリプトを見てみましょう。
#!/usr/local/bin/perl
print <<"EOM";
Content-type: text/html
EOM
open(FILE,"file") || &error("Read Error");
while(<FILE>) { print; }
close(FILE);
1;
こんなものです。
大体は、なにか処理をしてその結果を出力するものがほとんどです。これは処理によってまったく違いますが、必ずやらなければならない事はあります。
一行目にパスを書く
パスについては次に説明しますが、とりあえず一行目には必ず「準備」の項目で用意した『perl のパス』
を、前に”#!”を付けて書きます。
こうしておくと、「このファイルは/usr/local/bin/perlで実行して下さい」という意味になります。
出力のヘッダーを書く
print <<"EOM";
Content-type: text/html
EOM
この部分がそうです。
出力する内容は”print”というコマンドの後に続けて出力する内容を書けばいいのですが、
いきなり”<HTML>・・”などとやっても怒られます。
perlプログラムは、結果を直接クライアントではなく一度Webサーバに返すのですから、
「この出力結果の内容はこういう形式でかかれてますよー」という宣言を最初にしてあげてから内容を出力しなければなりません。
それがこの部分です。
最初に
Content-type: text/html
と書いて、まず出力内容を宣言します。この部分をヘッダーと言います。大抵HTML文書のはずですから、text/htmlとなります。
GIFイメージファイルの場合はimage/gifとなります。
これは内容によって他にも種類があるので、後で説明しましょう。
で、次に必ず改行して、更に次一行開けます。
この改行&一行空けることによって、サーバはヘッダーと内容を判断できるのです。
ですから、その次の行から内容を出力していけばいいのです。

ちなみに、ここまでは下の様に書いても同じです。
print "Content-type: text/html\n\n";
”\n”は改行を表しているので、2回改行・すなわち改行&一行空けた状態と同じことです。
おまけ
スクリプトの最後に、
1;
と書いておくといいでしょう。
1というのは「正常終了」を表すので、このスクリプトは正常に終了します、というー意味で入れておくこと。
実際CGIスクリプトってどんなのよ?(PHP編)
実物を見る
実際にPHP言語で書いたCGIスクリプトを見てみましょう。
<?php
echo "Hello!";
exit;
?>
これだけです。
PHPは「<?php」と「?>」の間に書いた部分がPHPスクリプト、つまりプログラム部分になります。
が!
PHPファイルでは、「<?php」と「?>」に書いた部分がプログラムになるというだけなので、CGIでPHPを使う場合は、他の部分は普通にHTMLを書いてかまいません。
逆に言えば、
<!DOCTYPE html>
<html>
<head>
<title>My HOMEPAGE</title>
<meta charset="utf-8">
</head>
<body>
Hello!
<?php echo "yahoo!"; ?>
</body>
</html>
↓ブラウザでみるとこんなカンジ。
Hello! yahoo!
このようにHTMLの中でプログラムにしたい部分のみ、PHPで書けばいいということになります。
もちろん、プログラム部分で、HTMLを出力するということも可能です。
<?php
echo <<<EOM
<!DOCTYPE html>
<html>
<head>
<title>My HOMEPAGE</title>
<meta charset="utf-8">
</head>
<body>
Hello!
yahoo!
</body>
</html>
EOM;
?>
これは、「echo <<<EOM」から「EOM;」の間を出力するという意味のPHPプログラムです。ブラウザで見ると同じ結果になるはずです。
PerlのCGIプログラムと比べてみると、かなり楽です。
Content-type: text/htmlヘッダーをつけなくていいので、それだけでも楽です。
ヘッダーとは、Perlのほうで説明していますが、「この出力結果の内容はこういう形式でかかれてますよー」という宣言を最初にしてあげることです。
どうしてこんなに違うかというと、PHPの場合は大抵このヘッダー部分を自動的につけてくれる仕組みになっているからです。

PHPをCGIで使う場合、実は2種類の方法でプログラムを実行しています。
●モジュール版
Webサーバの中にある機能でプログラムを実行する。WindowsのApacheなどは通常こちらの設定になる。
●CGI版
Perlと同じで、外部のPHPにプログラムを実行させて、結果をかえす。最近のレンタルサーバだとこちらのほうが多い。

一般的にはモジュール版のほうが速いと言われていますが、多くの人が1つのコンピュータを共有するレンタルサーバではセキュリティ上に問題が出てくる場合あります。
なのでCGI版を採用しているところが多いです。FastCGIといった高速版が多く採用されています。
どちらを使うか選べる場合もあるようですが、特にレンタルサーバで使う場合は、大抵速いほうが基本設定になっているので、あまり深く考えないでいいかも。
色んなサーバでPHP使ってきましたが、普通にPHPのプログラムを書いて拡張子を.phpにしておけば、たいていどこでも問題なく使えるはずです。
どうやってCGIを動かすの?
実行パス
これは主にPerlでの話しです。
「準備」の項目で、『perl のパス』という言葉が出てきました。
これは、すぐ前にやったPerlが置いてある場所です。
大抵、
/usr/local/bin/perl
これがPerlの実体になります。
これは、最初が”/”で始まってますから絶対パス形式(「ホームページ作成」の方を参照)で書かれていて、これを指定すればどこからでもperlが実行できます。
このように、絶対パスを使う場合は問題ありません。
が、絶対パスを使わなくていい方法もあります。
[スタート]->[コントロールパネル]->[システムとメンテナンス]->[システム]
の[システムの詳細設定]から[詳細設定]タブを選択した画面の右下にある「環境変数」をクリックします。
環境変数とは、コンピュータシステム全体で持っている変数です。
で、下の一覧の中に「Path」という変数がないでしょうか?ここを選択して[編集]を押すと、設定画面が出てきます。
PathとPATHは同じです。
[ユーザの環境変数]のほうもPathがありますが、「システム環境変数;ユーザ環境変数」という形になるので、先に設定したシステム環境変数の値の方が優先になります。
一応ユーザ環境変数のほうにしておくのが無難でしょうが、自分は面倒なのでシステム環境変数で。どちらもかまいません。

色んなディレクトリが”;”で繋がれて出てきませんか?
この複数の各ディレクトリのすぐ下にあるプログラムは、コンピュータ内のどこのディレクトリにいても実行できるのです。
例えば、前にperlスクリプトはperlによって実行されると説明しましたが、実際にはコマンドプロンプトから
perl test.pl
(test.plはperlスクリプトの書かれたファイル名)ってな風に実行します。もしもこれを実行する人の環境の「Path」の中に/usr/local/binがあれば、perlは/usr/local/binディレクトリのすぐ下にあるので、絶対パスで指定しなくてもどこからでも実行できます。
システムが、環境変数のPatjの中からperlがあるディレクトリを順に探っていき、/usr/local/bin下にあったので、それを実行したのです。
しかし、「Path」の中に/usr/local/binがなければ
『perlなんてプログラムはどこにあるかわからない!』
とシステムに怒られてしまうわけです。
Pathがなくても絶対パスで指定すればどこからでも実行されます。
CGIスクリプトを実行する命令を出すのはWebサーバです。
Webサーバは、CGIスクリプトの一行目に書かれたパスのプログラムに実行を依頼します。
ですから、一行目に必ずこの形式(#!絶対パス)でパスを書いておけば無事実行してくれるわけです。

これは、PHPをCGI版で実行するときも同じです。PHPスクリプトの一行目に、PHPのバスを書きます。
サーバに置いただけじゃ動かないことがある?
権限
Webサーバに置いてあるファイルには「所有者(オーナー)」と「権限(パーミッション)」というものが存在します。
普通のHTMLファイルを、自分のコンピュータからWebサーバに置く時にはあまり気にする必要はありませんが、CGIを使う場合はこれを設定しなければなりません。
簡単に言うと、
ファイルにはそれぞれ持ち主がいて、そのファイルに読み書きするには決められた権限のある人しかアクセスできませんよー
という設定がしてあるのです。
ffftpでサーバにアクセスすると、右側にはサーバの情報がでます。

これはそのディレクトリ上にある各ファイルの情報が一覧で表示されます。
所有者
で、この一番右にあるのがファイルの持ち主のIDまたは番号で、所有者ということになります。
自分のディレクトリの下にあるファイルは、基本的に全て自分が持ち主になります。
ここにはFTP接続する時のユーザIDかそのIDごとに割り振られた番号が表示されていると思います。
権限
ファイルは、読んだり書いたり実行したりすることができます。
○ read 「読み」
○ write 「書き」
○ exec 「実行」
この3種類ですね。readすることができる場合、read権限がある、といいます。
他の二つも同様。
で、この3種類の権限ですが、自分が持ち主の場合は大抵読み書き実行全てできます。ついでにこの権限も変更することができます。
が、ファイルにアクセスするのは自分だけではないのです。
ファイルにアクセスする人の種類は次の3種類。
● owner 「所有者」
自分のファイルの場合は自分のIDがownerということになる。
● group 「グループメンバ」
自分が所属するグループ。あまり深く考えなくていい。
● other 「それ以外の人」
グループ以外。これもあまり深く考えなくていい。
この3種類の人たちがそれぞれ各ファイルやディレクトリに対する上の3つの権限を個別に持っているのです。
先ほどのFTP画面で各ファイルの権限をを見ると右から2番目の「属性」という部分がそれぞれの権限をあらわします。
最初の3文字がowner権限、次の3文字がgroup権限、最後の3文字がother権限です。

それぞれの3文字分の権限の中で、
・1番目に”r”と書いてあれば、ファイルを読む権限があります。
・2番目に”w”とあれば、書き込む権限があります。
・3番目に”x”とあれば、実行する権限があります。
権限がない場合は”-”となっています。
test2.cgi rwxr-xr-x
これを例にしてみると、ファイルtest2.cgiに対して
・ownerの人は最初の3文字分”rwx”、つまり、読み書き実行すべての権限があります。
・groupの人はその次の3文字分”r-x”、読むことと実行することはできるけどファイルに書き込むことはできません。
・otherの人は最後の3文字分”r-x”、同じく読むことと実行することはできるけどファイルに書き込むことはできません。
という設定になっています。

ちょっとややこしくなっちゃいますが、覚えておいて損はないのでちょっとお付き合い下さい。
権限はそれぞれ”rwx”と”-”で設定されますが、数字で表現する場合もあります。
権限がある場合は”r”・”w”・”x”、権限がない場合はそれぞれの代わりに”-”で表現しますが、 これを、
権限がある場合”r”・”w”・”x”のそれぞれを”1”で、権限がない場合はそれぞれ”0”という数字に置き換えてみます。

こんな感じで。
さて、権限が”rwx”の場合は”111”と置き換えられました。これを2進数表現とみなします。
2進数の111は、10進数で言うと7です。
ちなみに2進数のリストは次の通り。
権限 | 2進数 | 10進数 |
---|---|---|
rwx | ![]() ![]() | 7 |
rw- | ![]() ![]() | 6 |
r-x | ![]() ![]() | 5 |
r-- | ![]() ![]() | 4 |
-wx | ![]() ![]() | 3 |
-w- | ![]() ![]() | 2 |
--x | ![]() ![]() | 1 |
--- | ![]() ![]() | 0 |
そして、その置き換えた各数字をそのまま3つ繋げた形が数字での表現になります。

rwxr-xr-xは755と表現できます。
権限の変更
ffftpのサーバ側を見てみましょう。
ファイルを一つ適当に選びます。
右クリックして「属性変更」を選択すると・・・

こんなのが出てきました。
説明するまでもなく、ここで権限を変更することができます。
権限をもたせる場合はチェックをし、はずす時は再びクリックしてチェックをはずします。
下のボックスから数値でも変更可能です。
OKボタンを押すと設定変更。
一覧に戻ると権限が変更されています。
権限の基本設定
CGIは大抵何かデータファイルを作って変更・削除・追加等という書き込み権限を必要とする作業をします。
例えば掲示板の場合、誰かが掲示板に書き込んだ内容はどこか別のファイルに保存されます。
発言を見る時はそれを読み込んで表示させればOK!

しかし、CGIプログラムを動かすのはowner以外の場合があります。
ので、CGIファイルを動かすためには、CGIファイルにはどのユーザも実行可能な権限をもたせます。
そのCGIプログラムの実行によって作られたデータファイルはCGIプログラムがそのファイルに対して読み書きしなければならないので、自分以外も読み書きする権限を与えておかないと動かない場合があります。
これをそのままあてはめてみますと、
CGIファイルは
rwxr-xr-x = 755
データファイルは
rwxrwxrwx = 777
となっていれば大抵の場合は動きます。
注意しなければならないのは、CGIによってファイルを新しく作成する場合。
このときは、そのファイルが作成されるディレクトリも
rwxrwxrwx = 777
と設定しておく必要があります。設定方法はファイルの場合と同様です。
ただし!権限の設定はサーバによって異なる場合がありますので、自分の所の案内をよく読んでください。
ちなみにXREAでの推奨は
実行ファイル 0700(rwx------) 以上
データファイル 0600(rw-------) 以上
CGI格納ディレクトリ 0705(rwx---r-x) 以上
データ格納ディレクトリ 0700(rwx------) 以上
だそうです。
最近のサーバはCGI関係の権限はほとんどowner権限だけ設定すればどうにかなるようです。
逆にサーバごとに指定された権限以外だと、セキュリティの関係上動かないようになっている場合もあります。
権限設定はなるべく許可の少ないほうがいいので、動かない場合は最低限の設定から、徐々に権限を増やしていきましょう。
「実行」って何?
さっきっからファイルの実行実行と言っていますが、ソレって一体なに?!という人の為に・・・
普通「実行ファイル」と言うと、そのファイル自体が機械語で書かれていて、それだけを「実行」することができます。
ちょうどperlがそうですね。
コマンドプロンプトから
> perl
と打つと動きます。つまり「プログラム」ですね。コマンドプロンプトとその仕組みついては、「Perl入門」で説明しています。
このperlというもの自体(/usr/local/bin/perl、Windowsの場合C:\perl\bin\perl.exe等)をエディタで開こうものなら大変です。
というか普通やりません。おかしくなるのでやらないで下さい。
開いたところで機械語(コンピュータが理解できる言葉)で書かれていて絶対に見てわかるものではありません。
このようなファイルの権限を見てみると、
rwx--x--x /usr/local/bin/perl
となっているはずです。
xがついているので実行することの出来るファイルということがわります。
ですが、問題はCGIスクリプトファイル。
これって自分達で書きますから、当然エディタで見れます。
なのに実行ファイル?
疑問はごもっとも。ですが、前の項目「実行パス」でやったように、CGIスクリプトファイルには一行目にそのスクリプトを実行するプログラム、PerlだったらPerlのパスが書かれています。
サーバはこのCGIファイルが呼ばれた時に、ファイルの権限を見て、自分が実行権限を持っていれば一行目のパスにスクリプトの内容を渡します。
よって、スクリプトファイルの場合は一行目のパスとファイルの中身セットでプログラム
扱いをしているので、実行ファイルでいいのです。