PHP: Hypertext Preprocessor
テンプレート:Infobox プログラミング言語 テンプレート:プログラミング言語 PHP: Hypertext Preprocessor(ピー・エイチ・ピー ハイパーテキスト プリプロセッサー)とは、動的にHTMLデータを生成することによって、動的なウェブページを実現することを主な目的としたプログラミング言語、およびその言語処理系である。一般的には PHP と省略して用いられており、これは「個人的なホームページ」を意味する英語の "Personal Home Page" に由来する[1]。
PHPはサーバーサイド・スクリプト言語として利用されており、Webサーバ上で動作し、Webサーバ上でPHPスクリプトの文書が要求されるたびに、そのPHPスクリプトが実行され、結果をウェブブラウザに対して送信する。平易な文法のため初心者でも習得しやすく、また大規模な開発にも多く用いられている。多くのフレームワークやライブラリが存在し、開発の手助けとなっている。
数多くのオープンソースウェブアプリケーションに利用されている一方、しばしば脆弱性の報告がなされ、過去に深刻なセキュリティホールが何度か報告されている。
特徴
PHPには以下の特徴を持ち合わせている。
- Webアプリケーションのサーバーサイド・スクリプトに専門化している。
- C言語やJava言語に似た、平易な文法。
- データベースへの容易なアクセス(組み込み関数、および、標準ライブラリPDOによる)。
- クラスベースオブジェクト指向のサポート。
- 例外処理 (try, catch, throw) のサポート。
- 多くのオープンソースのフレームワークやライブラリが利用可能である。
- ASP, JSPと似たHTML埋め込み型の構文をとる。ただし最近のフレームワークを使った開発では、埋め込み型の構文を使用しないことが多い。
- 様々な付加機能がPEARというオンラインライブラリ集でモジュールとして提供されている。pearコマンドで導入/管理ができる。PerlでいうところのCPANである。
- ウィキ構築に用いられるソフトのMediaWiki(Wikipediaで使われている)やPukiwikiを始めとして、数多くのオープンソースウェブアプリケーションに利用されている。
- 処理系本体は、C言語で書かれている。
技術構成
スクリプト実行環境
PHP4以降、Zend Engineをスクリプト言語を処理するエンジンとして利用している。Zend Engineは、PHP3の開発者によって設立されたZend Technologies Ltd.により開発されたオープンソースのスクリプト言語エンジンである。Zend Engineは1つのプロセスが1つのインタプリタのコンテキストを持つように設計されていて、単独ではマルチスレッドを用いた処理をサポートしていない。
スクリプト実行環境としてのPHPは、Zend Engineに加え、PHPの組み込み関数の実装、Webサーバや標準入出力とスクリプティングエンジンの間を仲介するSAPI (Server API) レイヤ、マルチスレッドで動くWebサーバのモジュールとして利用される場合にグローバル変数のセマンティクスを提供するTSRM (Thread Safe Resource Manager)、プラットフォーム間での入出力機構やAPIの差異を吸収するStreamsレイヤからできている。
しかし、一部の組み込み関数はプラットフォームごとに挙動が違うため、スクリプトによっては移植作業が必要になる場合がある。
Webサーバとの統合
PHPをWebサーバで動作させる方法には、実行ファイル形式 (CGI / FastCGI)、モジュール形式(mod_php / ISAPI など)がある。どの方法を利用するか(利用できるか)はWebサーバにより異なる。実行ファイル形式によるCGIはほぼ全てのWebサーバに対応しているが、Apacheで動作させる場合はmod_phpとFastCGI、IISで動作させる場合はFastCGIとISAPI、lighttpdで動作させる場合はFastCGIが使用できる。
このほかにも、PHPに標準で実装されているWebサーバ用APIは多い。以下に一覧を挙げる。
- CGI / FastCGI
- AOLserver
- Apache HTTP Server (バージョン 1.x 用 / 2.x 用)
- Lighttpd
- テンプレート:仮リンク
- Sun Java System Web Server
- Roxen WebServer
- Tux
- ISAPI (Microsoft Internet Information Services等)
- Caudium
- Continuity
- Pi3Web
- thttpd
とくに、HTTPリクエストの度にプロセスを起動させないインタフェース(Apacheとmod_phpの組み合わせ、またはlighttpdなどのFastCGIに対応したWebサーバ)での動作が高速である。
構文
多くの構文をC言語、Java、Perlなどのプログラミング言語から借用しており、動的に生成させるウェブ・ページを速やかに作成できるのが特徴である。
幾つかのサンプルコードとその実行結果を交え、PHPの文書構造を解説する。
基本と制御構造
PHPは"<?php" と "?>"で囲まれた内部をPHPコードと認識し実行する。それ以外の部分は全てHTMLコードとしてそのまま出力される。
<?php
if ($a) {
?>
<div>HTMLコード</div>
<?php
} else {
?>
<span><?php echo "aは偽"; ?></span>
<?php
}
?>
<?phpと?>で囲まれていない部分を除外した際に、構文通りの構造に文書がなっていればPHPはこれを正しく実行する。出力は以下のようになる(便宜上2通り記す)。
// $aが真の時の出力
<div>HTMLコード</div>
// $aが偽の時の出力
<span>aは偽</span>
if、else (elseif) は条件評価の制御構造としてよく知られた構文であり、他にもPHPではfor、while (do)、foreach、switch文などの制御構造がサポートされる。break、continue等の制御構造文もあるが、ループ式を命名するlabel文構造はない。
記号$は変数であることを示し、続く文字はその名前である。PHPは比較的変数に寛容であり、変数が確保されていない場合は、これをエラーとせずにnullとして処理する。
<?php
$a = x;
$$a = y; // $a==x なので $x = y;と等価
echo $x; // yを出力
?>
データ型
PHPは以下の型をサポートする
- スカラー型
- 複合型
- 特殊型
配列
配列の使用法は以下のようになる。
// array関数での生成
$a = array("wikipedia", "mediawiki", 3 => "commons");
echo $a[0]; # wikipedia
echo $a[3]; # commons
// 明示的な代入
$b[0] = "wikipedia";
$b[] = "mediawiki";
$b[] = "commons";
echo $b[2]; # commons
グローバル変数
PHPで定義されているスーパーグローバル変数を幾つか挙げる。
- $GLOBALS
- 全てのグローバル変数を連想配列とする。
括弧とは同義である。過去のバージョンは括弧内のみでしか参照できないが、現在のバージョンでは利用は非推奨となっている。
- $_SERVER ($HTTP_SERVER_VARS)
- 実行環境情報
- $_ENV ($HTTP_ENV_VARS)
- 環境変数
- $_POST ($HTTP_POST_VARS)
- POSTメソッド変数
- $_GET ($HTTP_GET_VARS)
- GETメソッド変数
- $_COOKIE ($HTTP_COOKIE_VARS)
- COOKIE変数
以下はPHP4.1以降で提供される。
- $_REQUEST
- $_GET、$_POST、$_COOKIE、$_FILES、更にURIクエリー(ロケーション)を連想配列として格納する。
- $_FILES
- ファイルアップロード処理変数
- $_SESSION
- セッション
全容把握には、var_dump 関数等で参照するとよい。
<?php
var_dump($_SERVER);
?>
クラスとオブジェクト
オブジェクト指向のPHPはクラスとオブジェクトをサポートしている。以下にクラス等オブジェクトの例をあげる。
<?php
class abc
{
public $a = null;
public function b()
{
echo "abcクラスbメソッド", PHP_EOL;
return "戻値:abc->b";
}
public function abc()
{
echo "abc:コンストラクタ生成", PHP_EOL;
}
}
class def extends abc
{
public function def()
{
echo "def:コンストラクタ生成 > ";
echo "def再定義メソッド(継承):", parent::b(), PHP_EOL;
}
public function b()
{
echo "オーバーライドされたbメソッド", PHP_EOL;
}
}
$c = new abc();
$c->b();
$f = new def();
$f->b();
?>
PHPに於けるコンストラクタ生成の演算子はnewである。extendsでクラスの継承が可能であるが多重継承はサポートされていない。メンバ変数を宣言し定義する際にはprivate・public・protected(アクセス権)を用いる(過去のバージョンでは var が使われていた)。echoは続くオブジェクトを文字列として出力するPHPの文書構造である。
parentは継承されたメソッドが、インスタンスされオーバーライドされた結果、継承されなかったメソッドを参照出来る。ここでdefクラスに継承されたメソッドはabc->bメソッドであり、def->bメソッドにより上書きされている。出力結果は以下の様になる。
abc:コンストラクタ生成 abcクラスbメソッド def:コンストラクタ生成 > abcクラスbメソッド def再定義メソッド(継承):戻値:abc->b オーバーライドされたbメソッド
アクセス権
アクセス権やfinalはPHP 5で導入された概念である(一部除く)。finalはメソッドを子クラスでオーバーライドすることを禁止する構造である。
インスタンス化されていないabcクラスのbメソッドを静的に呼び出したい場合、
// static:
class abc
{
public static function b()
{
}
}
とstatic宣言をせねばならない。宣言がない場合、全てpublic(どこからでも参照可)で処理される。
なおvarは互換性のため残されており、publicと等価であるが、PHP5.1.3以前のPHP5はエラーとなる。protectedは親クラス・派生クラス・ないしそれを実装するクラス自身からのアクセスのみを許可し、privateは定義クラス内部のみ参照が可能である。
インタフェース(定義部)と抽象化 (abstract)
抽象化はPHP 5より導入された概念であり、インタフェースはJavaのそれやObjective-Cので実装されているものである。 Objective-Cと違い、インタフェースはいまのところこれはコードから定義部と実装部を完全に切り離すものではなく、定義の必要性は無い。
やっていることは抽象クラス(抽象メソッド)とインタフェースは実質変わらないが、その概念は異なる。
インターフェースはその処理内容を定義せずに定義されるが、抽象クラス(抽象メソッド)は実装部の具体的な処理のコードと共に定義されている。
インタフェースの実装
まず最初に具体的なソースコードを示す。
<?php
interface classTemplates
{
public function methodAlpha($arg1, $arg2);
public function methodBeta($arg1);
}
class appTemplate implements classTemplates
{
public function methodAlpha($arg1, $arg2)
{
}
public function methodBeta($arg1)
{
}
}
?>
interface接頭辞をつけテンプレートを定義し、implementsをつけクラスに適用し実装する。テンプレートはextends で継承可能である。 テンプレートは定義されていても必ず適用されるクラスが必要なわけではない。ただし、適用する前に定義されている必要がある。
いまのところ、定義できるのメンバはpublic(公開可視性)のあるメソッドだけである。
適用されたクラスに定義されたメソッドの「アクセス権・引数」が異なればエラーを引き起こし、またクラスの名前と同じinterfaceは定義できない。
インタフェースの継承
<?php
interface classTemplatesModel
{
public function methodAlpha($arg1, $arg2);
public function methodBeta($arg1);
}
interface classTemplates extends classTemplatesModel
{
public function methodGamma();
}
?>
interfaceの多重継承について
interfaceは多重継承が可能である。複数のinterfaceを実装するにはimplementsにコンマ区切りでinterface名を書く。
<?php
interface classTemplatesModel
{
public function methodAlpha($arg1, $arg2);
public function methodBeta($arg1);
}
interface classTemplates
{
public function methodGamma();
}
class appTemplate implements classTemplates, classTemplatesModel
{
public function methodAlpha($arg1, $arg2)
{
}
public function methodBeta($arg1)
{
}
public function methodGamma()
{
}
}
?>
抽象クラスの定義
クラス名にfinalと同じ様に接頭辞としてabstractをつければ、それは抽象クラスとなる。
メソッドにつければ、それは必ず継承したクラスで実装されねばならない(引数は同じである必要がある)。具体的なソースを示す。
<?php
abstract class Alpha
{
abstract public function methodAlpha($arg1, $arg2);
protected function methodBeta($arg1)
{
echo "Alpha クラスで実装されたmathodBeta メソッド¥n";
}
public function __destruct()
{
echo "インスタンスを破棄、メモリを開放[Alpha::destruct]¥n";
}
}
class Beta extends Alpha
{
public function __construct()
{
$this->methodAlpha("","");
$this->methodBeta("");
}
public function methodAlpha($arg1, $arg2)
{
echo "Beta クラスで実装されたmethodAlpha メソッド¥n";
}
}
new Beta();
?>
__construct() は PHP 5からインスタンス生成の時に自動的に呼び出されるコンストラクタ(__destruct()、デストラクタも実装された)。
protected(保護可視性)は、継承されたクラス・または内部($this、parentなど)でないと、使えないようにする宣言である。
抽象化されたクラスはインスタンスを生成出来ない。よって new Alpha(); とすることは出来ない。また、抽象化されたメソッドは継承しないと使用することは出来ない。
実行結果
Beta クラスで実装された methodAlpha メソッド Alpha クラスで実装された methodBeta メソッド インスタンスを破棄、メモリを開放 [Alpha::destruct]
PDO
テンプレート:Main MySQLやPostgreSQLなど主要なRDBMSへの接続については、それぞれ専用の関数ライブラリが用意されている。phpinfo()を表示させれば、そのPHPバージョンにおけるインプリメント状況を確認できる。関数の仕様については微妙な差があり、異なるRDBMSへの移行には支障となる。そのリスクを軽減するのがPDO (PHP Data Object) と呼ばれる、共通する機能はなるべく同じインタフェースで実現しようというアイデアによる、抽象化ライブラリである。ただし文字列処理関数などSQLごとに存在している差異までカバーしているわけではなく、移行に際してはそれなりの注意が必要である。いくらか楽になるという程度の認識で、過信は禁物といえよう。RDBMSごとに、pdo_から始まる名称のドライバモジュールが提供されているが、最近のPHP5.2.5などドライバモジュールが見当たらなくても、標準で組み込まれているケースがある。
その他
include、require等の演算子で外部ファイルに記述されたPHPコードを追加ないし、参照、実行が可能である。returnは戻り値を返す文書構造である。return()とすることで戻り値を評価することも可能である。
Unixコマンドを実行可能であるが、CGIより実行権限は低くなっている。また一部関数はこのUnixコマンドを参照するため、Windows系OSでは使用できない関数がある。コマンドを参照する関数を使用する際は、サーバの設定でパスが通っている必要がある。
幾つもの拡張により扱える関数は環境に依りまちまちである。詳しくは外部リンクのリファレンスを参照されたい。
代表的なソフトウェア
ウェブアプリケーション、CMSなど
ウェブアプリケーション・フレームワーク
- CakePHP
- CodeIgniter
- Cosmos
- Ethna
- eZ components
- FuelPHP
- Kohana
- Laravel
- Lithium
- Maple
- Mojavi
- Omusuvi
- Peewee
- PHP on TRAX
- PRADO
- Risoluto
- Sabel
- Seagull
- Seasar.PHP
- Symfony
- WACT
- xFramework
- Yii
- Zend Framework
- Zoop
- ちいたん
- Chimpanzee
- FekePHP
対応する主要DBMS
歴史
PHP 1.0
1995年6月8日にリリース。ラスマス・ラードフが開発。初期は Perl でかかれたスクリプトだったが、その後C言語で書き直され、PHP (Personal Home Page Tools) となる。
PHP Version 2 (PHP/FI)
1996年4月16日にリリース。 FI(Form Interpreter、SQLによるDBMSツール)が統合され、1997年に PHP/FI2.0 となる。フルスペルは「Personal Home Page Construction Kit/Form Interpreter」。
PHP 3.0
1998年6月6日にリリース。 PHP/FI を元に、アンディ・ガトマンズとゼーブ・スラスキーによって PHP3 (PHP: Hypertext Preprocessor) が再度書き直された。
PHP 4.0.0
2000年5月22日にリリース。PHP3 を大幅に機能拡張。Zend Engine 導入。
PHP 4.1.0
2001年12月10日にリリース。スーパーグローバルが追加される。
PHP 4.2.0
2002年4月22日にリリース。register_globals の初期値が Off に変更される。
PHP 4.3.0
2002年12月27日にリリース。コマンドラインインタフェースの実装。
PHP 4.4.0
2005年7月11日にリリース。
2007年7月11日、PHP4のサポートを2007年12月31日をもって終了するという告知がなされた。重大なセキュリティに関する修正のみ、2008年8月8日まで継続され、その後すべてのサポートは終了した。
PHP 5.0.0
2004年7月13日にリリース。擬似的なオブジェクト指向がより一層強化されると共に、クラスライブラリとして SPL がサポートされた。 また、SQLite が標準装備されるようになった。Zend Engine 2.0 導入。
PHP 5.1.0
2005年11月24日にリリース。実行速度の改善、PDO エクステンションが追加される。
PHP 5.2.0
2006年11月2日にリリース。拡張モジュールに Filter(フィルタ)がデフォルトで追加される。
PHP 5.3.0
2009年6月30日にリリース。 以下の機能が追加になった[2]。
- 名前空間
- 遅延静的束縛
- goto
- クロージャ
- ガベージコレクション
PHP 5.4.0
2012年3月1日にリリース。 以下の機能が追加になった[3]。
- トレイト
- 配列の短縮構文
- 関数の返り値を配列として扱えるようになった
- クロージャが $this を使えるようになった
PHP 5.5.0
2013年6月20日にリリース。 以下の機能が追加になった[4]。
- ジェネレータ
- finallyキーワード
- foreach が list() に対応
- empty() が任意の式に対応
- array リテラルと string リテラルのデリファレンス
- ClassName::class によるクラス名の解決
- OPcache 拡張モジュールの追加
- foreach が非スカラーのキーに対応
- Apache 2.4 ハンドラが Windows に対応
- GD 拡張モジュールの改良
Windows版について
Windows環境でApacheと組み合わせる場合、Windows版PHPやApacheの開発環境であるMicrosoft Visual C++のバージョンの関係から、ApacheのモジュールはApache公式サイトではなく、「Apache Lounge」なるサイトにあるものを使うように、PHPの公式サイトに記載されている。