new takyam();

Qiitaぽい話はQiitaに書いていくことにする気がする http://qiita.com/takyam

PHP5.5の変更点を見る

そういえばPHP5.5が来てたので(随分前にね)、今更ながら変更点を追っかけてみる。

追っかけるっていっても、バージョンアップの度に公式ドキュメントに変更点が書いてあるのでそれを見るだけ。

PHP 5.4.x から PHP 5.5.x への移行
http://php.net/manual/ja/migration55.php

まだalpha版なのでphpbrewにも入ってないからソースビルド必須。ダウンロードは以下から。

http://downloads.php.net/dsp/

何も考えずにCentで ./configure からの make && make install でインストールできちゃったよ。

下位互換性

見る時に、まず注意してみるのが、下位互換性の無い変更点。

下位互換性のない変更点
http://php.net/manual/ja/migration55.incompatible.php

  • Windows XP および 2003 のサポートの終了
  • 大文字小文字を区別しない比較がロケールごとに変わる
  • PHP ロゴの GUID の削除
  • 内部的な実行方法の変更

特に影響は無さそうな感じです。
もしかすると「内部的な実行方法の変更」で使えなくなるPECLライブラリが出てくるかもしれませんが。

新機能

次に読むべきは新機能のページ。

新機能
http://php.net/manual/ja/migration55.new-features.php

  • ジェネレータの追加
  • finally キーワードの追加
  • foreach が list() に対応
  • empty() が任意の式に対応
  • array リテラルと string リテラルのデリファレンス
  • 新しいパスワードハッシュ API
  • Apache 2.4 ハンドラが Windows に対応

ここはじっくり見て行きましょう。まずは簡単なところから。

finally キーワードの追加

というか今までfinallyってなかったんだっけ?ってくらい当たり前にありそうだったものが、ようやく実装された、という感じでしょうか。

try{}の中でfopen()とかしたものを、finally{}の中でfclose()するとかが、一般的な利用用途でしょうか。

PHP 5.5 以降では、catch ブロックの後に finally ブロックも指定できるようになりました。 finally ブロックの何かに書いたコードは、 try および catch ブロックの後で常に実行されます。 例外がスローさされたかどうかには関係ありません。 finally ブロックを実行してから、通常の処理を続行します。

http://php.net/manual/ja/language.exceptions.php

というわけで、一般的な言語と同じようにtry/catchが終わったあとにfinally{}の中身が実行されるようです。

foreach が list() に対応

サンプルコードを見た方が早いですね。

<?php
// http://php.net/manual/ja/migration55.new-features.php
$array = [
    [1, 2],
    [3, 4],
];

foreach ($array as list($a, $b)) {
    echo "A: $a; B: $b\n";
}
?>

foreach()が機能的になる事で、foreach(){}の先頭で変数展開させてたようなパターンが大分楽に書けるようになりますね。特にこれによって新しくできることがあるわけではありませんが、こういう書くのが微妙に楽になる変更は嬉しいです。

array リテラルと string リテラルのデリファレンス

出来る事で不都合は無さそうだけど、利用用途が不明です・・・。

empty() が任意の式に対応

そういえば渡せなかったよなー、微妙に不便、というか大昔にコレでハマった記憶があって、そういう意味では嬉しい改修です。

新しいパスワードハッシュ API

password_hash関数が新しく追加されたよーとの事。

より簡単にパスワードをハッシュしたり管理したりできるようになりました。

とのことではありますが、hash()関数の何が難しいのかよくわかりません。。。 しかも、password_hash関数は、以下のような引数になっており

string password_hash ( string $password , integer $algo [, array $options ] )

第2引数の「$algo」は定数を渡すようになっていまして、その定数は以下のとおり

PASSWORD_BCRYPT (integer)
PASSWORD_BCRYPT を使うと、 CRYPT_BLOWFISH アルゴリズムで新たなパスワードハッシュを作ります。
PASSWORD_DEFAULT (integer)
アルゴリズムを指定しなかったときのデフォルトとして使うアルゴリズム。 PHP のバージョンが上がるときに、 その時点でより強力なハッシュアルゴリズムに対応していればデフォルトが変わる可能性があります。

http://php.net/manual/ja/password.constants.php

