CYDAS Developer's Blog

サイダス技術者ブログ

PHP5系 から 7系に上がって出来なくなること

こんにちは。技術部の金尾です。
PHPといえば良くも悪くもゆるい書き方を許してくれる大らかな言語ですが、7系以降では お行儀のわるい書き方には(以前よりは)厳しくなりました。
廃止されたものやルールが変わった部分もあるのでまとめておきます。

split関数の廃止

split関数が廃止されました。以降はpreg_splitexplodeを使う必要があります。

<?php
// 呼び出しても undefined
var_dump( split(',', '1,2,3,4') );
//=> Fatal error: Uncaught Error: Call to undefined function split() in ...

// explode などに置き換えましょう。
var_dump( explode(',', '1,2,3, 4' ) );
//=> array(4) {
  [0]=>
  string(1) "1"
  [1]=>
  string(1) "2"
  [2]=>
  string(1) "3"
  [3]=>
  string(2) " 4"
}

E_STRICT 通知の深刻度の変更

PHP7以降から E_STRICT 通知が廃止されました。それに伴い今まで E_STRICT だったものは E_NOTICE E_WARNING E_DEPRECATED のいずれかに変更になります。E_ALL & ~E_STRICT でひとまず非表示にしておく、ということができなくなったのでその場合対応が必要です。
いくつかある変更対象のエラーのなかで、比較的うっかりやりがちな Signature mismatch during inheritanceOnly variables should be passed by reference について取り上げます。

Signature mismatch during inheritance

オーバーライドしたメソッドのシグネチャが継承元と異なる場合、E_WARNING エラーが発生します。

<?php
class Hoge {
    public function method(){
        return 'hoge';
    }
}

class ChildHoge extends Hoge {
    // 親の method とは異なる引数を指定してオーバーライド
    public function method($foo){
        return 'hoge' . $foo;
    }
}
//=> Warning:  Declaration of ChildHoge::method($foo) should be compatible with Hoge::method() in ...

Only variables should be passed by reference

引数に参照渡しを要求している関数にメソッドの戻り値を直接渡すと E_WARNING エラーが発生します。 array_poparray_shiftなどを使用する際には注意が必要です。

<?php
// 関数の戻り値を直接渡しては×
var_dump(array_pop( explode(',', '1,2,3,4') ) );
//=> Notice:  Only variables should be passed by reference in ...

// 一度変数に格納すればok
$hoge = explode(',', '1,2,3,4');
var_dump(array_pop($hoge));
//=> string(1) "4"

変数やプロパティ、メソッドへの間接的なアクセスの扱いの変更

$$foo['bar']$foo->$bar['baz'] といった、
変数やプロパティ、メソッドへの間接的なアクセスを厳密に左から右の順で評価するようになりました.

PHP5 PHP7
$$foo['bar']['baz'] ${$foo['bar']['baz']} ($$foo)['bar']['baz']
$foo->$bar['baz'] $foo->{$bar['baz']} ($foo->$bar)['baz']
$foo->$bar'baz' $foo->{$bar['baz']}() ($foo->$bar)'baz'
Foo::$bar'baz' Foo::{$bar['baz']}() (Foo::$bar)'baz'

このため可変変数や可変メソッドを使用するときには5.x系とは異なる挙動をすることがあります。

<?php
class Foo {
    public function bar(){
        echo "bar";
    }
    public function baz(){
        echo "baz";
    }
}
$arr = ['bar' => 'bar', 'baz' => 'baz'];

// PHP5.x系では $arr['bar'] が先に評価されていたが、
// PHP7.x系では (new Hoge)->$arr が先に評価されるためとエラーになる。
(new Foo)->$arr['bar']();
//=> Notice:  Array to string conversion in ...
//=> Notice: Undefined property: Foo::$Array in ...

// 波括弧を使用して $arr['bar'] を先に評価するよう指定すればok
(new Foo)->{$arr['bar']}();
//=> "bar"

無効な文字列による算術演算の通知

PHP7.1以降、数値形式ではない文字列を使って算術演算を行おうとしたときに E_WARNING あるいは E_NOTICE エラーが発生するようになりました。キャストしてくれることをいいことにうっかり空文字を0として扱ってしまうとバンバン Warning エラーが出ます。

  • E_NOTICE になるケース 数字で始まり、数値以外で終わる文字列のときに発生
    Notice: A non well formed numeric value encountered in ...

  • E_WARNING になるケース 数値が含まれない文字列のときに発生
    Warning: A non-numeric value encountered in ...

<?php
var_dump("0" + 1);
//=> int(1)

var_dump("01" + 1);
//=> int(2)

var_dump("" + 1);
//=> Warning:  A non-numeric value encountered in ...

var_dump("1m" + 1);
//=> Notice:  A non well formed numeric value encountered in ...

var_dump("m1" + 1);
//=> Warning:  A non-numeric value encountered in ...

var_dump("1m" + ""); 
//=> Notice:  A non well formed numeric value encountered in ... 
//=> Warning:  A non-numeric value encountered in ...