アシアルブログ

アシアルの中の人が技術と想いのたけをつづるブログです

PHP5.6.0alphaリリース!新機能を試す


こんにちは、久保田です。PHP5.6.0alpha1が1月23日付けでリリースされました。

この記事では5.6に搭載される以下の新機能や変更を紹介します。

  • phpdbgデバッガ
  • 可変長引数のための文法の追加
  • 定数定義での計算のサポート
  • その他NEWSファイルに記述されている変更


PHP5.6.0をビルドして試してみる



PHP5.6の新機能を紹介する前に、まずはMacOSXLinux環境にPHP5.6をビルドして試す方法を紹介します。Windows環境の場合にはビルド済みのバイナリが用意されているのでそれをダウンロードして下さい。

まず5.6.0alpha1リリースの記事にあるリンクから、PHP5.6.0alpha1のパッケージをダウンロードして解凍します。次に解凍したパッケージのディレクトリに進んでconfigureスクリプトを叩きます。



$ cd php-5.6.0alpha1/

$ ./configure


この時ビルドに必要なツールがない場合には失敗して警告が出るので、メッセージに従って必要なツールをインストールして下さい。ビルドに必要なツールの詳細についてはPHPマニュアルのUnix システムへのインストールの項を参照して下さい。

configureスクリプトが無事終わって、makeコマンドを叩くとビルドが始まります。



$ make 


ビルドが無事終わったらsapiディレクトリ以下に各種バイナリが生成されていることを確認します。コマンドラインで利用するPHPは、sapi/cli/phpに置かれています。今回のこの記事で紹介するphpdbgはsapi/phpdbg/phpdbgに置かれています。



$ sapi/cli/php -v
PHP 5.6.0alpha1 (cli) (built: Jan 31 2014 13:07:58)
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.6.0-dev, Copyright (c) 1998-2014 Zend Technologies

$ sapi/phpdbg/phpdbg --version
phpdbg 0.3.1 (built: Jan 31 2014 13:08:01)
PHP 5.6.0alpha1, Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.6.0-dev, Copyright (c) 1998-2014 Zend Technologies


さてPHP5.6をビルドできたところで、5.6の新機能を説明します。

最も大きな変更: phpdbgが標準で含まれるように



これまで、PHPのコードにブレークポイントを仕掛けてデバッグする場合には、phpdbgやxdebugなどのモジュールをPECLでインストールしてセットアップする必要がありました。PHP5.6ではデバッグ用のSAPIを提供しているphpdbgモジュールが標準で含まれるようになりました。

ここでは簡単にphpdbgの使い方を紹介してみます。まず、デバッグ対象である以下のPHPのコードをhoge.phpというファイル名で保存します。



<?php // hoge.php

$hoge = 'hogehoge';
echo $hoge . "\n";


phpdbgは、gdbライクなインターフェイスxdebugよりも手軽に利用できるデバッガです。phpdbgコマンドから起動して簡単に利用できます。読み込むPHPファイルは、-eオプションで起動時に渡します。



