PHP5.4.0以降での参照渡しと値渡し。

自宅のテストサーバ環境をアップデートしたらPHPのバージョンが5.5.9になって、大昔に書いたPHPスクリプトが、

Fatal error: Call-time pass-by-reference has been removed

なるエラーを吐いて動かない。

要するに、PHP5.4.0以降では、以前のバージョンで許容されていた「関数を呼ぶときに引数を参照渡しする」という機能が廃止されているわけです。

なので、例えば「配列の一個目の値を書き換える」という、どうでも良い関数を例にすると、

<?php
// 5.3.x 以前ではとりあえず動く。5.4.0 以降ではエラー。

$original = array( 'a' , 'b' , 'c' );

print_r( $original );

kakikae( &$original ); //関数呼び出し

print_r( $original );

function kakikae( $a ){ //関数宣言
  $a[0] = 'A';
}
?>

出力は…

//PHP5.4.0 以降
Fatal error: Call-time pass-by-reference has been removed at line xxx.
//PHP5.3.x 以前。意図した動作。
Array ( [0] => a [1] => b [2] => c ) //関数を通す前
Array ( [0] => A [1] => b [2] => c ) //関数を通した後

これは、こう書かなくてはなりません。

<?php
// 5.3.x 、5.4.0 以降で正しく動作。

$original = array( 'a' , 'b' , 'c' );

print_r( $original );

kakikae( $original ); //関数呼び出し

print_r( $original );

function kakikae( &$a ){ //関数宣言
  $a[0] = 'A';
}
?>

出力は…

//意図した結果。
Array ( [0] => a [1] => b [2] => c ) //関数を通す前
Array ( [0] => A [1] => b [2] => c ) //関数を通した後

値を参照渡しにするかどうかは、関数呼び出し時ではなく、関数宣言時にしなさいよ」ということですね。自分で昔書いたスクリプトはこの辺りを適当にしていたので、ちょっと面倒なことになってしまった。

ちなみに、PHP5.3.x以前では、

kakikae( &$original );//呼び出し
function kakikae( $a ){ /*略*/ } //関数宣言

…という書き方でも、

kakikae( &$original );//呼び出し
function kakikae( &$a ){ /*略*/ } //関数宣言

…でも、

kakikae( $original );//呼び出し
function kakikae( &$a ){ /*略*/ } //関数宣言

…でも、意図した動作をしてくれますね。ユルい。

カテゴリ: