C++ Webプログラミング:初心者のガイド

こんにちは、Web開発者志望の皆さん!あなたと一緒にC++ Webプログラミングの興味深い旅に出ることができて、とても楽しみです。コンピュータサイエンスを10年以上教えてきた者として、最初は難しく感じるかもしれませんが、忍耐と練習を通じて、素早くダイナミックなウェブアプリケーションを作成できるようになることを保証します。では、始めましょう!

C++ Web Programming

CGIとは?

コーディングを始める前に、CGIが何であるかを理解しましょう。CGIはCommon Gateway Interfaceの略で、ウェブサーバーと動的コンテンツを生成するプログラムの間のトランスレータといえます。CGIを友好な中間者と考えてください。ウェブユーザーからのリクエストを受け取り、それをあなたのC++プログラムに渡し、その結果をユーザーのブラウザに返します。

ウェブブラウジング

CGIの重要性を理解するためには、ウェブブラウジングの仕組みを理解する必要があります。URLをブラウザに入力すると、以下のようになります:

  1. ブラウザがウェブサーバーにリクエストを送信します。
  2. サーバーがこのリクエストを処理します。
  3. 静的なページの場合、サーバーは直接送信します。
  4. 動的なコンテンツの場合、CGIが機能します。
  5. CGIは適切なプログラム(私たちの場合はC++プログラム)を実行します。
  6. プログラムがコンテンツを生成します。
  7. CGIはこのコンテンツをサーバーに送り返します。
  8. サーバーがコンテンツをブラウザに配信します。

CGIアーキテクチャダイアグラム

このプロセスを簡単なダイアグラムで視覚化しましょう:

[ユーザーのブラウザ] <--> [ウェブサーバー] <--> [CGI] <--> [C++プログラム]

このダイアグラムは、あなたのC++プログラムがCGIを通じてウェブとどのように対話するかを示しています。

ウェブサーバーの設定

最初のCGIプログラムを書く前に、ウェブサーバーを設定する必要があります。ほとんどのウェブサーバー(ApacheやNginx)にはCGIモジュールがあります。これらを有効にし、CGIスクリプトのディレクトリを設定する必要があります。例えば、Apacheでは以下のように設定ファイルに追加します:

ScriptAlias /cgi-bin/ /var/www/cgi-bin/
<Directory "/var/www/cgi-bin">
AllowOverride None
Options +ExecCGI
Require all granted
</Directory>

これは、Apacheに /var/www/cgi-bin/ 内のファイルをCGIスクリプトとして扱うよう指示します。

最初のCGIプログラム

では、C++で最初のCGIプログラムを書きましょう。"Hello, World!"の簡単な例から始めます:

#include <iostream>
using namespace std;

int main() {
cout << "Content-type:text/html\r\n\r\n";
cout << "<html>\n";
cout << "<head>\n";
cout << "<title>Hello World - First CGI Program</title>\n";
cout << "</head>\n";
cout << "<body>\n";
cout << "<h2>Hello World! This is my first CGI program</h2>\n";
cout << "</body>\n";
cout << "</html>\n";
return 0;
}

以下に説明します:

  1. iostreamライブラリをインクルードしてインプット/アウトプット操作を行います。
  2. Content-type行は重要です。ブラウザがどのようなコンテンツを期待するかを示します。
  3. その後、静的なHTMLファイルと同じようにHTMLコードを出力します。
  4. \n文字は出力の適切な改行を保証します。

HTTPヘッダー

前の例では、この行がありました:

cout << "Content-type:text/html\r\n\r\n";

これはHTTPヘッダーです。ブラウザが後続のコンテンツをどのように解釈するかを示すために必要です。ヘッダーの種類は多岐にわたりますが、今のところはContent-typeヘッダーに焦点を当てます。

CGI環境変数

CGIは、リクエストに関する情報を提供する環境変数を提供します。以下のプログラムはいくつかのこれらの変数を表示します:

#include <iostream>
#include <cstdlib>
using namespace std;

int main() {
cout << "Content-type:text/html\r\n\r\n";
cout << "<html><body>";
cout << "SERVER_NAME: " << getenv("SERVER_NAME") << "<br>";
cout << "REQUEST_METHOD: " << getenv("REQUEST_METHOD") << "<br>";
cout << "QUERY_STRING: " << getenv("QUERY_STRING") << "<br>";
cout << "</body></html>";
return 0;
}

このプログラムは、ウェブサーバーによって設定された環境変数を getenv() を使って取得します。

C++ CGIライブラリ

CGIプログラミングをより簡単にするために、cgiccなどのライブラリを使用することができます。以下はその使用方法の例です:

#include <iostream>
#include <cgicc/Cgicc.h>
#include <cgicc/HTTPHTMLHeader.h>
#include <cgicc/HTMLClasses.h>

using namespace std;
using namespace cgicc;

int main() {
Cgicc cgi;
cout << HTTPHTMLHeader() << endl;
cout << HTMLDoctype(HTMLDoctype::eStrict) << endl;
cout << html() << head(title("My First CGI Program")) << endl;
cout << body() << h1("Hello, World!") << endl;
cout << body() << html();
return 0;
}

このライブラリは、HTMLを生成し、フォームデータを処理するためのクラスを提供します。

GETとPOSTメソッド

ウェブサーバーにデータを送信するための2つの主要なメソッドがあります:GETとPOST。

GETメソッド

GETメソッドは、データをURLの一部として送信します。以下はその例です:

#include <iostream>
#include <cgicc/Cgicc.h>
#include <cgicc/HTTPHTMLHeader.h>
#include <cgicc/HTMLClasses.h>

using namespace std;
using namespace cgicc;

int main() {
Cgicc cgi;
cout << HTTPHTMLHeader() << endl;
cout << html() << body() << endl;

form_iterator name = cgi.getElement("name");
if(name != cgi.getElements().end()) {
cout << "Hello, " << **name << "!" << endl;
} else {
cout << "No name was submitted." << endl;
}

cout << body() << html();
return 0;
}

このプログラムは、"name"パラメータをURL(例:http://yourserver.com/cgi-bin/program?name=John)から探し、ユーザーに挨拶します。

POSTメソッド

POSTメソッドは、HTTPリクエストのボディにデータを送信します。これはより安全で、より多くのデータを処理できます。以下はその例です:

#include <iostream>
#include <cgicc/Cgicc.h>
#include <cgicc/HTTPHTMLHeader.h>
#include <cgicc/HTMLClasses.h>

using namespace std;
using namespace cgicc;

int main() {
Cgicc cgi;
cout << HTTPHTMLHeader() << endl;
cout << html() << body() << endl;

form_iterator name = cgi.getElement("name");
if(name != cgi.getElements().end()) {
cout << "Hello, " << **name << "!" << endl;
} else {
cout << "No name was submitted." << endl;
}

cout << body() << html();
return 0;
}

このコードはGETの例と似ていますが、POSTリクエスト用に設計されています。

フォームデータの処理

次に、異なるタイプのフォームデータの処理方法を見ていきましょう:

チェックボックスデータ

form_iterator checkbox = cgi.getElement("mycheckbox");
if(checkbox != cgi.getElements().end() && checkbox->getValue() == "on") {
cout << "Checkbox is checked!" << endl;
} else {
cout << "Checkbox is not checked." << endl;
}

ラジオボタンデータ

form_iterator radio = cgi.getElement("myradio");
if(radio != cgi.getElements().end()) {
cout << "Selected option: " << **radio << endl;
} else {
cout << "No option selected." << endl;
}

テキストエリアデータ

form_iterator textarea = cgi.getElement("mytextarea");
if(textarea != cgi.getElements().end()) {
cout << "Text area content: " << **textarea << endl;
} else {
cout << "Text area is empty." << endl;
}

ドロップダウンボックスデータ

form_iterator dropdown = cgi.getElement("mydropdown");
if(dropdown != cgi.getElements().end()) {
cout << "Selected option: " << **dropdown << endl;
} else {
cout << "No option selected." << endl;
}

CGIでクッキーの使用

クッキーは、クライアントのマシンに小さなデータを保存するためのものです。以下は、クッキーを設定および取得する方法です:

クッキーの設定

#include <cgicc/HTTPCookie.h>

// ... (他のインクルードと名前空間宣言)

int main() {
Cgicc cgi;
HTTPCookie cookie("user", "John Doe");
cookie.setMaxAge(3600);  // クッキーは1時間後に失効

cout << HTTPHTMLHeader().setCookie(cookie) << endl;
// ... リストの残りのHTML出力
}

クッキーの取得

const CgiEnvironment& env = cgi.getEnvironment();
const vector<HTTPCookie>& cookies = env.getCookieList();

for(vector<HTTPCookie>::const_iterator i = cookies.begin(); i != cookies.end(); ++i) {
if(i->getName() == "user") {
cout << "Welcome back, " << i->getValue() << "!" << endl;
break;
}
}

ファイルアップロードの例

最後に、ファイルアップロードの処理方法を見ていきましょう:

#include <iostream>
#include <fstream>
#include <cgicc/Cgicc.h>
#include <cgicc/HTTPHTMLHeader.h>
#include <cgicc/HTMLClasses.h>

using namespace std;
using namespace cgicc;

int main() {
Cgicc cgi;
cout << HTTPHTMLHeader() << endl;
cout << html() << body() << endl;

const_file_iterator file = cgi.getFile("userfile");
if(file != cgi.getFiles().end()) {
ofstream out("/path/to/upload/directory/" + file->getFilename());
out << file->getData();
cout << "File " << file->getFilename() << " uploaded successfully." << endl;
} else {
cout << "No file was uploaded." << endl;
}

cout << body() << html();
return 0;
}

このプログラムは、アップロードされたファイルをサーバー上の指定されたディレクトリに保存します。

そして、それで全てです!C++ Webプログラミングの基本的な部分をCGIを使ってカバーしました。練習は成功の鍵です。これらの例を試して、それらを実験して、まもなく複雑なウェブアプリケーションをC++で作成できるようになります。楽しいコーディングを!

Credits: Image by storyset