PHP: Hypertext Preprocessor

出典: フリー百科事典『ウィキペディア(Wikipedia)』

PHP Hypertext Preprocessor から転送)
PHP5
-
パラダイム 命令型, オブジェクト指向
開発者 The PHP Group
最新リリース 5.2.6 / 2008年5月1日
型付け 弱い動的型付け
影響を受けた言語 Perl, C
プラットフォーム cross-platform
ライセンス PHP License[1]
ウェブサイト http://www.php.net/
  
PHP4
-
パラダイム 命令型, オブジェクト指向
開発者 The PHP Group
最新リリース 4.4.8 / 2008年1月3日
型付け 弱い動的型付け
影響を受けた言語 Perl, C
プラットフォーム cross-platform
ライセンス PHP License[2]
ウェブサイト http://www.php.net/
  

PHP: Hypertext Preprocessorピー・エイチ・ピー ハイパーテキスト プリプロセッサー)とは、動的にHTMLデータを生成することによって、動的なウェブページを実現することを主な目的としたプログラミング言語、およびその言語処理系である。

PHPは、HTML埋め込み型のサーバサイド・スクリプト言語として分類される。この言語処理系自体は、C言語で記述されている。

ウェブサーバ上で動作し、ウェブサーバ上の文書が要求されるたびに、この文書に記述されたPHPのプログラムを実行し、その結果をウェブブラウザに対して送信する。

ウェブブラウザに送信されるデータは通常のHTMLであり、PHPのプログラムを含まない。この点でHTML埋め込み型のクライアントサイド・スクリプト言語(JavaScriptなど)と本質的に異なっている。

平易な文法のため初心者でも習得しやすく、また大規模な開発にも多く用いられている。多くのフレームワークやライブラリが存在し、開発の手助けとなっている。

しばしば脆弱性の報告がなされ、過去に深刻なセキュリティホールが何度か報告されている。

目次

[編集] 名称

正式名称は「PHP: Hypertext Preprocessor」であるが、一般的には「PHP」と省略して用いられる。このPHPとは、Personal Home Page Toolsの頭文字に由来する[1]

[編集] 仕様

PHPはCommon Gateway Interface (CGI) をサポートしており、CGIをサポートするWebサーバ上でPHPスクリプトを実行することができる。この他にもFastCGIを通じてWebサーバから起動したり、利用するWebサーバモジュール機構を提供していれば、モジュールとしてWebサーバに組み込んだ状態で動作させることが可能である。その為、phpモジュールに脆弱性があった場合、簡単にWebサーバの権限を奪取され、サーバを破壊されることもある。

PHPは、PHP4以降Zend Engineをスクリプト言語を処理するエンジンとして利用している。Zend Engineは、PHP3の開発者によって設立されたZend Technologies Ltd.により開発されたソースコードが公開されているスクリプティングエンジンで、PHP5ではZend Engine 2.0になった。Zend Engineは基本的に1つのプロセスがインタプリタのコンテキストを1つだけ持つものとして設計されている。したがってマルチスレッドを用いたスクリプティングはサポートしていない。

Zend Engineを除くPHP本体は、PHP組み込み関数の実装を含むほか、Webサーバコマンドラインインターフェイスとスクリプティングエンジンの間を仲介するSAPI (Server API)レイヤ、マルチスレッドで動くWebサーバのモジュールとして利用される場合にグローバル変数のセマンティクスを提供するTSRM (Thread Safe Resource Manager)、さまざまなプラットフォームの入出力機構やAPIの差異を吸収するためのStreamsレイヤから成る。

開発者はSAPIの提供するSPIを実装することで、さまざまなWebサーバのモジュールとしてPHPを動作させることができる。標準では以下のWebサーバ用のSAPIが提供されている。

PHPを動作させる方法には、実行ファイル形式(CGI / FastCGI)、モジュール形式(mod_php / ISAPI)がある。どの形式を使用するかはWebサーバーにより異なる。一例を挙げるならば、Apacheで動作させる場合はmod_phpを使用し、IISで動作させる場合はISAPIを使用し、lighttpdで動作させる場合はFastCGIを使用し、AN HTTPDで動作させる場合はCGIを使用する(いずれも代表例であり、他の形式でも動作させることは可能だが、実例は少ない)。

PHPにおいては一般的に実行ファイル形式よりもモジュール形式の方が高速に動作するとされる。そのためApacheとmod_phpの組み合わせがよく用いられている。ただし実行ファイル形式でもFastCGIを使用することによりモジュール形式と並ぶパフォーマンスを出すことも可能である(例えばlighttpdとFastCGIの組み合わせ)。

