コンテンツにスキップ

PHP

なぜ生まれた?
動的なページには別の CGI プログラムが要り、アクセスのたびに Perl を起動する負荷も重かった。
何を解決した?
HTML の中に短い処理を埋め込み、C で書いた1つのプログラムやサーバーのモジュールで実行した。
何を残した?
フォームの値を自動で変数にする手軽さが、既定の変更から削除まで約10年の課題になった。
登場
作者
Rasmus Lerdorf
状態
現役

1994年、Rasmus Lerdorf は、ネットに載せた自分の履歴書のページを誰が読んでいるのかを知りたいと考えていました。 本人は PHP/FI 2.0 のマニュアルの「Brief History」に、仕事の契約の合間に “I needed a quick tool to get an idea of who was reading my online resume”(オンラインの履歴書を誰が読んでいるのかをざっと知るための、手早い道具が欲しかった)と書いています。

当時、ページを返すたびに何かを計算させるには、CGI という仕組みでサーバーに別のプログラムを起動させ、そのプログラムに HTML を出力させるのがふつうでした。 アクセスが1回あるたびにプログラムが1回起動するので、Perl で書けば、そのたびに Perl の処理系も起動します。 Lerdorf も最初の道具を Perl の小さな CGI のラッパーとして書きました。

困ったのは、その起動の重さでした。本人は次のように書いています。

“The web server where I had my resume was extremely overloaded and had constant problems forking processes.” (履歴書を置いていた Web サーバーはひどく過負荷で、プロセスの fork にいつも問題を抱えていた)

そこで Perl のラッパーを C で書き直しました。理由は “to get rid of the considerable overhead of having to fork Perl each time my resume was accessed”(履歴書が読まれるたびに Perl を fork する、かなりの負荷をなくすため)です。 PHP は、言語を作ろうとして始まったものではなく、混み合った1台のサーバーの上で、自分のページのアクセスを数えるための道具でした。

同じサーバーを使うほかの人がこの道具に気づいて使いはじめ、機能の要望が増えていきました(2.0 マニュアル)。

1995年6月8日、Lerdorf は Usenet のニュースグループ comp.infosystems.www.authoring.cgi で Personal Home Page Tools(PHP Tools)1.0 を発表しました。 中身は “a set of small tight cgi binaries written in C”(C で書いた、小さく引き締まった CGI バイナリの集まり)で、アクセスログ、アクセスカウンタ、参照元 URL の記録、フォームの表示などが並んでいました。 root の権限も “Perl or Tcl or any other script interpreter”(Perl や Tcl などのインタプリタ)も要らず、自分の CGI プログラムを動かせれば使える、とも書いています。

この記事では、作者の変更履歴が「最初の正式な 1.0 リリース」とするこの投稿を登場としています。php.net の History of PHP は、作られた年を1994年としています。

PHP は最初からプログラミング言語として作られたのか

Section titled “PHP は最初からプログラミング言語として作られたのか”

違います。本人は最初の道具について “It was never intended to go beyond my own private use.”(自分で使う以上のものにするつもりはなかった)と書いています。

同じころ Lerdorf は、SQL のクエリを Web ページに埋め込む CGI ラッパーも作り、FI(Form Interpreter)と名付けました。 作者の変更履歴では、1995年10月9日の 1.91 で FI と Tools を1つのバイナリにまとめ、10月17日の 1.92 を「PHP/FI の最初の公開リリース」としています。 一方、php.net の History は、1995年10月の書き直しを Personal Home Page Construction Kit と呼び、PHP/FI の名は1996年4月に付いたと書いています。名前の時期は、この2つの資料で食い違っています。

php.net は、1995年秋の FI を、Perl に似た変数を持つものの “a CGI tool --- but still not quite as a language”(CGI の道具ではあっても、まだ言語とは言いにくい)と評価しています。 変わったのは1996年です。4月16日の告知で、Lerdorf は “PHP/FI is a server-side HTML embedded scripting language.”(PHP/FI は HTML に埋め込むサーバーサイドのスクリプト言語です)と書きました。 データベース、cookie、ユーザー定義関数に対応したこの世代を、php.net は道具の集まりから言語へ進化しはじめたものと位置づけています。

1997年、テルアビブの Andi Gutmans と Zeev Suraski が、大学のプロジェクトには PHP/FI 2.0 では足りないとしてパーサを書き直しはじめます。Lerdorf と3人で開発を進め、1998年6月6日に PHP 3.0 が公開されました。 名前は、個人用という含みを消すため “PHP: Hypertext Preprocessor”(再帰的な頭字語)に改められています(php.net)。

なぜ HTML の中にコードを書く形だったのか

Section titled “なぜ HTML の中にコードを書く形だったのか”

