前回はPHP 6のインストールまで進んだので、あとはApacheの中心的な設定ファイル「httpd.conf」を編集し、必要な設定を行いましょう。
root権限を取得してからhttpd.confをエディタで開き、PHP 6のモジュールがロードされる設定になっていることを確認します。以下の1行が記述されていればOKです。
LoadModule php6_module /usr/lib/httpd/modules/libphp6.so
次に、「.php」拡張子をPHPスクリプトとして認識してもらうために、「AddHandler」宣言が並んでいるところに以下の1行を追加します。
AddHandler php6-script .php
あと、これは任意ですが、ディレクトリだけ指定したリクエストを受け取った場合、指定されたディレクトリ内にindex.phpが存在すれば、それが実行されるようにしておきます。「DirectoryIndex」にindex.phpを追加しましょう。
DirectoryIndex index.html index.html.var index.php
以上で最低限の設定は完了です。httpd.confを保存したらApacheを再起動しましょう。
PHPが動作しているか確認するには、以下の1行だけを書いたファイル(仮にinfo.phpとします)を公開ディレクトリ下に設置し、ブラウザからアクセスしてみます。
<?php phpinfo(); ?>
「PHP Version 6.0.0-dev」と書かれたインフォメーションページが表示されたら、無事PHP 6が動いたということです。
では、早速PHP 6の新機能を見ていくことにしましょう。
名前空間「namespace」
既にPHP 5.3系にバックポートされているためPHP 6の新機能というのはちょっとはばかられますが、言語仕様の面で大きな変化となるのが「namespace」と呼ばれるものです。日本語では一般に「名前空間」と訳されますが、簡単に言うとクラス名や関数名の衝突を防ぐことを目的とした機能です。
例えば、あるPHPスクリプト(script1.php)で、外部のファイルに記述されたクラスや関数ライブラリをincludeやrequireで読み込んでいるとします。また、このPHPスクリプトのファイル中にも、関数(f1)が記述されているとしましょう。
script1.php
<?php
include 'script2.php';
:
:
function f1() {
:
:
}
?>
さて、ここでincludeされている関数ライブラリ「script2.php」にも「f1」という名前の関数が定義されていたらどうなるでしょう。
script2.php
<?php
function f1() {
:
:
}
?>
当たり前ですが、PHPでは複数の関数を同じ名前で宣言することは許されませんので、「Fatal error: Cannot redeclare f1() (previously declared in script1.php:5) in script2.php」という致命的なエラーになります。
ひとりで組める範囲の小さなスクリプトなら、プログラマが自分で考えて重複しないように命名すればよいのですが、最近はPHPも大規模なシステムに採用されることが増えていますし、便利な共有ライブラリやフレームワークを使った開発も一般的になっています。複数のプログラマが並行で作業しつつ、名前が重複しないようにするためには、あらかじめきちんと命名規則を定める必要があります。また、システムの規模が大きくなれば、それだけ名前が重複する可能性も高くなりますので、名前自体がどんどん長くわかりにくくなってしまいます。
こういった問題は、PHPで使われる「関数名」や「クラスメソッド名」が、常に「グローバルな空間」という大きな単位で扱われるために起きます。そこで、ひとつの「名前」が有効な空間をより小さな単位に分割し、プログラマが容易に把握できる範囲に閉じこめるための機能が「名前空間」なのです。
先ほどの例で言うと、明示的に指定しない限り、script1.phpのf1関数と、script2.phpのf1関数は、共にグローバルな名前空間の「f1関数」であり、区別がつきません。しかし、それぞれのスクリプトが、各々別の名前空間を持てば、この問題は解決できるはずです。PHP 6で追加された名前空間の機能では、「namespace 名前空間名;」で、個別に名前空間を宣言することができます。なお、namespaceの宣言は、必ずスクリプトファイルの先頭で行わなければならないことに注意しましょう。
script1.php
<?php
namespace ns1;
include 'script2.php';
echo f1();
function f1() {
return 'script1 - f1';
}
?>
script2.php
<?php
namespace ns2;
function f1() {
return 'script2 - f1';
}
?>
名前空間が別々に分離されたことで、このスクリプトはエラーを起こさずに実行されます。名前空間を指定せずに関数を実行した場合、呼び出し元と同じ名前空間内にある関数が実行されますので、この例では以下のような結果が返ります。
別の名前空間にある関数を実行する場合は、「名前空間名::関数名」の形式で呼び出します。
script1.php
echo ns2::f1();
:
:
名前空間は、「ns1::ns2::ns3...」のように階層的に宣言することもできます。OOPなプロジェクトでは、クラス階層と対応づける等して、よりわかりやすく後々メンテナンスしやすいコーディングを行うことが可能でしょう。