PHPにはWindowsUNIXなどのオペレーティングシステムに対応した処理系が存在する。一部の組み込み関数はプラットフォームごとに挙動が違うため、スクリプトによっては移植作業が必要になる場合がある。

また、多くのDBMSへのインターフェイスを標準で備えており、DBMSとの連携にも高い力を発揮する。

HTML埋め込み型の処理系としては他にASPJSPなどがある。

PHPには様々な付加機能がPEARというオンラインライブラリ集でモジュールとして提供されており、同名のツールを使って導入/管理が出来る。Perlで言うCPANと同じ役割を持っている。

[編集] 構文

多くの構文をC言語、JavaPerlなどのプログラミング言語から転用しており、動的に生成させるウェブ・ページを速やかに作成できるのが特徴である。ウィキ構築に用いられるソフトの一つであるMediaWikiは、PHPによって書かれている。

幾つかのサンプルコードとその実行結果を交え、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ではforwhile(do)、foreachswitch文などの制御構造がサポートされる。breakcontinue等の制御構造文もあるが、ループ式を命名するlabel文構造はない。

記号$は変数であることを示し、続く文字はその名前である。PHPは比較的変数に寛容であり、変数が確保されていない場合は、これをエラーとせずにヌルとして処理する。

<?php
$a = x;
$$a = 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
セッション

全容把握には、print_r関数等で参照するとよい。

<?php
print_r($_SERVER);
?>

[編集] クラスとオブジェクト

オブジェクト指向のPHPはクラスとオブジェクトをサポートしている。以下にクラス等オブジェクトの例をあげる。

<?php
class abc{
 var $a = null;
 function b(){
  echo "abcクラスbメソッド¥n";
  return "戻値:abc->b";
  }
 function abc(){
  echo "abc:コンストラクタ生成¥n";
  }
 }
class def extends abc{
 function def(){
  echo "def:コンストラクタ生成 > ";
  echo "def再定義メソッド(継承):" . parent::b() . "¥n";
  }
 function b(){
  echo "オーバーライドされたbメソッド¥n";
  }
 }
 
$c = new abc();
abc::b();
$f = new def();
$f->b();
?>

PHPに於けるコンストラクタ生成の演算子はnewである。extendsでクラスの継承が可能であるが多重継承はサポートされていない。varはおなじみだが、メンバ変数を宣言し定義する。echoは続くオブジェクトを出力するPHPの文書構造である。そのほかにもlist(配列)、final(メソッド)、private・public・protected(アクセス権)などの文書構造がある

parentは継承されたメソッドが、インスタンスされオーバーライドされた結果、継承されなかったメソッドを参照出来る。ここでdefクラスに継承されたメソッドはabc->bメソッドであり、def->bメソッドにより上書きされている。出力結果は以下の様になる。

abc:コンストラクタ生成
abcクラスbメソッド
def:コンストラクタ生成 > abcクラスbメソッド
def再定義メソッド(継承):戻値:abc->b
オーバーライドされたbメソッド

[編集] アクセス権

アクセス権やfinalはPHP 5で導入された概念である(一部除く)。finalはメソッドを子クラスで上書きすることを禁止する構造である。

上記コードのインスタンス化されていないabc::b();でスコープ解決されたメンバ部分は、PHP5ではアクセス権の問題でアクセス出来ない。この場合、インスタンス化せずに呼び出したいので、

// static:
class abc{
 var $a = null;
 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 methodAlfha($arg1, $arg2);
        public function methodBeta($arg1);
        }
 
class appTemplate implements classTemplates
        {
        public function methodAlfha($arg1, $arg2)
                {
                }
        public function methodBeta($arg1)
                {
                }
        }
?>

interface接頭辞をつけテンプレートを定義し、implementsをつけクラスに適用し実装する。テンプレートはextends で継承可能である。 テンプレートは定義されていても必ず適用されるクラスが必要なわけではない。ただし、適用する前に定義されている必要がある。

いまのところ、定義できるのメンバはpublic(公開可視性)のあるメソッドだけである。

適用されたクラスに定義されたメソッドの「アクセス権・引数」が異なればエラーを引き起こし、またクラスの名前と同じinterfaceは定義できない。

  • インタフェースの継承
