Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
4
Help us understand the problem. What is going on with this article?
@SuguruOoki

PHP 5.6.xから7.0.xに移行におけるコード修正

More than 3 years have passed since last update.

まだ途中なので随時更新します。

概要

最近バージョンが別のものを扱うことが多いため、バージョンによっての変更点などをまとめようと思い至った。詳しい変更点などは公式のドキュメントに任せることとしてコードベースでどのような点を直したら良いかをまとめる。ただし、「動作を変わらないように動かす」という点に重きを置いているため、ベストプラクティスではないことも多いことに注意。

もし良い方法をお持ちの方はご教授お願いしますm(_ _)m

対象

  • 現在PHP5.6以前でコードを書いている方

動かなくなるコードを今までと同じように動作させる

その1 「$$」 => 「global は単純な変数だけを受け付ける」

今まで動いていた「$$変数」が動かなくなるので以下のように変更する。
また、この使い方は5.6でも使えるのでもし5.6.xをまだ使っている方がいれば、先に変更しておくとのちの移行で捗ると思われる。

index.php
<?php
function f() {
    // PHP 5 でしか使えません
    global $$foo->bar;

    // PHP 5 と PHP 7 の両方で使えます
    global ${$foo->bar};
}
?>

一般論として、単純な変数以外を global で使うことは推奨しません。

変更点その2 「set_exception_handler」

set_exception_handler() で登録した例外ハンドラの実装で Exception 型を宣言している場合は、 Error オブジェクトがスローされると fatal エラーが発生

error.php
<?php
// PHP 5 でのこの実装は、そのままでは PHP 7 では動きません
function handler(Exception $e) { ... }
set_exception_handler('handler');

// PHP 5 と 7 の両方で動く
function handler($e) { ... }

// PHP 7 でだけ動く
function handler(Throwable $e) { ... }
?>

その3 「global は単純な変数だけを受け付ける」

global_variable.php
<?php
function f() {
    // PHP 5 でしか使えない
    global $$foo->bar;

    // PHP 5 と PHP 7 の両方で使える
    global ${$foo->bar};
}
?>

動くけれど、落とし穴になりそうな点

その1 「list()の挙動変更」

list() での変数の代入が、逆順ではなくなる
これは今までとは違う挙動になるので注意が必要。
listを使っていた場合にはそこの挙動をチェックして影響の確認が必要。

list.php
<?php
list($a[], $a[], $a[]) = [1, 2, 3];
var_dump($a);
?>
PHP5の出力
array(3) {
  [0] => int(3)
  [1] => int(2)
  [2] => int(1)
}
PHP7の出力
array(3) {
  [0] => int(1)
  [1] => int(2)
  [2] => int(3)
}

一般論として、 list() での代入がどの順で行われるかに依存するコードは書かないことを推奨します。 代入の順番は、実装の都合によって今後も変わる可能性があるからです。

と公式ドキュメントには書かれているため、listの順番に関わるコードを書いていてそれを置き換える際には、とりあえず動かしたいなら、sortあたりでよしなにしてあげると良いかもしれない。(冗長になりそう)

その2 「空の list() の廃止」

今まではできていた空のlistでの定義ができなくなった。
よって、以下のようなコードはphp7では動かない。

empty_list.php
<?php
list() = $a;
list(,,) = $a;
list($x, list(), $y) = $a;
?>

もし上記のようなlistがあれば、空のlistではない初期化を利用する。

その3 「list() は文字列を展開しない」

PHP7からはlist() が文字列変数を展開しない。 また、以下では参照わたしも使っているが、これも注意が必要な模様。

str_list.php
<?php
list($bar) = "abcde";
var_dump($bar); // NULL
?>

PHP7から動かすにはstr_split(文字列を配列にする) を使うと良い。公式でもその方法を推奨している模様。

fix_str_list.php
<?php

$str = "abcde";

$arr1 = str_split($str);
$arr2 = str_split($str, 3);

print_r($arr1);
print_r($arr2);

?>
Array
(
    [0] => H
    [1] => e
    [2] => l
    [3] => l
    [4] => o
    [5] =>
    [6] => F
    [7] => r
    [8] => i
    [9] => e
    [10] => n
    [11] => d
)

Array
(
    [0] => Hel
    [1] => lo
    [2] => Fri
    [3] => end
)

注意点

str_split() でのマルチバイト文字列の扱いは、文字単位ではなくバイト単位での分割となる

参照による代入で自動的に作成した配列要素の並び順の変更

list.php
<?php
$array = [];
$array["a"] =& $array["b"];
$array["b"] = 1;
var_dump($array);
?>
PHP5
array(2) {
  ["b"] => &int(1)
  ["a"] => &int(1)
}
PHP7
array(2) {
  ["a"] => &int(1)
  ["b"] => &int(1)
}
fix_str_list.php
<?php
$array = [];
$array["a"] =& $array["b"];
$array["b"] = 1;
var_dump($array);
?>
4
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
SuguruOoki
現在は、TechBowlで主にフロントエンドを描いてる人。 以前は、バックエンドの開発と、データ分析をやっていた。
techtrain
プロのエンジニアを目指すU30(30歳以下)の方に現役エンジニアにメンタリングもらえるコミュニティです。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
4
Help us understand the problem. What is going on with this article?