Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

なぜ、PHPのmbstring.func_overloadをdeprecatedにするのに5年かかったのか? - 慢心、環境の違い

7,500 views

Published on

#y8spring

Published in: Government & Nonprofit

なぜ、PHPのmbstring.func_overloadをdeprecatedにするのに5年かかったのか? - 慢心、環境の違い

  1. 1. なぜ、 PHP の mbstring.func_overload を deprecated にするのに 5 年 かかったのか? - 慢心、環境の違い Y8 2017 spring in Shibuya sasezaki May 27, 2017
  2. 2. 2 目次 ● 自己紹介 ● PHP のこれまで ● PHP の仕組み と 拡張モジュール ● PHP と 文字列 ● mbstring.func_overload の機能について ● 非推奨提案するに至った経緯 / 提案以降の話 ● 5 年かけたことについての反省点 ● "mbstring.func_overload" と同じ事態を避けるには ● まとめ ● ... おまけの話 ( 例えば文字列を避ける、 7.2 での他の deprecated)
  3. 3. 3 自己紹介  はじめまして! sasezaki です。  私が mbstring.func_overload につい て deprecated を表示するようにしろ ! と bugs.php.net に issue レポート (#65785) した人です。
  4. 4. 4 過去の主な Talk 2009 / PHP勉強会 PHP カンファレンス 2011 PHP カンファレンス福岡 2016
  5. 5. 5 PHP のこれまで
  6. 6. 6 皆さん PHP を知っていますか?
  7. 7. 7
  8. 8. 8 私は 「俺 ホントはPHP のこと、ちっとも 分かってあげてやれてなかったんだ !」 というのを 10 年ぐらい続けてます。
  9. 9. 9 だって、そうですよね。 PHP のソースコード・ドキュメントには 非常に多くの開発者が、 その都度の状況や思惑などを おりまぜながら、 PHP は成長してるのだから。 ( 今も! )
  10. 10. 10 閑話休題
  11. 11. 11 PHP: Hypertext Preprocessor  としてよく聞く話 ・ LAMP (Linux, Apache, MySQL, P** ) の P として普及 ・ C によく似た文法。グルー言語としてみなされることもある ・ 非常に多くの機能( 拡張 / 関数・クラス ) が標準で 用意されている。
  12. 12. 12 PHP これまでの歩み https://github.com/open-source-museum/the-history-of-php/
  13. 13. 13 PHP の普及期  .php3 拡張子?  Zend Engine 1  デフォルトでは、 register_globals をオフに - 4.2  stream (I/O抽象化レイヤー ) の導入 - 4.3 1999 2003~
  14. 14. 14 PHP 3 や 4 の初期 、みんな mbstring を使っていたかというと・・・ ➔ PHP 版の jcode もありましたが・・・ ➔ ※ PHP 3の頃は、前身として I18n Package というものだったようです。 (ext/mbstring/README_PHP3-i18n-ja) 1999 2003~
  15. 15. 15 PHP 5移行期 ● 日本にとどまらず、勉強会やカンファレンスが活発に ● “ フルスタックフレームワーク”ブームもありオブジェクト 指向が意識されるように なぜフルスタックを重宝した ? (依存性 ? PHP 4/5バージョンの差異への対応 ?) ● PHP 5.3リリースまで間が空く 2004 2008~
  16. 16. 16 さよなら PHP 6 ● 5.3 リリース ● register_globals , safe_mode, magic_quotes_gpc の非 推奨化 (E_DEPRECATED エラー ) ● バイナリセーフではない関数 (ereg, split)の非推奨化 ● GitHub の浸透も相まって ライブラリなど PHP でも開発が活 発に / CIの SaaS 台頭 2009 2012~
  17. 17. 17 ~~ PHP 5.6そして PHP 7.0, 7.1~ ● 5.5 - preg_replace()の /e 修飾子 (eval) が非推奨に ● 5.6 - iconvおよび mbstring の、エンコーディングに関する オプションが非推奨に ● PHP 7.0 リリース ● スカラー型宣言 / 戻り値の型宣言 の導入 ● AST 導入 2013 2017~
  18. 18. 18 PHP 7.2~ ● 7.2 ● 非推奨の追加 – $php_errormsg, create_function(), mbstring.func_overload など ● 8.0 ● 2020 年 ? ● JIT ? 2017~ https://wiki.php.net/todo/php72#timetable
  19. 19. 19 PHP のこれまで 新規機能を取り込みながらも、危ない機能については 廃止しながら進化してきた。 OSS を取り巻く状況の変化により、品質向上の土壌も 進化していった。
  20. 20. 20 PHP の 仕組み と 拡張モジュール
  21. 21. 21 PHP -リクエストごとのライフサイクル https://www.slideshare.net/ircmaxell/php-under-the-hood-dpc
  22. 22. 22 拡張モジュールでの処理のフック MINIT/ MSHUTDOWN http://fntlnz.github.io/php-extensions-development
  23. 23. 23 PHP 拡張 の種類 http://php.net/extensions.membership
  24. 24. 24 コア拡張 ● ストリーム (4.3 にて登場 ) ● Phar (5.3から組み込み ) ● SPL (5.3から組み込み ) ・・・など 今となっては、当然存在するでしょ ! という機能も、過去にはビルド時に外せた 「これらは実際のところ拡張ではありません。 PHP の コアに組み込まれており、 コンパイルオプションで 無効にすることはできません。」 http://php.net/extensions.membership
  25. 25. 25 バンドルされている拡張 ● iconv ● マルチバイト文字列 (mbstring) ● intl ・・・など 「これらの拡張は PHP にバンドルされています。」 http://php.net/extensions.membership
  26. 26. 26 外部拡張 ● 各 DB 向けドライバ (MySQLi など ) ● Gettext ● DOM ● cURL ・・・など 「これらの拡張は PHP にバンドルされています が、コンパイルするには外部ライブラリが 必要となります。」 http://php.net/extensions.membership
  27. 27. 27 PECL 拡張 ● V8js ● SPL_Types /Data Structures ● phtreads / 各イベント系 (libevent など ) ● mysqlnd_* 系 ・・・など ここまでが、 php.net にてマニュアルが 閲覧できるものです。 「これらの拡張は » PECL にあります。 また、 外部のライブラリを必要とするかもしれません。」
  28. 28. 28 その他 ● hnw/php-timecop ● krakjoe/autostrict ● runkit7/runkit7 (funkit) ・・・など 野良拡張を導入して、今まで動いてた スクリプトが動かない!は自己責任
  29. 29. 29 PHP の しくみ / 拡張モジュール PHP 自体でのフック・コード解析する余地がある。 開発者と利用者 ( コンポーネント開発者 ) が想定する 環境はコアとバンドルである。
  30. 30. 30 PHP と 文字列
  31. 31. 31 「 PHP では、 文字は 1 バイトと同じで す。つまり、 256 個の異なる文字を使用可 能です。 これは、PHP が Unicode をネ イティブにサポートしていないことも意味 します。」 http://php.net/language.types.string
  32. 32. 32 「 PHP における文字列型は、バイトの配 列と整数値 ( バッファ長 ) で実装されてい ます。 バイト列を文字列に変換する方法に ついては何の情報も持っておらず、完全に プログラマ任せとなっています。」 http://php.net/language.types.string
  33. 33. 33 https://www.slideshare.net/nikita_ppv/php-7-what-changed-internally PHP 5 での zval
  34. 34. 34 https://www.slideshare.net/nikita_ppv/php-7-what-changed-internally PHP 7 での zval
  35. 35. 35 ということは?
  36. 36. 36 ・・というような例もあります。
  37. 37. 37 ... あなたの PHP で書かれたプログラム ソースではバイナリ操作って行います? ( バイナリ操作のために文字列関数使ってますか? )
  38. 38. 38 PHP と バイナリ操作と・・ ● 画像処理 (GD, ImageMagick) ● ファイル判定 (finfo) ● password_hash などの パスワードのハッシュ (5.5) ● random_bytes (PHP 7.0)
  39. 39. 39 「けど、けど、文字 ( テキスト ) とバイナリ を分 けないと不便じゃん!」
  40. 40. 40 もしかして、 PHP 6 の話 ですか? https://www.slideshare.net/andreizm/the-good-the-bad-and-the-ugly-what-happened-to-unicode-and-php-6
  41. 41. 41 PHP での文字エンコーディングモジュール ● iconv ● mbstring ● intl
  42. 42. 42 PHP と 文字列 PHP では低レイヤに関わる機能の多くを提供し ている。 PHP で 文字エンコーディングに関わる操作を行 うときは、専用のモジュールが必要となる。
  43. 43. 43 mbstring.func_overload とは
  44. 44. 44 「 PHP アプリケーションの多くは、英語 等のシングルバイトの言語用に設計されて おり、 日本語を含むマルチバイト文字列を 扱う場合には問題を生じる場合がありま す。 substr() 等の PHP の文字列関数の 多くは、 マルチバイト文字列に対応してい ません。」 php.net/mbstring.overload
  45. 45. 45 なので (?)
  46. 46. 46 「 mbstring では、 対応するマルチバイト文字対 応版の関数で既存の PHP 関数を オーバーロード する機能をサポートします。関数のオーバーロード を行うと、例えば substr() を PHP スクリプトで コールした場合に、 mb_substr() が代わりにコー ルされるようになります。 これにより、マルチバ イト文字に対応しないアプリケーションの移植が容 易となります。」 php.net/mbstring.overload
  47. 47. 47 なんと ! 夢のような機能!
  48. 48. 48 mbsting.func_overload の対象となる関数
  49. 49. 49 動作例 mbstring.internal_encoding = UTF-8 mbstring.func_overload = 2 php.ini sample.php <?= strlen(" あ "); // 1
  50. 50. 50 素敵!抱いて!
  51. 51. 51 (;´Д`) unexpected.php <?php $html = '<html>...'; $response->setHeader('Content-Length', strlen($html));
  52. 52. 52 mbstring.func_overload はマルチバイトを考慮できてな いアプリケーションへの解決案だった。 バイナリと文字に違いがない PHP にとっては、影響の 高い機構だった。 mbstring.func_overload とは
  53. 53. 53 非推奨と提案するに至った経緯 / 各開発者の反応
  54. 54. 54 2012 年 ● Zend Framework 2の開発がスタート ● Db などのいくつかのコンポーネントのアーキテクチャ は書きなおされました。が、あくまでベースは ZF1 。
  55. 55. 55 当時の私は、こういう憤りをもってました。 「メジャーバージョンアップに合わせて git に移行し たけど、 (1. 系からの ) 枝分かれ以降の修正が取り込まれ てないじゃん。ずこ!」
  56. 56. 56 プルリク!マージ ! 貢献 ! 圧倒的成長 !
  57. 57. 57 そんなとき
  58. 58. 58 Zend Framework の 開発者ML 2012 年 4 月
  59. 59. 59 zf1 にて、各コンポーネントごとで PHP 環境の 差分対応のために横展開的な修正があったことから、 ユーティリティコンポーネント (ZendStdlib) の開発気風が高まり、その一環で マルチバイト対応の点から、 StringUtils の提案が行われます。
  60. 60. 60 当時の対応 ・・・ mbstring.func_overload フラグがあったら 分岐の繰り返し
  61. 61. 61 メイン開発者の一人 Ben Scholzen の投稿 http://zend-framework-community.634137.n4.nabble.com/Environment-amp-StringUtils-td4559272.html
  62. 62. 62 mbstring.func_overload で ZF を壊すやつは 他の方法でも環境を壊す (safe_mode をオンにしてるように )
  63. 63. 63 かくして、 ZF 2では mbstring.func_overload を サポートしない方向へ 2012 年 4 月
  64. 64. 64 僕「分かったっす。僕これ mbstring のメンテナーに伝えるっす」
  65. 65. 65 CakePHP や Symfony 、 PEAR の ライブラリでもフラグによる分岐が あることを踏まえて、廃止の提案
  66. 66. 66 mbstring メンテナー廣川さんの 廃止に向けてのレスポンスあり
  67. 67. 67 大垣さんが deprecated の提案を internals に投稿 ※ internals とは、 PHP のコア開発についてのメインの ML です。 http://news.php.net/php.internals
  68. 68. 68 その時 (2012 年 4 月 ) の反応 > 特になし! <
  69. 69. 69 ... もちろん この2012 年 4 月の時点で 「 mbstring.func_overload やめた方が 良くない?」 が PHP 利用者に伝わる訳ではなく。。
  70. 70. 70 2012 年 5 月 https://github.com/reactphp/react/pull/27
  71. 71. 71 ReactPHP での mbstring.func_overload が ON のときをサポートしようとする Pull Request 2012 年 5 月
  72. 72. 72 僕「 You 、やめときなよ」 「それでも、動かせるようにしたい」
  73. 73. 73 igorw のレスポンス 「 mbstring.func_overload の振る舞いは      register_globals や magic quotes への  汚いハックを思い出させる」
  74. 74. 74 ~~ そのまま時は流れる ~~
  75. 75. 75 bugs.php.net に レポート 2013 年 9 月
  76. 76. 76 2013 年 10 月 「ユニコードについてのスライド up しました」、 という PHP 開発者のツイート https://twitter.com/auroraeosrose/status/388380154713489409
  77. 77. 77 `Intl doesn't support function “overloading”`
  78. 78. 78 Nikita が 反応 「 func_overload は ASAP な drop 対象でしょ」
  79. 79. 79 僕「その件なんですけど、 bugs にレポート してまして・・」 Nikita 「 intenals に投稿して」
  80. 80. 80 僕「か、かしこま ! 」
  81. 81. 81 ~~ けど、そのまま時は流れ ~~ PHP 7の開発も佳境に入り
  82. 82. 82 Nikita の deprecation の提案 2015 年 3 月
  83. 83. 83 2015 年 3 月
  84. 84. 84 ~~ またまた時は流れ ~~
  85. 85. 85 2016 年 2 月 7.1 に向け Deprecation の RFC 提案が出され http://news.php.net/php.internals/91265
  86. 86. 86 2016 年 11 月 RFC は 7.2 向けの Deprecations に http://news.php.net/php.internals/96993
  87. 87. 87 2016 年 11 月 非推奨の一つとして、 mbstring.func_overload が リストに上がる https://wiki.php.net/rfc/deprecations_php_7_2
  88. 88. 88 賛成多数で可決 2017 年 1 月 https://wiki.php.net/rfc/deprecations_php_7_2
  89. 89. 89 ちなみに
  90. 90. 90 2016 年 12 月 ・・ twig ではしれっと削除されてる https://github.com/twigphp/Twig/commit/b09faf8
  91. 91. 91 非推奨と提案するに至った経緯 / 各開発者の反応 PHP 利用者 ( 主にライブラリ作成者 ) は、 PHP が標準 で用意しているがために mbstring.func_overload をサ ポートしようとしていた。 PHP 自体が用意している機能でも見直すことが必要。
  92. 92. 92 反省点
  93. 93. 93 Zend Framework 2 での ML でのやりとり、および日本人メ ンテナーへの報告 (2012 年 ) から internals での投票可決と master への反映まで 5 年の月日が経過していた。  ※ PHP 7.2 はまだリリースはされていません。 ➔なぜ 5 年かけてしまったのか? ➔5 年の歳月のうち取れた行動はなかったのか?
  94. 94. 94 ● 取れるべきアクションを取らなかった 慢心 ● 環境の違い を否定できてなかった後悔
  95. 95. 95 ● レポートは一度どこかに投稿すれば終わりという訳で はない ● 動きがなかったら、再度自分からアクションを起こ すしかない ➔internals や bugs.php.net への登録は もっと早めにできたはず 取れるべきアクションを取らなかった 慢心
  96. 96. 96 取れるべきアクションを取らなかった 慢心 ● マニュアルに注意書きを載せることも可能だった ● 実は、 php.gr.jp への投稿時に注意書きも載せた方がいい ですね。という話はあった。 – コミット権がないことに、人任せになっていた。 – マニュアルの警告追記も用意してマージ依頼までもでき たはず。 ● 警告の理由を、皆が納得できるように事細かく書かな ればという思いこみもあった。という逃げ
  97. 97. 97 環境の違い を否定 できてなかった後悔 ● 環境の違いを否定する環境づくり ● ライブラリ導入時のチェックを強化すべきだったのでは – 例 ) mbstring.func_overloadがオンの時にコンポーネント をインストールさせない ● 周知・啓蒙が足りなかった ?
  98. 98. 98 ところで
  99. 99. 99 「あぁ、 mbstring.func_overload が 邪魔する件?」 「前から知ってたよ。」
  100. 100. 100 ?
  101. 101. 101 2004 年 7 月
  102. 102. 102 2004 年 7 月 * Do not use gzip encoding if certain string functions are overloaded by mbstring extension (bug #1781)
  103. 103. 103 実は 13 年ぐらい前から気付いてた。
  104. 104. 104 コミュニティ・バグトラッキングの 分断という後悔
  105. 105. 105 結局、現状の機能を肯定してしまったがため に長い間 NO と言えなかった。 盲目的に、 臭いものに蓋をするようにコーディングを 行っていたのはなぜだろう?
  106. 106. 106 慢心・環境の違い
  107. 107. 107 "mbstring.func_overload" と 同じ事態を避けるには
  108. 108. 108 PHP 言語の成長の貢献者としてできること (?) ➔傍観者効果に陥らないようにする – リーナスの法則? ➔先人の教訓を生かす – YAGNI, Feature Creep, 結果の局所化 PHP の利用者としてできること ➔ヴァージョン互換性・設定依存と向き合う
  109. 109. 109 ヴァージョン互換性・設定依存と向き合う 秘伝のタレをやめる 「あらゆる環境での動作サポート」という欲望を捨てる ➔PHP 環境の前提条件 ( ビルドオプション ・php.ini) を制限する (PHP のヴァージョンアップに対して ) 継続的・横断的に動作することを検証、 マイグレーションの促進・いびつな設定の排除 ➔ コード解析、ユニットテスト、互換性の確認 処理のフックでごまかす (?)
  110. 110. 110 アプリケーション動作環境の前提条件 を制限する ● 動作時にチェックする ? ● 例 ) コンストラクタで extension のチェック ● アプリケーション構築時の前提条件を制限する ● プロビジョニングによる冪等性 ● フレームワークによる環境チェック ( 参考例 )SymfonyEnvironments ● コンポーネント・インストール時の前提条件を制限する ● Diagnostics ● composer だと pre-install-cmd ?
  111. 111. 111 PHP でのコード解析 ( 基本 )  デバッガ・プロファイラ・ユニットテスト  Xdebug, phpdbg  静的解析  Reflection  tokenizer  PHPParser  AST (nikic/php-ast) ● IDE, SaaS (scrutinizerなど ), 他の言語による解析ツール
  112. 112. 112 https://github.com/ziadoz/awesome-php#code-analysis PHP のコード解析ツール は様々なものが登場しています
  113. 113. 113 互換性を確認する  PHP 7 へ非推奨となった箇所の診断  php7cc など  複数の PHP バージョンでの挙動確認  3v4l など  利用しているモジュール・関数の互換性解析 ● PHP CompatInfo
  114. 114. 114 まとめ
  115. 115. 115 今日の主な話は ● 歴史のある OSS だからこそ、抱える問題に目を背けて いてはいけないという話 ● PHP での機能非推奨化への過程の一例紹介 ● PHP の進化を支えるための基本の紹介
  116. 116. 116 ● 例えば文字列をさける ● PHP 7.2 での deprecation ● mbstring.func_overload 以外で ● PHP 7 での文字列最適化 おまけの話
  117. 117. 117 ● fig/http-message でのストリームと Content-Length ● 拡張での処理のフック ● runkit を用いた処理の書き換え ● 名前空間を使った hack < 非推奨 > ● Var を dump すると、ほら・・ < 非推奨 > ● 口承伝来 bin2hex との組み合わせ < 非推奨 > 例えば文字列をさける
  118. 118. 118 ※ Wiki.php.net の rfc ページ見ながら話します PHP 7.2 での deprecation
  119. 119. 119 ※ 資料『 PHP AST 徹底解説 ( 補遺 ) 』にて、該当箇所の 確認をします PHP 7 での文字列最適化
  120. 120. 120 ご清聴ありがとうございました

×