<?php
interface classTemplatesModel
        {
        public function methodAlfha($arg1, $arg2);
        public function methodBeta($arg1);
        }
 
interface classTemplates extends classTemplatesModel
        {
        public function methodGamma();
        }
?>
  • interfaceの多重継承について

今のところ、多重継承は出来ない。よって以下のコードは無効である

<?php
interface classTemplatesModel
        {
        public function methodAlfha($arg1, $arg2);
        public function methodBeta($arg1);
        }
 
interface classTemplates extends classTemplatesModel
        {
        public function methodGamma();
        }
 
// このようなimplementsの実装は無効。
class appTemplate implements classTemplates, classTemplatesModel
        {
        public function methodAlfha($arg1, $arg2)
                {
                }
        public function methodBeta($arg1)
                {
                }
        public function methodGamma()
                {
                }
        }
?>

[編集] 抽象クラスの定義

クラス名にfinalと同じ様に接頭辞としてabstractをつければ、それは抽象クラスとなる。

メソッドにつければ、それは必ず継承したクラスで実装されねばならない(引数は同じである必要がある)。具体的なソースを示す。

<?php
abstract class Alfha
        {
        abstract public function methodAlfha($arg1, $arg2);
        protected function methodBeta($arg1)
                {
                echo "Alfha クラスで実装されたmathodBeta メソッド¥n";
                }
 
        public function __destruct()
                {
                echo "インスタンスを破棄、メモリを開放[Alfha::destruct]¥n";
                }
        }
 
class Beta extends Alfha
        {
        public function __construct()
                {
                $this->methodAlfha("","");
                $this->methodBeta("");
                }
 
        public function methodAlfha($arg1, $arg2)
                {
                echo "Beta クラスで実装されたmethodAlfha メソッド¥n";
                }
        }
 
new Beta();
?>

__construct()は PHP 5からインスタンス生成の時に自動的に呼び出されるコンストラクタ(__destruct()、デストラクタも実装された)。
protected(保護可視性)は、継承されたクラス・または内部($this、parentなど)でないと、使えないようにする宣言である。

抽象化されたクラスはインスタンスを生成出来ない。よってnew Alfha();とすることは出来ない。また、抽象化されたメソッドは継承しないと使用することは出来ない。

  • 実行結果
Beta クラスで実装されたmethodAlfha メソッド
Alfha クラスで実装されたmethodBeta メソッド
インスタンスを破棄、メモリを開放[Alfha::destruct]

[編集] PDO

詳細はPHP Data Objectを参照。

MySQLPostgreSQLなど主要なRDBMSへの接続については、それぞれ専用の関数ライブラリが用意されている。phpinfo()を表示させれば、そのPHPバージョンにおけるインプリメント状況を確認できる。関数の仕様については微妙な差があり、異なるRDBMSへの移行には支障となる。そのリスクを軽減するのがPDO(PHP Data Object)と呼ばれる、共通する機能はなるべく同じインタフェースで実現しようというアイデアによる、抽象化ライブラリである。ただし文字列処理関数などSQLごとに存在している差異までカバーしているわけではなく、移行に際してはそれなりの注意が必要である。いくらか楽になるという程度の認識で、過信は禁物といえよう。RDBMSごとに、pdo_から始まる名称のドライバモジュールが提供されているが、最近のPHP5.2.5などドライバモジュールが見当たらなくても、標準で組み込まれているケースがある。

[編集] その他

include、require等の演算子で外部ファイルに記述されたPHPコードを追加ないし、参照、実行が可能である。returnは戻り値を返す文書構造である。return()とすることで戻り値を評価することも可能である。

Unixコマンドを実行可能であるが、CGIより実行権限は低くなっている。また一部関数はこのUnixコマンドを参照するため、Windows系OSでは使用できない関数がある。コマンドを参照する関数を使用する際は、サーバーの設定でパスが通っている必要がある。

幾つもの拡張により扱える関数は環境に依りまちまちである。詳しくは下記外部リンクのリファレンスを参照されたい。

[編集] PHPによる有名なソフト

[編集] 対応する主要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 となる。

[編集] PHP 3.0

1998年6月6日にリリース。 PHP/FI を元に、アンディ・ガトマンズ (Andi Gutmans) と ゼーブ・スラスキー (Zeev Suraski) によって 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 (フィルタ) がデフォルトで追加される。

[編集] 脚注

  1. ^ PHP の歴史と関連するプロジェクト - PHP Manual。

[編集] 関連項目

[編集] 外部リンク