Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ナツへの扉

 ナツへの扉

PHP5.3.3からPHP7.2.6への移行についての知見

takeshi_sengoku

May 31, 2018
Tweet

Other Decks in Technology

Transcript

  1. どんなひと? • 仙石 毅 • PHPでの商売歴は15年ほど • PHP3からの付き合い • 昔はJavaやC#などもやっていました

    • "如何にして人間様を動かさないか"に興味があります • "(初回以降で)ロジックに触れたら負けだと思っている" • 今はサーバサイドチームでこんな事やっています • 機能改修、処理の共通・統合化 • 実装側のセキュリティに関わるあれこれ • コードレビュー、教導 • PHPのバージョンアップ ©︎ 2018 PRECS Inc.
  2. PHPのバージョンアップとは言うが、何をするの? 1. PHPバージョンをなるだけ新しくする 現在のバージョンは5.3.3 計画策定時では5.6.X 最終的に7.2.6 or Upper 2. PHPのバージョンを上げても動くようにする

    PHP5.3.3が全盛、あるいはそれ以前からのコードを多数収録 当然の事ながらWarningでログが肥大化し、Fatalで止まります 兎に角辻褄を合わせる事が肝要 3. 更新後のコードでも現行環境で動くようにする オンプレサーバが200台近くあり、それぞれ別のお客様向けです (お安いプランになると共有サーバとしても振舞う) そのため逐次更新が必要となります 結果、数週間の間PHP7とPHP5の実行系が平行する事になります ©︎ 2018 PRECS Inc.
  3. 基底現実の案件は、どうしてこんなにつらくきびしいのだろう…。 1. 自動テスト、ナシ 現在平行して作成中 2. composer、ナシ 5.3.3ですしね 3. ローカル仮想環境、ナシ ほぼフルオートビルドシェルはあるのだが名前解決の都合上

    共用開発サーバ上の個人開発環境でやるしかない 破壊的テストはで き ま せ ん 4. ペアプログラマー、ナシ そんなに人回せないしね(但し、レビュー、テストの支援はある 5. 洋ナシ 実用中のPEARライブラリが複数存在する ©︎ 2018 PRECS Inc.
  4. 私公開後悔コーカイ中♪ 1. テンプレートエンジン 先に最終的バージョンをメジャーの中で最新にするべきでした ある意味動作確認が取れているため、心理的な負担が減る (そのまま動くとは言っていない) 2. ライブラリの廃棄、差し替え 時間が無かったため、PEARをモダンな物に差し替える事が 出来ませんでした

    どちらにせよcomposer使えないので出来る事は限られていたが 3. 自動テスト可能な状況の用意 特に旧環境、新環境での同一のデータの用意が出来ませんでした とはいえパターンが複雑すぎてどちらにせよ間に合わなかったが ©︎ 2018 PRECS Inc.
  5. やるべき鉄板作業 静的解析 1. phpcsを使いましょう。 但し5.3.3で動くバージョンでは7.2系の解析が出来ないため、 一時的に7.2.Xが動く環境を用意する必要があります 次のコマンドで概要(txt)と詳細(csv)を得られます ©︎ 2018 PRECS

    Inc. ./vendor/bin/phpcs -p -d memory_limit=512M --standard=PHPCompatibility ¥ --parallel=10 ¥ --runtime-set testVersion '7.2' ¥ --ignore=*.js,*.css,*/cache/*,*/public/* ¥ --report-csv=report-detail72.csv ¥ --report-summary=report72.txt ¥ /path_to_output_dir
  6. やるべき鉄板作業 コーディングルール 7. 適用 可能ならばPSR-2などでコードフォーマットを統一する事を お薦めします 今回の弊社のケースでは運よく対応を開始していたため、 差分検出などが容易でした 特にSmartyなどの外部ライブラリと比較する場合は、 Smarty側も併せてコードフォーマットを統一させ、差分を検出

    すると大幅な楽が出来ます 今回は次のコマンドでフォーマットを行いました php-cs-fixerの場合、PHPの構文解析器を用いて解析、再展開を 行うため、安心して使用する事が出来ます ©︎ 2018 PRECS Inc. php-cs-fixer fix --level=psr2 /path_to_directory
  7. やるべき鉄板作業 なお、次の警告が存在する場合、php-cs-fixerは動作しません 『【warning】Assigning the return value of new by reference

    is deprecated in PHP 5.3』 その為、まず先にリファレンス渡しを行っている箇所の見直しと 修正が必要となります PHP5以降ではほぼリファレンス渡しを使う機会は無いので、 このタイミングに始末してしまいましょう リファレンスの設定の仕方によっては絶対に修正出来ないケース もあるため、注意して作業しましょう ちなみに次の正規表現で9割は対象を検知できます ©︎ 2018 PRECS Inc. /=[ ¥t]*&/
  8. 稀によく見る対応パターン HTTP_SERVER_VARS 1. $HTTP_RAW_POST_DATA $GLOBALS['HTTP_RAW_POST_DATA'] $GLOBALS['HTTP_SERVER_VARS'] $GLOBALS['HTTP_SERVER_VARS']['SCRIPT_NAME'] など 次のコードのようなコードがあるためgrep必須です ©︎

    2018 PRECS Inc. $_globals_map = array( 'g' => 'HTTP_GET_VARS', 'p' => 'HTTP_POST_VARS', 'c' => 'HTTP_COOKIE_VARS', 's' => 'HTTP_SERVER_VARS', 'e' => 'HTTP_ENV_VARS' ); $GLOBALS[$_globals_map[$_c];
  9. 稀によく見る対応パターン 2. メソッドの引数の数 親クラスと子クラスで引数が異なるとPHP7.2.5において警告 引数の数が完全に一致し、デフォルト引数の有無、型まで 見られます ©︎ 2018 PRECS Inc.

    $not_enough_args_count = 2- func_num_args(); if ($not_enough_args_count > 0) { throw new ¥ArgumentCountError(sprintf('Too few arguments to function %s(), %s passed', __METHOD__, $not_enough_args_count)); } $args = func_get_args(); $payment_total = $args[0]; $payment_class = $args[1]; $split_count = array_key_exists(2, $args) ? $args[2] : null; $use_3dsecure_flg = array_key_exists(3, $args) ? $args[3] : null;
  10. 稀によく見る対応パターン 次のようにトラバーサブルな振る舞いを行っているクラスなどの 場合は配列の内部ポインタを意識した修正を求められます ©︎ 2018 PRECS Inc. - $child =

    each($this->children); - if ($child) { - return $child['value']; -} else { - reset($this->children); - return false; -} + if (is_null(key($this->children))) { + reset($this->children); + return false; +} + $value = current($this->children); + next($this->children); + return $value;
  11. 1分の1の確率で成功 composer 1. 導入 今までの環境ではnamespaceは導入されていませんでした 全部グローバルにある環境でも、次のcomposer設定を使えば なんとかなるかもしれません ©︎ 2018 PRECS

    Inc. { "name" : "precs/rpst", "description" : "The NG Precs Cart.", "type" : "project", "autoload" : { "psr-4" : { "App¥¥rpst¥¥": "./", // 今後新しく作るApp用 "": "./" // 既存のApp用 } }, }
  12. 未来への片道切符 2. useの導入 当然の事ですが現状はrequire地獄です 先のcomposer導入でrequireを段階的にkillし、useに置き換えます この場合ありがちなのが複数のroot requireがある事 この場合、先行してroot requireの先頭に全てのroot require

    から呼ばれるrequireファイルを設定しておきます 後はcomposer対応がうまくいったら、そのファイルにautoload 呼び出しを追加しておしまい、とできます 3. composer経由でのライブラリの導入 PEARライブラリをモダンな最近のものに差し替える 併せて既存環境と同居出来る類のフレームワーク (例えば、Flywheel2)を導入し、開発効率を上げるのです ©︎ 2018 PRECS Inc.