ハッシュアルゴリズムのデフォルトが変わっちゃうと、それまでのサービスと互換性取れなくなるんじゃなかろうか・・・、とかなり心配になっちゃいますので、できれば PASSWORD_DEFAULT をそのまま利用するのは避けたほうがいいのかもしれません。

きっとそのへんちゃんと考えてアップデートしてくれるよ!って言い切れないよねー(^ρ^)

現在は定数として、DEFAULT と BCRYPT が用意されてるので、DEFAULT === BCRYPT なのかな?と思って調べてみました。

<?php
$password = 'password_sample';

echo 'PASSWORD_DEFAULT' . PHP_EOL;
echo password_hash( $password , PASSWORD_DEFAULT ) . PHP_EOL;

echo 'PASSWORD_BCRYPT' . PHP_EOL;
echo password_hash( $password , PASSWORD_BCRYPT ) . PHP_EOL;

出力結果は、

PASSWORD_DEFAULT
$2y$10$EQMoyrL4BULhW2Mv/ZS4teO6hyrAaU2hEouBQwmdPWRlUdjWnrnde
PASSWORD_BCRYPT
$2y$10$e/hvNEa4qUzXdTPtVBssMee.8jgxMjAg42CNNjcROFB3WZUTB96Ea

という感じなので、DEFAULTとBCRYPTは別物のようですね。

んじゃDEFAULTって何なのだろう・・・。

ジェネレータの追加

Rubyではおなじみのyieldが使えるようになりました。
何者なのか、理解するまでは気持ち悪い機能でもありますので、
以下のスライドで理解を深める事をオススメします。

PHP5.5新機能「ジェネレータ」初心者入門
http://www.slideshare.net/kwatch/php55

PHPの情報はまだまだ少ないので、「Ruby yield」とかで検索すると、有益な情報がいろいろ拾えるとおもいますよ。

新機能はこれくらいでしょうかね。

新しい関数、クラス、インターフェース、メソッド

毎回標準ライブラリなんだったりで、結構な量の新しい関数等が追加されます。

新しい関数
http://php.net/manual/ja/migration55.new-functions.php

新しいクラスやインターフェイス
http://php.net/manual/ja/migration55.classes.php

新しいメソッド
http://php.net/manual/ja/migration55.new-methods.php

とはいえ、ライブラリ開発とかじゃない通常のWEBアプリケーション開発で使いそうなのは、boolval()関数くらいでしょうか。

boolval()
http://php.net/manual/ja/function.boolval.php

strval()やintval()と同じように、booleanに変換してくれる関数のようです。
これまでも、(boolean)キャストはできましたので、一応後付で関数化してくれた、という感じでしょうか。

0: false
42: true
0.0: false
4.2: true
"": false
"string": true
[1, 2]: true
[]: false
stdClass: true

判断基準は、 == や empty() などと同じようですね。

新しいグローバル定数

MySQLi
MYSQLI_SERVER_PUBLIC_KEY オプションが追加されました。 mysqli_options() で使えます。
http://php.net/manual/ja/migration55.global-constants.php

MySQL5.5だか5.6だかで使えるようになった公開鍵認証方式に対応するためのやつでしょうか?

鍵までのパスを指定するのか、文字列を指定するのかわかりませんが。。。

そもそもMySQL側の認証をどうやって設定刷るのかわからないので、そのうち調べてみたいですね。

その他

他にもいくつかあるようですが、特に普段使わなそうなのでザッと目を通しておくくらいで良いとおもいます。

関係あるとしたらpreg_replace() の /e が非推奨になったことくらいでしょうか?

PHP 5.5.x で推奨されなくなる機能
http://php.net/manual/ja/migration55.deprecated.php

変更された関数
http://php.net/manual/ja/migration55.changed-functions.php

その他の拡張モジュールに対する変更
http://php.net/manual/ja/migration55.extensions-other.php

INI ファイルの扱いに関する変更
http://php.net/manual/ja/migration55.ini.php

まとめ

5.3 → 5.4ほどのインパクトは無いですが、finally, empyt(), foreach(list()), boolval() と、細かいところで使い勝手がよくなってるので、5.4を使ってる人は5.5になったタイミングで移行してみても良いのではないでしょうか?

と、思うと同時に、アップデートするメリットもあんまりなさそうなので、安定するとか、5.4がサポートされなくなる、とか、そういった理由がなければアップデートする必要もないな、と思いましたw