PHP5.6からPHP7にアップグレードして実際にはまった点9個
仕事で使っているPHPアプリケーションをPHP7 beta1で動かしてみたらそのままでは動きませんでした。 私が実際にはまった点を紹介します。
なお、PHP7の変更点についてはhnwさんの記事に詳しく網羅されているのでご一読ください。
Apacheのモジュール名が変わっていた
ApacheにPHPを組み込むためのモジュール(俗にいうmod_php)のモジュール名・ファイル名が変更になっていました。
LoadModule php5_module modules/libphp5.so
↓
LoadModule php7_module modules/libphp7.so
memcache extensionがインストールできない
PHPからMemcachedを使うためのExtensionには2つあります。
memcacheの方はビルドできませんでした。 一方、memcachedの方は Githubレポジトリのphp7ブランチを使えばビルドできました。
ビルド・インストールするには下記のようにします。
sudo yum install libmemcached-devel
cd /usr/local/src
git clone -b php7 --depth 1 https://github.com/php-memcached-dev/php-memcached
cd php-memcached
phpize
./configure
make
sudo make install
エクステンションをmemcache
からmemcached
に差し替える場合は影響範囲が広くなります。
memcache
のPHP7対応を待つという選択肢もありますが、いつかリリースされるという保証はありません。
imagickがインストールできない
pecl install imagick
などとしても無駄無駄ァでした。
これも、Githubのphpsevenブランチを取得してビルドしたらうまくいきました。
sudo yum install ImageMagick ImageMagick-devel
cd /usr/local/src
git clone -b phpseven --depth 1 https://github.com/mkoppanen/imagick
cd imagick
phpize
./configure
make
sudo make install
IntクラスやStringクラスがエラーに
class Int {}
class String {}
こういうクラス名がエラーになります。
PHP Fatal error: Cannot use 'Int' as class name as it is reserved
PHP Fatal error: Cannot use 'String' as class name as it is reserved
PHP7調査(34)型名と同じクラス名が作れないようになった
preg_replaceのe修飾子の挙動が変わる
- PHP5.5からpreg_replaceのe修飾子はDEPRECATED扱いとなっていたが、一応動いてはいた。
- PHP7では、preg_replaceのe修飾子を使うと、Warningを吐きつつNULLを返す。
- PHP5.5時代にpreg_replaceに@を書いてお茶を濁した人は、PHP7で地雷を踏む。
関数のパラメータで同じ変数名を2回書いたらエラーに
(深遠な理由から)こういう関数を定義していたら、PHP5.6では問題なかったのですが、
function func($void = null, $void = null) {
//$voidは関数内では一切使用しない
}
PHP7だとFatal Errorになりました。
PHP Fatal error: Redefinition of parameter $void in /Users/DQNEO/a.php on line 6
同じ名前の変数をを2回定義できなくなったようです。 下記のようにして回避しました。
function func($void1 = null, $void2 = null) {
}
クラス名と同名のコンストラクタが非推奨に
こういうやつがDEPRECATEDになります。
class Pager
{
function Pager(){}
}
PHP Deprecated: Methods with the same name as their class will not be constructors in a future version of PHP; Pager has a deprecated constructor
PEAR系ライブラリのようにPHP4時代に作られたライブラリが軒並みこれに該当します。
class Pager
{
- function Pager($options = array())
+ function __construct($options = array())
pg_field_type関数が激遅になっていた。
pg_field_typeというのは、PHPからPostgreSQLを使うときに、クエリの結果セットからカラムのデータ型を調べるときに使います。ORマッパの内部で使われていたりします。(INSERTする直前に対象テーブルの全カラムのデータ型を調べる等)
これはおそらくパフォーマンス劣化バグだと思われるので、正式版リリースまでに修正されることを待ちましょう。
もしくは、PHP本家にPull Requestを送るチャンスかもしれません・・・!
OSXで–with-pgsqlをつけるとコンパイルエラー
OSX(yosemite)で ./configure --with-pgsql
でビルドできませんでした。
undefined symbols for architecture x86_64:
"__emalloc_16", referenced from:
_zif_pg_lo_open in pgsql.o
__php_pgsql_notice_handler in pgsql.o
"__emalloc_24", referenced from:
_zif_pg_query in pgsql.o
_zif_pg_query_params in pgsql.o
_zif_pg_prepare in pgsql.o
_zif_pg_execute in pgsql.o
_zif_pg_get_result in pgsql.o
_zif_pg_insert in pgsql.o
"__emalloc_56", referenced from:
_php_pgsql_fetch_hash in pgsql.o
"_lo_lseek64", referenced from:
_zif_pg_lo_seek in pgsql.o
"_lo_tell64", referenced from:
_zif_pg_lo_tell in pgsql.o
"_lo_truncate64", referenced from:
_zif_pg_lo_truncate in pgsql.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [libs/libphp7.bundle] Error 1
解決方法がわからなかったのでいったん諦めました。 まあ本番はLinuxですしね… (あの葡萄はすっぱい的な)
まとめ
PHP7を導入してはまった点をまとめました。
逆に言うと、たったこれだけ直しただけで問題なく動きました。 メジャーバージョンアップのわりには後方互換はかなり保たれている印象です。
正式版のリリースは2015年10月だそうです。 待ち遠しいですね!
https://wiki.php.net/rfc/php7timeline
PHP++