Do You PHP?    
Search Engine Optimization  php5 powerd  Valid XHTML 1.0!  Valid CSS!  このサイトのはてなブックマーク数 



last updated
2008/12/06

counter hits
since 1999/11/06


PHP6.0.0-devを試してみる - goto文のサポート

cautionここにある新規機能は、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
/**
 * @see http://www.php.net/~derick/meeting-notes.html#adding-goto
 */
for ($i = 0; $i < 9; $i++)
{
    if (true) {
        /**
         * Fatal error: 'break' operator with non-constant operand is
         * no longer supported in ...
         */
//        break blah;
        goto blah;
    }
    echo "not shown";
blah:
    echo "iteration $i\n";
}
?>

また、ラベルは行頭である必要はないようです。

●goto2.php
  
<?php
/**
 * @see http://www.php.net/~derick/meeting-notes.html#adding-goto
 */
for ($i = 0; $i < 9; $i++)
{
    if (true) {
        /**
         * Fatal error: 'break' operator with non-constant operand is
         * no longer supported in ...
         */
//        break blah;
        goto blah;
    }
    echo "not shown";  blah:
    echo "iteration $i\n";
}
?>

なお、ループ内のラベルにはジャンプできません。

●goto3.php
  
<?php
/**
 * @see http://www.php.net/~derick/meeting-notes.html#adding-goto
 */
for ($i = 0; $i < 9; $i++)
{
    if (true) {
        /**
         * Fatal error: 'break' operator with non-constant operand is
         * no longer supported in ...
         */
//        break blah;
        goto blah;
    }
    echo "not shown";
blah:
    echo "iteration $i\n";
}

/**
 * ループ内にジャンプはできない
 *
 * Fatal error: 'goto' into loop or switch statement is disallowed in ...
 */
//goto blah:
?>

ラベル名とラベルのスコープ

ラベル名は同一ファイル内で一意でなければなりません。また、ラベル名のスコープはファイル内のみです。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";
}

/**
 * 同一ファイル内でラベル名は一意である必要がある
 *
 * Fatal error: Label 'blah' already defined in ...
 */
//blah:


goto test;
echo 'not display!';


test:
echo 'display!';

/**
 * Fatal error: 'goto' to undefined label 'blah2' ...
 */
//goto blah2;
?>

●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などでどうにかなると思うんですがねぇ。



About This Site |  Privacy Policy |  Contact
Copyright © 1999 - 2008 by Hideyuki SHIMOOKA all rights reserved.