PHP Tools の機能には、ページに最終アクセスの情報を出すことや、サーバーが対応していなくても SSI(サーバー側でページに別のファイルを差し込む仕組み)と同じことをすることがありました。 作者の変更履歴は、1995年9月の 1.90 で改善したものを “tag replacement language”(タグを置き換える言語)と呼んでいます。 出発点は「ページを出力するプログラム」ではなく、「ふつうの HTML のページに、置き換える印を書いておく」形でした。 FI のころは <!--sql ... --> のように HTML のコメントの中に書き、PHP/FI 2.0 で <? ... > という書き方になります。

作者は2.0 のマニュアルで “Many people find the embedded nature much easier to deal with than trying to create separate HTML and CGI files.”(HTML と CGI を別々のファイルで作るより、埋め込む形のほうがずっと扱いやすいと感じる人が多い)と書いています。 後からの評価では、1998年のドイツの雑誌 c’t が、この方式を「server parsed HTML」と呼び、SSI をその早い例として挙げています。

ページの下に「このページは何回読まれたか」を出す処理で比べます。 Perl の側はこの記事のための作例で、当時の実際のコードではありません。Perl 5 で動く書き方にしています。

counter.cgi(作例)
#!/usr/bin/perl
# アクセスのたびに起動し、数を1増やして、ページ全体を出力する
$file = "/home/user/counter.dat";
open(COUNT, "+<$file") || die "cannot open $file: $!";
flock(COUNT, 2);
$count = <COUNT>;
$count++;
seek(COUNT, 0, 0);
print COUNT "$count\n";
close(COUNT);
print "Content-type: text/html\n\n";
print "<HTML><HEAD><TITLE>Resume</TITLE></HEAD><BODY>\n";
print "<H1>Resume</H1>\n";
print "<P>(履歴書の本文も、ここで print する)</P>\n";
print "<P>This page has been accessed $count times.</P>\n";
print "</BODY></HTML>\n";

PHP/FI 2.0 では、アクセスログを有効にしてビルドすると、ページごとの累計を返す getTotal() と、その日の数を返す getToday() が使えます(2.0 マニュアル)。

resume.html(PHP/FI 2.0)
<HTML><HEAD><TITLE>Resume</TITLE></HEAD><BODY>
<H1>Resume</H1>
<P>(履歴書の本文は、ふつうの HTML のまま)</P>
<?;
$total = getTotal();
$today = getToday();
echo "This page has been accessed $total times ($today today).";
>
</BODY></HTML>

Perl の側では、ページそのものがプログラムの中にあり、見た目を少し変えるだけでも print の行を書き直します。 PHP/FI の側では、ページは HTML のままで、コードは数を出す数行だけです。記録は PHP/FI 自身が取ります。

なぜ Perl の CGI ではなく PHP が広まったのか

Section titled “なぜ Perl の CGI ではなく PHP が広まったのか”

作者が挙げた理由は、Perl という言語の良し悪しではありませんでした。 2.0 のマニュアルは、小さな Perl の CGI プログラムをたくさん書かずに済むこと、Perl を何度も fork する負荷がなくなること、データベースを使うページが簡単に作れること、HTML と CGI を分けずに済むことを挙げています。

次の一歩は、Web サーバーの中で動くことでした。変更履歴では、1996年4月23日の 1.99l で Apache 1.1 のモジュールとして動くようになります。 2.0 のマニュアルはその利点を “there is no CGI involved”(CGI を通らない)と説明し、HTML の中のコードを Apache のプロセスがそのまま実行する、と書いています。 同じマニュアルには、すべての利用者に CGI を使わせる ISP の悩みに向けた Safe Mode の説明もあります。

データベースへの対応も早く、1995年10月には mSQL の関数がそろい、1996年4月に Postgres95、1997年1月に MySQL に対応しました(変更履歴)。 PHP 3.0 について php.net は、言語を拡張しやすかったので何十人もの開発者がモジュールを寄せた、と書き、これが成功の鍵だったと評価しています。

c’t の1998年12月号の Michael Kunze の記事は「LAMP」という見出しで、Linux・Apache・MySQL・PHP の組み合わせを、費用のかからない Web 公開の仕組みとして紹介しました。 PHP については “It is normally an additional module and is simply hooked up to the Apache web server.”(ふつうは追加のモジュールで、Apache につなぐだけ)と書いています。

広がりを示す数字は、PHP の側が書いたものです。

時点数字出典
1998年5月約6万のドメインが “PHP” を含むヘッダを返した(当時のドメインの約1%)php.net(Netcraft の調査として)
1998年6月(PHP 3.0 の公開)7万を超えるサイト・ドメインPHP 3.0 の公開の告知、php.net
PHP 3.0 のピークインターネットの Web サーバーの約10%php.net

