続、ごあいさつ
こんにちは!石川です。開発本部カードバトル推進委員名誉会長石川です。
MTGではテーロスブロックの新しいエキスパンション「神々の軍勢」が発売されました。
MagicOnlineでドラフトを何回かしましたが、敗北に敗北を重ね、大量の金を失いました。
ウィザード社に貢献しているんだと言い聞かせることで精神を保っています。
PHP5.5…
前回の記事から相当な時間が空いてしまいました。どれくらいかというと、既にPHP5.6.0alpha1がリリースされてしまったぐらいですw
PHP5.6の新機能について記事を書いている人もちらほらといる中、空気を読まずに前回同様、
新機能?を実際にコードを動かしながら確認していこうと思います。
foreach が list() に対応
foreach で list() を使って、 ネストした配列を個別の変数に展開できるようになりました。
前回の記事で比較的目玉の機能を紹介してしまった為いきなり地味です笑
早速書いてみます。
1 2 3 4 5 6 7 8 |
$array = [ ['foo', 'FOO'], ['bar', 'BAR'], ]; foreach ($array as list($a, $b)) { echo "A: $a; B: $b\n"; } |
処理結果
A: foo; B: FOO
A: bar; B: BAR
これまでは下の様に書いていました。
1 2 3 4 5 6 7 |
//foreach ($array as list($a, $b)) { // echo "A: $a; B: $b\n"; //} foreach ($array as $childArray) { list($a, $b) = $childArray; echo "A: $a; B: $b\n"; } |
こうして比べてみると楽に書ける様になっているのがわかりますね。
地味ではありますが、こういう奇麗なコーディングが出来る様になる改善が行われるのは良いことですよね。
無理やり活路を見出してみる
前回記事のGeneratorと組み合わせてみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
function readCSVGenerator($filename) { $f = fopen($filename, 'r'); try { $line = fgets($f); while ($line !== false) { yield explode(',', rtrim($line)); // 一行毎に配列にして返却する(rtrimで行末の改行を潰してます) $line = fgets($f); } } finally { fclose($f); } } $gen = readCSVGenerator('test.csv'); foreach ($gen as list($number, $alpha)) { echo "Number: $number; Alpha: $alpha\n"; }; |
処理結果
Number: ‘0’; Alpha: ‘ぜろ’
Number: ‘1’; Alpha: ‘いち’
Number: ‘2’; Alpha: ‘に’
やってることは何も変わらないのですが、関数と組み合わせてみました。
1.Generatorによって処理が汎用化されている
2.使う側がどういう配列が生成されるか知っている
こんな場合に利用すると良いと思います。
上記処理ではechoするだけなのであまり有用では無いですが、そこはツッコミなしで。
empty() が任意の式に対応
変数だけでなく、任意の式を empty() に渡せるようになりました。
issetだのemptyだのis_nullだのphpのこのテの式って混乱しがちじゃないですか?
何渡すとtrueだのfalseだの関数が渡せるだの渡せないだの。
チームで開発する際にはこの辺のポリシーが統一されていないと悲しい事件が起こりがちです。
とりあえず書いてみる
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
function returnUndefined() { } function returnNull() { return null; } function returnEmpty() { return ''; } function return0() { return 0; } function return1() { return 1; } echo "undefined: " . var_export(empty(returnUndefined()), true) . "\n"; echo "null: " . var_export(empty(returnNull()), true) . "\n"; echo "empty: " . var_export(empty(returnEmpty()), true) . "\n"; echo "0: " . var_export(empty(return0()), true) . "\n"; echo "1: " . var_export(empty(return1()), true) . "\n"; |
処理結果
undefined: true
null: true
empty: true
0: true
1: false
こんな感じですね。関数が渡せる様になっています。
混乱しがちな空文字とかNULLとか0とかについては以前塚原さんが検証した記事があるのでそちらを読んでみてください。
で、他のはどうなってんのよ?
そもそも昔どうだったっけ?ってのを全く覚えていないので比較してみました。
それぞれ関数を渡した時の挙動です。
バージョン | empty | isset | is_null |
---|---|---|---|
5.4 | Fatal error | Fatal error | ○ |
5.5 | ○ | Fatal error | ○ |
issetはFatal Errorのままです。
emptyやis_nullは値に対する検査で、issetは変数そのものに対する検査だからでしょう。
ただ、同じFatal Errorでもメッセージは変わっていました。
バージョン | Fatal Error Message |
---|---|
5.4 | Can’t use function return value in write context in … |
5.5 | Cannot use isset() on the result of a function call (you can use “null !== func()” instead) in … |
親切になってますw
こういう目に見えないところもサポートが厚くなっているのを見てちょっと感動しました。
array リテラルと string リテラルのデリファレンス
Array と string をデリファレンスして、 個々の要素や文字に直接アクセスできるようになりました。
まぁ書いてみるか
1 2 3 4 5 6 7 |
echo 'Array dereferencing: '; echo [1, 2, 3][0]; echo "\n"; echo 'String dereferencing: '; echo 'PHP'[0]; echo "\n"; |
処理結果
Array dereferencing: 1
String dereferencing: P
これを最初見た時は誰得?と思いましたが、RFCによると、言語仕様の一貫性を保つための改善、ということらしいです。
どこの言語もそうかもしれないですが、PHPは特に言語仕様の統一には相当苦労してるんだろうなぁと勝手に思っています。
::class によるクラス名の解決
ClassName::class で、 ClassName クラスの完全修飾名を取得できるようになりました。
1 2 3 4 5 6 |
namespace Name\Space; class ClassName {} echo ClassName::class; echo "\n"; |
処理結果
Name\Space\ClassName
はい。
このテの機能追加は、特にフレームワークを作る時なんかに嬉しいかもしれませんね。
普通に開発するぶんには使用する機会はほとんど無いでしょう。
OPcache 拡張モジュールの追加
Zend Optimiser+ のオペコードキャッシュ機能が、 OPcache 拡張モジュール としてPHP に追加されました。 OPcache は、PHP のパフォーマンスを向上させるために、 事前にコンパイル済みのスクリプトのバイトコードを共有メモリに格納します。 その結果、PHP がリクエストのたびにスクリプトの読み込みやパースをする必要がなくなります。
これ検証とかするとなるとそれだけで記事使いそうなので割愛します(汗
ものすごくわかりやすいスライドをhnwさんがUPしているのでそちらを読んでください。
Zend OPcacheの速さの秘密を探る。
よくわかりました。感謝です。
foreach が非スカラーのキーに対応
ClassName::class で、 ClassName クラスの完全修飾名を取得できるようになりました。 次の例を参照ください。
これも全く使い方が思いつかなかったんですが、RFCによると、これまでforeachのキーがstringとintしか対応してなくて、それ以外の場合に煩雑な書き方しなきゃならんかったから、素直に書けるようにしたよ!とのこと。
今まではこう書いてた
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
$iterNumber = new ArrayIterator( array( 'zero', 'one', 'two' ) ); // 配列をイテレータにする $iterHiragana = new ArrayIterator( array( 'a' => 'あ', 'i' => 'い', 'u' => 'う' ) ); $multiIter = new MultipleIterator( MultipleIterator::MIT_KEYS_ASSOC ); // 連想配列のキーをイテレータごとに指定する $multiIter->attachIterator($iterNumber, 'number'); // numberというキーでイテレータを取得できる様に設定する $multiIter->attachIterator($iterHiragana, 'hiragana'); // hiraganaというキーでイテレータを取得できる様に設定する // MultipleIterator(MultipleIterator::MIT_KEYS_ASSOC)をforeachで回すと以下の形式で処理されます // key: array ( 'number' => 0, 'hiragana' => 'a') // value: array ( 'number' => 'zero', 'hiragana' => 'あ') foreach( $multiIter as $values ) { $keys = $multiIter->key(); // 現在の要素のキーを取得 echo '[number] key=' . $keys['number'] . ' value=' . $values['number'] . "\n"; echo '[hiragana] key=' . $keys['hiragana'] . ' value=' . $values['hiragana'] . "\n"; }; |
PHP5.5ではこう書く
1 2 3 4 |
foreach( $multiIter as $keys => $values ) { echo '[number] key=' . $keys['number'] . ' value=' . $values['number'] . "\n"; echo '[hiragana] key=' . $keys['hiragana'] . ' value=' . $values['hiragana'] . "\n"; }; |
処理結果
[number] key=0 value=zero
[hiragana] key=a value=あ
[number] key=1 value=one
[hiragana] key=i value=い
[number] key=2 value=two
[hiragana] key=u value=う
この例で登場するMutlipleIteratorの存在自体を知らなかったんですが、どうやら複数ファイルを同時に読み込んでいく時とかに使うらしいです。
「なんでこの書き方で動かねーんだよ!」という思いを抱かなくてすむ様になったのは良いことですね。
Apache 2.4 ハンドラが Windows に対応
Apache 2.4 ハンドラ SAPI が Windows に対応するようになりました。
Windows使ってないので省略
GD の改良
GD 拡張モジュールに、さまざまな改良が加えられました。
GD使ってな(ry
まとめ
ということで、PHP5.5の新機能についてほとんど検証できました。
後半戦は地味になってしまいましたが、矛盾の解消や書きやすく読みやすいコードになる様なサポートの追加など、地道な進化を着実に行っていることが伺えますね。
検証が終わったところで、冒頭でも述べた様に既にPHP5.6のアルファ版がリリースされてるので次回はPHP5.6に触れてみようかなぁと思っています。
ここまでお読み頂き、ありがとうございました!m(_ _)m
アライドアーキテクツでVPoPをしています。おもにダイエットに関する話を書きます。たまにサービス開発において大事だと思っていることを書いたりします。