php5.6 symfony2.3からphp7 symfony2.8にVer UPしようとして出来なかった話（symfonyは出来た）

[Symfony Advent Calendar 2015](http://qiita.com/advent-calendar/2015/symfony)の21日目の記事です。
昨日は[qcmnagai](http://qiita.com/qcmnagai)さんの[Prezto用Symfonyモジュールを作成してみる](http://tech.quartetcom.co.jp/2015/12/21/prezto-symfony-module/)でした。
* * *

# はじめに

現在メインで関わっているプロダクトはcentos6.7 & php5.6(最近5.4から上げた) & symfony2.3で動いています。
symfony2.3はLTSですが2016年5月でbug fixes supportが終わってしまいます[^1]。（とは言ってもsecurity fixesは2017年5月までですが）
またphp7はどうやらかなり速いらしいです。[^2]

symfony2.3自体はphp7に対応している[^3]ので、
どうせならどっちも一気に上げてみてテストコストを削減しようという甘い考えでやってみました（そして、挫折しました）。

# php5.6 => php7
以下のyum reposirtoryを追加することphp7自体は簡単にCentOSに入ります。
https://webtatic.com/packages/php70/

まずは既存のphp関係を全削除してすっきりした気持ちになります。
`sudo yum remove php*`

rpmを入れます[^4]
`rpm -Uvh https://mirror.webtatic.com/yum/el6/latest.rpm`

php7とphp5.6時代に使用していたextensionを入れます[^4]
`yum install php70w php70w-opcache php70w-devel php70w-mbstring php70w-mcrypt php70w-pecl-xdebug php70w-gd php70w-pear php70w-pdo php70w-mysql php70w-intl`

## peclとの戦い
ここまでは予想通りすんなりといけました。パッケージマネージャー万歳です。
ここからはpeclで入れるextensionです。
peclさんは一発で予定通りに動いてくれたことがないです。

### 1. APCu
すでにphp7に対応した5.1.2がリリースされています。
https://pecl.php.net/package-info.php?package=APCu&version=5.1.2

ということで
`pecl install apcu-beta`
すんなり入りました[^4]。

### 2. SSH2
前回うまくいったからといって安易に
`pecl install ssh2`
すると
`pecl/ssh2 requires PHP (version >= 4.0.0, version <= 6.0.0), installed version is 7.0.0RC4`

そうこなくっちゃ、という感じですね。
ところがこれに関しても下記の記事に丁寧に手順がまとまっていて、
その通りにすれば何の苦もなく入ります。

https://medium.com/php-7-tutorial/solution-how-to-compile-php7-with-ssh2-f23de4e9c319#.5obtit4xh

訓練されたPHPerの皆さんはもう慣れっこでしょうが、私のような新米PHPerは最後にphp.ini記述を加えるのをよく忘れます。
`extension=ssh2.so`

### 3. mongo => mongodb

ここまであまりにも順調で拍子抜けしていた私。
しかしmongoは一筋縄ではいきませんでした。

php7から一部のlegacyなextensionがサポートされなくなりました。
その中にpecl/mongoが含まれます。

今後はmongodbにお世話になることになります[^5]。

しかし、2015/12/21の段階ではmongodbもphp7対応がstableになっていません。
https://github.com/mongodb/mongo-php-driver/issues/171

git hubにPHP7というブランチが上がっているのでgit cloneしてきたものをbuildしてみます。

手順はREAD MEにしっかりとまとまっています。
https://github.com/mongodb/mongo-php-driver/tree/PHP7#installation

が、makeが通らない。
どうやらCentOSのデフォルトのgccが古いのが原因らしいので（これだからCentOSは…）
下記リンク先を参考に新し目のgccを有効にします。

http://abyssluke.hatenablog.com/entry/2014/07/07/202702

気をつけなきゃいけないのは
`scl enable devtoolset-2 bash`
はbashのセッション（って言い方であってますかね？だいたい≒タブだと思います）ごとにしか効きません。
`extension=mongodb.so`も忘れずに。

意外とすんなり行ったという印象です。（が、それが思い上がりであったと知るのに時間はかかりませんでした。）


## 画面が表示できない

`FatalErrorException: Error: Uncaught TypeError: Argument 1 passed to Symfony\Component\Debug\ExceptionHandler::handle() must be an instance of Exception, instance of Error given in hoge/vendor/symfony/symfony/src/Symfony/Component/Debug/ExceptionHandler.php:67
`

調べるとcomposer install忘れているとのこと。
http://stackoverflow.com/questions/13237755/symfony-2-app-dev-php-error

うん？と思いながらもcomposer installしてみるとext-mongoがないと怒られます。

ext-mongoはmongodbに変わったはず...、まさか。

そう、doctrine/mongodb-odmはmongodbに未対応（必然的にphp7にも未対応）なのでした。
https://github.com/doctrine/mongodb-odm/issues/1234

issue自体はここに上がっていたりします。
https://github.com/doctrine/mongodb-odm/issues/1292

現在のプロジェクトからdoctrineのmongoORマッパーへの依存を取り除くのは、
もはや検証どころではない時間がかかります。

こうしてphp7、symfony2.8の夢は一旦お預けとなったのでした。

# symofony2.3 => symofony2.8
難しいことを考えずにcomposer.jsonの
`"symfony/symfony": "2.3.*",`
を
`"symfony/symfony": "2.8.*",`
に書き換えるだけで、composer updateが通りました。

最初symfony2.8のcomposer.jsonの記述をできるだけ真似ようとしたのですが、これは失敗でした。

もし、twig関連でエラーが出たらapp/config/config.ymlを下記のように書き換えればおさまります。

http://stackoverflow.com/questions/33843765/symfony-2-servicenotfoundexception-non-existent-service-templating-engine-php

profilerを開くとdeprecatedの警告が大量に出ていますが、
流石はsymfonyこの程度のVer UPは簡単に動きます。

# まとめ
mongo使いはまだphp7にあげてはいけない。ダメ絶対。

わりとノリと勢いで書いたので、ツッコミどころがありましたら柔らかめのまさかりを投げていただけると幸いです。
最後まで読んでくださった方、お付き合いいただきありがとうございました。

* * *
明日は[ochi51](http://qiita.com/ochi51)さんの「CybozuHttpBundleについて」です。

[^1]: http://symfony.com/roadmap?version=2.3#checker
[^2]: http://www.slideshare.net/hnw/php7
[^3]: http://symfony.com/blog/symfony-achieves-100-php7-compatibility
[^4]: 私の環境ではroot権限が必要でした。
[^5]: https://docs.mongodb.org/ecosystem/drivers/php/#mongodb-compatibility