$ sapi/cli/phpdbg -e hoge.php
[Welcome to phpdbg, the interactive PHP debugger, v0.3.1]
To get help using phpdbg type "help" and press enter
[Please report bugs to <http://github.com/krakjoe/phpdbg/issues>]


PHPファイルを読み込んで、特に何もせずにrunコマンドで実行してみます。



phpdbg> run
[Attempting compilation of /Users/anatoo/Desktop/php-5.6.0alpha1/hoge.php]
[Success]
hogehoge
phpdbg>


これだけだと何の意味もないので、次はhoge.phpの中身をコンパイルしてその結果であるオペコードを覗いてみます。

PHPのコードは、PHPの言語処理系によってパースされて内部のZendEngineによって実行できる内部表現にコンパイルされた後に実行されます。ZendEngine向けにコンパイルされる内部表現をオペコードといいます。

今までこのオペコードを見るには、vldというPECLモジュールをインストールする必要がありましたが、このphpdbgではオペコードも簡単に覗けます。

compileコマンドでソースコードをオペコードへコンパイルをして、print execコマンドを打つとコンパイルされたhoge.phpのオペコードが表示されます。



phpdbg> compile
[Destroying previously compiled opcodes]
[Attempting compilation of /Users/anatoo/Desktop/php-5.6.0alpha1/hoge.php]
[Success]

phpdbg> print exec
[Context /Users/anatoo/Desktop/php-5.6.0alpha1/hoge.php]
        L0-0 {main}() /Users/anatoo/Desktop/php-5.6.0alpha1/hoge.php
                L3      0x10a188ff8 ZEND_ASSIGN                    $hoge                C0                   @0
                L5      0x10a189028 ZEND_ECHO                      $hoge                <unused>             <unused>


ZEND_ASSIGNという$hogeに'hogehoge'値が代入する命令と、ZEND_ECHOという$hogeの値が表示するという命令のオペコードが表示されます。

これだけだとつまらないので、次にデバッガらしくブレークポイントを張ってステップ実行する方法を紹介します。ブレークポイントを張るには、breakコマンドを使ってブレークする位置を指定します。

ブレークポイントに指定できるのは、ファイルの行数や関数名やメソッド名やそれ以外にもオペコードや特定の条件下にのみブレークするなど、かなり柔軟に指定できます。

ここではhoge.phpの3行目を指定してみます。break (ファイル名):(行数)という形で指定します。



phpdbg> break hoge.php:3
[Breakpoint #0 added at /Users/anatoo/Desktop/php-5.6.0alpha1/hoge.php:3]


ブレークポイントを張ったら、次にrunコマンドで実行します。



phpdbg> run
[Breakpoint #0 at /Users/anatoo/Desktop/php-5.6.0alpha1/hoge.php:3, hits: 1]
 00002:
>00003: $hoge = 'hogehoge';
 00004:


3行目でブレークしています。ブレークしている状態で、nextコマンドやstepコマンドを使うとステップ実行できます。



phpdbg> next
hogehoge
phpdbg>


phpdbgデバッガの詳しい使い方は、phpdbgのウェブサイトや以下の参考資料を参照して下さい。



可変長引数のための文法が追加



関数やメソッドで、可変長引数を取るための文法が追加されました。以下のようなコードが動きます。



<?php

function foo(...$args)
{
    var_dump($args);
}

foo(1, 2, 3);
// => array(3) {
//      [0]=>
//      int(1)
//      [1]=>
//      int(2)
//      [2]=>
//      int(3)
//    }


class Foobar {}

function bar($first, Foobar ...$args)
{
    var_dump($args);
}

bar(1, new Foobar, new Foobar);
// => array(2) {
//      [0]=>
//      object(Foobar)#1 (0) {
//      }
//      [1]=>
//      object(Foobar)#2 (0) {
//      }
//    }


これまでは、可変長引数を扱うにはfunc_get_args()関数を使う必要がありましたが、今回追加された文法により以下のように記述できるようになりました。

参考:



定数定義での計算のサポート



クラス定数や、プロパティや引数のデフォルト値を設定する定数定義で計算をサポートするようになりました。計算に利用できるのは、スカラー値や他の定数を用いた演算子による計算です。以下のようなコードが動きます。



<?php

const A = 60 * 60 * 5;

const B = A > 0 ? 'A' : 'B';



もちろんクラス定数やプロパティの初期化でも利用できます。



<?php

class Foobar 
{
    const A = 10;
    const B = A * 10;

    public $a = 1 << 0;
    public $b = 1 << 1;
    public $c = 1 << 2;
}


さらに、関数・メソッドのデフォルト引数やstatic変数の初期化時にも利用できます。



<?php

class Foo
{
    const A = 'hoge';

    function doSomething($a = 10 * 10, $b = self::A . 'str') 
    {
        // ...
    }
}

function foo()
{
    static $bar = 10 * 10 * Foo::A;
}



参考:



その他の変更



NEWSファイルに記載されているその他の変更をリストにしておきます。



NEWSファイル



以下に、NEWSファイルの簡単な訳を掲載します。細かな変更点はこれを参照して下さい。



 PHP                                                                        NEWS
 |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

 23 Jan 2014, PHP 5.6.0 Alpha 1
 - CLI server:
   . CLI WebサーバにいくつかのMIMEタイプ追加 (Chris Jones)
   . Added some MIME types to the CLI web server. (Chris Jones)
 
 - Core:
   . IS_VARオペランドの値の取得を最適化。 (Laruence, Dmitry)
   . Improved IS_VAR operands fetching. (Laruence, Dmitry)
   . 空白文字列の扱いを最適化。Zend Engineは毎回新しい空白の文字列をアロケーションする代わりに、
     internedな空白文字列を使うようになった。
   . Improved empty string handling. Now ZE uses an interned string instead of
     allocation new empty string each time. (Laruence, Dmitry)
   . 内部での演算子のオーバーロードを実装。
     (RFC: https://wiki.php.net/rfc/operator_overloading_gmp). (Nikita)
   . Implemented internal operator overloading
     (RFC: https://wiki.php.net/rfc/operator_overloading_gmp). (Nikita)
   . 互換性のないコンテキストの問題に関して、 E_STRICTではなくE_DEPRECATED警告を出すようにした。(Gustavo)
   . Made calls from incompatible context issue an E_DEPRECATED warning instead
     of E_STRICT (phase 1 of RFC: https://wiki.php.net/rfc/incompat_ctx).
         (Gustavo)
   . 2GBよりも大きなファイルをアップロードできるようになった。(Ralf Lang, Mike)
   . Uploads equal or greater than 2GB in size are now accepted.
     (Ralf Lang, Mike)
   . POSTデータを扱うメモリ使用量を200%から300%ほど圧縮した。
     $HTTP_RAW_POST_DATAグローバル変数に値を受け入れないようにしている時に
     always_populate_raw_post_dataディテクティブが、必ず廃止予定の警告を出す。
     この設定は、将来のPHPのバージョンでは、デフォルトになる。(Mike)
   . Reduced POST data memory usage by 200-300%. Changed INI setting
     always_populate_raw_post_data to throw a deprecation warning when enabling
         and to accept -1 for never populating the $HTTP_RAW_POST_DATA global 
         variable, which will be the default in future PHP versions. (Mike)
   . 可変長引数をとる関数専用の文法を実装。
     (RFC: https://wiki.php.net/rfc/variadics). (Nikita)
   . Implemented dedicated syntax for variadic functions
     (RFC: https://wiki.php.net/rfc/variadics). (Nikita)
   . #50333バグを修正。emalloc/efree/strdupを使ってマルチスレッド時のスケーラビリティを改善。
     emalloc/efree/estrdup (Anatol, Dmitry)
   . Fixed bug #50333 Improving multi-threaded scalability by using
     emalloc/efree/estrdup (Anatol, Dmitry)
   . 定数定義でのスカラー値や定数の計算を実装。
     (RFC: https://wiki.php.net/rfc/const_scalar_exprs). (Bob)
   . Implemented constant scalar expressions (with support for constants)
     (RFC: https://wiki.php.net/rfc/const_scalar_exprs). (Bob)
   . finallyを使うとSegfault出してしまう#65784バグを修正。(Laruence, Dmitry)
   . Fixed bug #65784 (Segfault with finally). (Laruence, Dmitry)
   . #66509バグを修正。 (copy() arginfo has changed starting from 5.4). (willfitch)
   . Fixed bug #66509 (copy() arginfo has changed starting from 5.4). (willfitch)
 
 - cURL:
   . 機能リクエスト#65646を実装(open_basedirやsave_mode時にCURLOPT_FOLLOWLOCATIONを再び有効にした)。 (Adam)
   . Implemented FR #65646 (re-enable CURLOPT_FOLLOWLOCATION with open_basedir
     or safe_mode). (Adam)
 
 - GMP:
   . GMPモジュールで内部での演算子オーバーロードを用いて様々な改善を実装し、
     基本的な構造を表すのにオブジェクトを利用するようにした。
     (RFC: https://wiki.php.net/rfc/operator_overloading_gmp). (Nikita)
   . Moved GMP to use object as the underlying structure and implemented various
     improvements based on this.
     (RFC: https://wiki.php.net/rfc/operator_overloading_gmp). (Nikita)
   . n番目のルートを計算するためのgmp_root()関数とgmp_rootrem()関数を追加。
     (Nikita)
   . Added gmp_root() and gmp_rootrem() functions for calculating nth roots.
     (Nikita)
 
 - Hash:
   . gost-crypto (CryptoPro S-box) GOSTハッシュアルゴリズムの追加. (Manuel Mausz)
   . Added gost-crypto (CryptoPro S-box) GOST hash algo. (Manuel Mausz)
 
 - JSON:
   . バグ#64874のケースパートを修正("json_decode handles whitespace and case-sensitivity incorrectly")。
   . Fixed case part of bug #64874 ("json_decode handles whitespace and
     case-sensitivity incorrectly")
 
 - mysqlnd:
   . MySQL5.5以降で基本的なAPIでネイティブにサポートされていないSP OUT 変数のフラグを使えないように修正。(Andrey)
   . Disabled flag for SP OUT variables for 5.5+ servers as they are not natively
     supported by the overlying APIs. (Andrey)
 
 - OPcache:
   . いくつかの内部関数で、定数やクラス定数を取得する際に最適化を追加。(Laruence, Dmitry)
   . Added an optimization of class constants and constant calls to some
     internal functions (Laruence, Dmitry)
   . FCALL_BY_NAMEをDO_FCALLに変換する最適化パスを追加。(Laruence, Dmitry)
   . Added an optimization pass to convert FCALL_BY_NAME into DO_FCALL.
     (Laruence, Dmitry)
   . op_array_->literalsテーブル内での、同一の定数やそれに関係するcache_slotsをマージする最適化パスを追加。(Laruence, Dmitry)
   . Added an optimization pass to merged identical constants (and related
     cache_slots) in op_array->literals table. (Laruence, Dmitry)
   . スクリプトレベルで定数置換する最適化パスを追加。
   . Added script level constant replacement optimization pass. (Dmitry)
 
 - Openssl:
   . SSLストリームコンテキストで利用できるcrypto_methodオプションを追加。 (Martin Jansen)
   . Added crypto_method option for the ssl stream context. (Martin Jansen)
   . フィンガープリントのサポートの追加。(Tjerk Meesters)
   . Added certificate fingerprint support. (Tjerk Meesters)
   . 明示的にTLSv1.1 and TLSv1.2ストリームtransportsを追加。(Daniel Lowrey)
   . Added explicit TLSv1.1 and TLSv1.2 stream transports. (Daniel Lowrey)
   . バグ#65729を修正(CN_matchが偽陽性)。 (Tjerk Meesters)
   . Fixed bug #65729 (CN_match gives false positive). (Tjerk Meesters)
   
 - PDO_pgsql:
   . バグ#42614を修正(PDO_pgsqlでpg_get_notifyのサポートを追加)。 (Matteo)
   . Fixed Bug #42614 (PDO_pgsql: add pg_get_notify support). (Matteo)
   . バグ #63657を修正(pgsqlCopyFromFile, pgsqlCopyToArray use Postgres < 7.3 syntax)。 (Matteo)
   . Fixed Bug #63657 (pgsqlCopyFromFile, pgsqlCopyToArray use Postgres < 7.3
     syntax). (Matteo)
 
 - phpdbg:
   ・phpdbg sapiを含むようにした(RFC: https://wiki.php.net/rfc/phpdbg)。
     (Felipe Pena, Joe Watkins and Bob Weinand)
   . Included phpdbg sapi (RFC: https://wiki.php.net/rfc/phpdbg).
     (Felipe Pena, Joe Watkins and Bob Weinand)
 
 - pgsql:
   . pg_version()関数がPQparameterStatus()に含まれている全てのレポートを返すようにした。 (Yasuo)
   . pg_version() returns full report which obtained by PQparameterStatus().
     (Yasuo)
   . pg_lo_truncate()関数を追加。 (Yasuo)
   . Added pg_lo_truncate(). (Yasuo)
   . PostresSQL9.3以降での64bitラージオブジェクトのサポートを追加。 (Yasuo)
   . Added 64bit large object support for PostgreSQL 9.3 and later. (Yasuo)
 
 - Session:
   . バグ#65315を修正(session.hash_functionのデフォルトが密かにmd5になる)。
     (Yasuo)
   . Fixed Bug #65315 (session.hash_function silently fallback to default md5)
     (Yasuo)
   . 機能リクエスト#54649を実装(session_serializer_name()関数を作成)。 (Yasuo)
   . Implemented Request #54649 (Create session_serializer_name()). (Yasuo)
   . 機能リクエスト#17860を実装(Session write short circuit)。 (Yasuo)
   . Implemented Request #17860 (Session write short circuit). (Yasuo)
   . 機能リクエスト#20421を実装(session_abort()関数とsession_reset()関数の追加)。 (Yasuo)
   . Implemented Request #20421 (session_abort() and session_reset() function).
     (Yasuo)
   . 機能リクエスト#11100を実装(session_gc()関数の追加)。 (Yasuo)
   . Implemented Request #11100 (session_gc() function). (Yasuo)
 
 - Standard:
   . 機能リクエスト#65634を実装(プロトコルバージョン1.1のHTTPラッパーがとても遅い)。 (Adam)
   . Implemented FR #65634 (HTTP wrapper is very slow with protocol_version
     1.1). (Adam)
   . saltがない場合のcrypt()関数の挙動を、RFCに従って変更。 (Yasuo)
     https://wiki.php.net/rfc/crypt_function_salt
   . Implemented Change crypt() behavior w/o salt RFC. (Yasuo)
     https://wiki.php.net/rfc/crypt_function_salt
   . 機能リクエスト#49824を実装(array_fill()関数が空の配列を作れるように変更)。 (Nikita)
   . Implemented request #49824 (Change array_fill() to allow creating empty
     array). (Nikita)
 
 - XMLReader:
   . #55285バグを修正。 (XMLReader::getAttribute/No/Ns methods inconsistency). 
     (Mike)
   . Fixed bug #55285 (XMLReader::getAttribute/No/Ns methods inconsistency). 
     (Mike)
 
 - Zip:
   . libzipをバージョン1.11.2にアップデート。
     PHPはilibzipのプライベートなシンボルを使わなくなった。 (Pierre, Remi)
   . update libzip to version 1.11.2.
     PHP don't use any ilibzip private symbol anymore.  (Pierre, Remi)
   . ZipArchive::setPassword($password)という新しいメソッドの追加。 (Pierre)
   . new method ZipArchive::setPassword($password). (Pierre)
   . システムのlibzipでビルとする際に、--with-libzipオプションを追加。(Remi)
   . add --with-libzip option to build with system libzip. (Remi)
   . 新しいメソッド:
     ZipArchive::setExternalAttributesName($name, $opsys, $attr [, $flags])
     ZipArchive::setExternalAttributesIndex($idx, $opsys, $attr [, $flags])
     ZipArchive::getExternalAttributesName($name,  &$opsys,  &$attr [, $flags])
     ZipArchive::getExternalAttributesIndex($idx,  &$opsys,  &$attr [, $flags])
   . new methods:
     ZipArchive::setExternalAttributesName($name, $opsys, $attr [, $flags])
     ZipArchive::setExternalAttributesIndex($idx, $opsys, $attr [, $flags])
     ZipArchive::getExternalAttributesName($name,  &$opsys,  &$attr [, $flags])
     ZipArchive::getExternalAttributesIndex($idx,  &$opsys,  &$attr [, $flags])


番号が書かれているバグや機能リクエストの詳細は、http://bugs.php.netを参照して下さい。

終わりに



PHP5.6では、5.4のtraitや5.5のジェネレータ・コルーチンのような言語としての派手な新機能はありませんでしたが、PHPをより洗練するための着実な改善が見られます。

5.5でOPCacheモジュールが標準で含まれるようになったのに続き、5.6ではデバッグを行なうためのphpdbgが標準で組み込まれるようになりました。また、文法面でも可変長引数や定数計算を扱うための文法が追加されました。

PHP5.6の正式リリースが楽しみですね。