技術・開発

【PHP 5.4】Fatal error: Call-time pass-by-reference has been removed の原因と対応方法

2013年4月23日

PHP 5.4環境で古いスクリプトを動かそうとした際、以下のようなエラーに遭遇したので備忘録としてメモしておきます。

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

原因:関数呼び出し時の「参照渡し(&)」が廃止された

エラーメッセージの通り、PHP 5.4以降では「Call-time pass-by-reference(関数呼び出しの際に参照渡しを行う機能)」が完全に廃止されました。

PHP 5.3以前は、関数を呼び出す際に引数に & をつけること(例:test(&$a);)が許容されていましたが、PHP 5.4からはこれが非推奨ではなく「Fatal error(致命的なエラー)」として扱われるようになっています。

対処方法:呼び出し側の「&」を削除する

エラーを解消するには、関数を呼び出している側の & を削除するだけでOKです。

「えっ、それだと参照渡しじゃなくて値渡しになっちゃうのでは?」と思うかもしれませんが、ご安心ください。関数を定義している側(function test(&$a, $b))に & が付いていれば、呼び出し側で & をつけなくても、PHP側で自動的に参照渡しとして処理してくれます。

具体的な修正例は以下の通りです。

<?php
/**
 * テストコード
 */
$a = 1;
$b = 2;

// 関数定義側:ここで&$aとなっているので、参照渡しになる
function test(&$a, $b)
{
    return true;
}

// 修正前:呼び出し側に & をつけるとPHP 5.4以降では Fatal error になる
// test(&$a, $b); 

// 修正後:呼び出し側の & を抜くだけでエラー回避&参照渡しとして動作する
test($a, $b); 

このように、呼び出し側の & を抜くだけで正しく動作するようになります。

おまけ(古いプラグインの扱いについて)

今回はWordPressの古いプラグイン「Semisecure Login Reimagined」を動かす際にこのエラーが表示されたため、プラグインのコアファイルを直接上記のように修正して対応しました。

とりあえずこれで動くようにはなりましたが……最終更新が数年前で止まっているような古いプラグインの場合、PHPのバージョンアップに伴う他のセキュリティリスクや不具合が潜んでいる可能性もあります。
根本的な解決としては、最新のPHPに対応している代替プラグインへの乗り換えを検討したほうが良いかもしれませんね。

-技術・開発
-, , , , ,