手軽さのための仕組みと、その後

Section titled “手軽さのための仕組みと、その後”

PHP/FI 2.0 では、フォームの入力欄ごとに同じ名前の変数が自動で作られました。マニュアルの例では、name と age の欄があるフォームを受けるページに <?echo "Hi $name, you are $age years old!<p>"> と書くだけで値を出せます。 同じマニュアルは、この仕組みの弱点にもすでに触れています。POST のフォームから来るはずの変数でも、URL に ?data=something と付ければ GET で値を入れられてしまうので、SecureVar() で GET からの設定を止める、という説明です。

1996年1月の 1.99a で入った magic quotes は、GET や POST の値の引用符を自動でエスケープし、フォームの値をそのまま SQL に渡しやすくするものでした(変更履歴と 2.0 マニュアル)。

仕組み何が楽だったかどう改められたか
外部の変数の自動登録(register globals)フォームや cookie の値をすぐ変数として使える4.2.0(2002年4月)で既定 Off、5.3 で非推奨、5.4.0(2012年3月)で削除
magic quotesフォームの値を SQL に渡すときの引用符を自分で処理しなくてよい5.3 で非推奨、5.4.0 で削除
safe mode多くの利用者が同じサーバーで PHP を使う ISP でも、ファイルの持ち主ごとに操作を制限できる5.3 で非推奨、5.4.0 で削除

4.2.0 の告知は、外部からの変数を既定で登録しなくなったことを「いちばん大きな変更」とし、4.1.0 で入った superglobal の配列を使うよう案内しました。参考資料には PHP の安全なプログラミングについての記事を挙げています。 最初は手軽さのための既定だった仕組みを、既存のサイトとの互換を保ちながら外すのに、既定を変えてから削除まで約10年かかりました。

大きなアプリケーションを動かすために

Section titled “大きなアプリケーションを動かすために”

php.net は、PHP 3.0 は複雑なアプリケーションを効率よく動かすようには作られていなかった、と書いています。 Gutmans と Suraski は中核を Zend Engine として書き直し、2000年5月の PHP 4.0 の土台にしました。 その後も 2004年7月の PHP 5 で新しいオブジェクトモデル、2015年12月の PHP 7.0 で PHP 5.6 の最大約2倍の速さ(php.net)と、大きなプログラムを支える方向へ作り直されています。

php.net のリリース一覧(2026年10月28日に確認)で最新の安定版は、2026年9月24日に公開された PHP 8.5.11 です。

W3Techs の集計(2026年10月28日)では、サーバーサイドの言語がわかるサイトの 69.2% が PHP を使っています。PHP を使うサイトの中の版の内訳は次のとおりです。

版PHP を使うサイトの中の割合
Version 865.7%
Version 726.6%
Version 57.7%
Version 40.1%
  • 1994〜95年、Lerdorf が過負荷のサーバーで自分の履歴書のアクセスを数えるとき、毎回 Perl を fork する負荷を避けるために C で書き直した道具が始まりです。
  • HTML のページに印を書いて置き換える形から出発し、root も Perl も要らない CGI として、のちに Apache のモジュールとして、動的なページを手軽にしました。
  • 最初から言語だったわけではなく、言語を名乗ったのは1996年の PHP/FI、いまの名前になったのは1998年の PHP 3.0 です。
  • フォームの値の自動登録や magic quotes などの手軽さの仕組みは、2002年に既定が変わり、2012年の 5.4.0 で削除されました。
  • 2026年10月時点で最新の安定版は 8.5.11 で、W3Techs ではサーバーサイドの言語がわかるサイトの 69.2% が PHP です。

年表

  1. Rasmus Lerdorf が Personal Home Page Tools(PHP Tools)1.0 を Usenet で発表する talks.php.net

  2. 作者の変更履歴で「PHP/FI の最初の公開リリース」とされる 1.92 が出る talks.php.net

  3. PHP/FI を「HTML に埋め込むサーバーサイドのスクリプト言語」として発表する talks.php.net

  4. 1.99l で Apache 1.1 のモジュールとして動くようになる talks.php.net

  5. Andi Gutmans・Zeev Suraski とともに書き直した PHP 3.0 が公開される talks.php.net

  6. Zend Engine を土台にした PHP 4.0.0 が公開される php.net

  7. PHP 4.2.0 で、外部の変数が既定ではグローバル変数として登録されなくなる php.net

  8. 新しいオブジェクトモデルを持つ PHP 5.0.0 が公開される php.net

  9. PHP 5.4.0 で register globals・magic quotes・safe mode が削除される php.net

  10. Zend Engine 3.0 を土台にした PHP 7.0.0 が公開される php.net

系譜

この技術が出てくる物語

同時代の出来事

出典