謎の演算子
PHPへのオペレータ追加続き
$ php -r '$users ||= "john"; echo $users[0];' john
おお!!!!!!
var_dumpで確認
$ php -r '$users ||= "john"; var_dump($users); ' array(1) { [0]=> &string(4) "john" }
え。文字列リテラルへの参照ってなに!?
数値を…
$ php -r '$users ||= 20070602; var_dump($users); ' array(1) { [0]=> &int(20070602) }
え?え??
動作確認用のスクリプトを作成。wktk
push.php
<?php $arr = array(); for ($i = 0; $i < 5; $i++) { $arr ||= $i; } var_dump($arr); $i = 100; // 書き換えてみる var_dump($arr); ?>
出力
$ php push.php array(5) { [0]=> int(5) [1]=> int(5) [2]=> int(5) [3]=> int(5) [4]=> int(5) } array(5) { [0]=> int(100) [1]=> int(100) [2]=> int(100) [3]=> int(100) [4]=> int(100) }
名付けてリファレンスプッシュ演算子。
- $users[] = 'john';
- $users ||= 'john';
を比較した場合、の存在が大きな違いになってくる。の存在が$usersを配列と解釈して処理を実行していってくれるのですが、が無いということで、||=演算子側で左辺値$usersにがあるように見せるような実装をしなきゃいけない。
最初はガンガンと、opcodeを読んでゴチャゴチャ実装してたのですが、segmentation faultやら見たこと無いようなエラーが沢山出るので、一旦リセット。
考えをシンプルにして、左辺値をconvert_to_array_ex()で配列に変換し、右辺値をadd_next_index_zval()で突っ込んでみたら、上記の参照状態での挿入になりました。
いやぁ、奥が深い。まだまだわからないことだらけです。いろいろと勉強になりますね。
実装コードはまとまればそのうち…。
$users[] ||= 'john'で配列に代入!みたいな既存のルールに沿うような演算子なら結構簡単に作れるかもしれないです。
あ。あとこんな感じに離して書けるんですね。しらなかった。
$users []= 'john';