PHP6.0.0-devを試してみる - goto文のサポート
ここにある新規機能は、PHP5.3.0から利用可能になる予定です。
次期メジャーバージョンであるPHP6をあれこれやってみます。今回は、goto文のサポートです。
過去の一時期、「スパゲティコードになるからgoto文は悪だ!」みたいな風潮があり、個人的にはそれ以来全然使っていません。前に使ったのは、N88-BASICだったでしょうかねぇ。。。
それは置いとくとして、PHP6からgoto文がサポートされます。実際に使わなければならない場面が思いつかないのがナニですが、一応まとめてみました。
使用した環境
今回の環境は、CentOS4.5+Apache2.2.4+PHP6.0.0-devです。ソースは本家CVSリポジトリから直接取得しています。手順は『Do You PHP? - anonymous cvsからPHPのソースを取得する』を参照してください。また、PHPは以下のようなconfigureオプションを付けてbuildしています。
●PHP6.0.0-devのconfigureオプション--with-apxs2=/usr/local/apache2/bin/apxs \
--prefix=/usr/local/lib/php6 \
--with-pear=/usr/local/lib/php6/pear \
--with-config-file-path=/usr/local/lib/php6/ini/ \
--with-config-file-scan-dir=/usr/local/lib/php6/ini.d \
--enable-zend-multibyte \
--with-dom \
--enable-filter=shared \
--with-gettext=shared \
--with-mcrypt=shared \
--with-gd=shared \
--with-jpeg-dir \
--with-png-dir \
--with-zlib-dir \
--with-ttf \
--with-freetype-dir \
--enable-gd-native-ttf \
--enable-gd-jis-conv \
--enable-soap=shared \
--enable-pdo=shared \
--with-pdo-sqlite=shared \
--with-sqlite=shared \
--enable-sqlite-utf8 \
--with-openssl=shared \
--with-curl=shared \
--enable-bcmath=shared \
--enable-pcntl=shared \
--enable-sockets=shared \
--with-oci8=shared,/usr/lib/oracle/xe/app/oracle/product/10.2.0/server/ \
--with-pdo-oci=shared,/usr/lib/oracle/xe/app/oracle/product/10.2.0/server/ \
--with-pdo=shared \
--enable-sigchild \
--with-xsl=shared \
--enable-zip=shared
いずれも「--prefix」オプションを付けているため、phpコマンドのパスがデフォルトとは変わっていますが適宜読み替えてください。
goto文とラベルの構文
goto文の構文は、
goto [ラベル名];
となるようです。また、ラベルの宣言は
[ラベル名]:
です。Minutes PHP Developers Meetingにあるサンプルの再掲ですが、以下のような感じになります。
●goto1.php
<?php
for ($i = 0; $i < 9; $i++)
{
if (true) {
goto blah;
}
echo "not shown";
blah:
echo "iteration $i\n";
}
?>
また、ラベルは行頭である必要はないようです。
●goto2.php
<?php
for ($i = 0; $i < 9; $i++)
{
if (true) {
goto blah;
}
echo "not shown"; blah:
echo "iteration $i\n";
}
?>
なお、ループ内のラベルにはジャンプできません。
●goto3.php
<?php
for ($i = 0; $i < 9; $i++)
{
if (true) {
goto blah;
}
echo "not shown";
blah:
echo "iteration $i\n";
}
?>
ラベル名とラベルのスコープ
ラベル名は同一ファイル内で一意でなければなりません。また、ラベル名のスコープはファイル内のみです。require/includeしたファイルに定義したラベルへはジャンプできません。
たとえば、以下のような2つのPHPスクリプト
●goto4.php
<?php
require_once 'goto5.php';
for ($i = 0; $i < 9; $i++)
{
if (true) {
goto blah;
}
echo "not shown";
blah:
echo "iteration $i\n";
}
goto test;
echo 'not display!';
test:
echo 'display!';
?>
●goto5.php
<?php
test:
echo 'included file';
blah2:
この実行結果は以下のようになります。
●goto4.phpの実行結果included fileiteration 0 iteration 1 iteration 2 iteration 3 iteration 4
iteration 5 iteration 6 iteration 7 iteration 8 display!
まとめ
たかだかgoto文のためにウダウダ書いてきましたが、ホントにどういう場面で使うんでしょう。。。if文やbreak/continueなどでどうにかなると思うんですがねぇ。
|