PHP7対応†
- ページ: BugTrack2
- 投稿者: umorigu
- 優先順位: 重要
- 状態: 完了
- カテゴリー: 本体新機能
- 投稿日: 2016-01-03 (日) 07:32:46
- バージョン: 1.5.0
- リリース予定バージョン: 1.5.1
メッセージ†
2015/12/03 に PHP7 が リリースされました。 php.net:archive/2015.php
2016-01-03時点の最新版である PukiWiki 1.5.0 は PHP7 で動作しないので修正が必要です。
PukiWiki 1.5.0 を PHP7 で動作させたときの表示:
Parse error: syntax error, unexpected 'new' (T_NEW) in C:\d\p7\lib\func.php on line 531
関連情報:
分かっている問題:
- 1. 新しいオブジェクトを参照渡しで代入できない - 「new 文の結果を参照渡しで変数に代入することができなくなりました。」
- 2. 変更された関数 - preg_replace() 関数が "\e" (PREG_REPLACE_EVAL) をサポートしなくなりました。
- 3. navi.inc.php のNextリンクが不正。リンク先がparentと同じになっている
- 4. ereg系正規表現関数がなくなった
コメント: & new Class()†
- 新しいオブジェクトを参照渡しで代入できない は、BugTrack2/146みたく結果をバッファに入れてからなら参照渡しできるのかな?と思ったけど、php.net:manual/language.operators.assignment.phpからするとPHP4だけ最初は丸々コピーされる状況がリビジョン:b1489f40b55e74dec22f0066bfb07bf1e835132c と変わらない気がするので意味ないかな~と思い直す…(お役に立てなさそうだ…) --
- なるほど "&" が目に入っていませんでした。
- PHP4においてオブジェクトを代入した際の挙動はいわゆる deep copy であって、shallow copy するためには 参照渡しを明示しなければならなかった
- PHP5からはオブジェクトを代入した際の挙動が shallow copy に変わり、deep copy するためにはオブジェクト毎に clone しなければならなくなった。参照渡しは Deprecated となった
- PHP7では
class の参照渡しの記法自体が禁じられた。 (状況的に、newの)参照渡しは構文エラーとなった
- もしかすると少し誤解があるかもしれません。PHP7でもオブジェクトへの参照が禁止されたわけではありません。new の前に & が書けなくなっただけです。PHP4と5以降で違いがあるのはnewの挙動です。PHP4「newでオブジェトの実体が返る」PHP5「newでオブジェクトの実体を指すポインタが返る」。単純にnewした結果を代入するとdeep copyになったりshallow copyになったりするのは、newの挙動が変わった結果として表れている現象と言えるでしょうか。一方、参照の代入 ( $a =& $b ) は右辺の変数の参照を代入するものであり、つまりPHP5以降は = & new Class は(右辺に変数がないので)意味がなかったのを、PHP4との互換性のために無理やり = new Class と同じ挙動(オブジェクトの実体を指すポインタを返す)に読み替えていた、ということのようです。PHP7ではこの「無意味な記法」ができなくなった、ということだと理解しています -- umorigu
- このような状況で、仮にPHP4のコードをPHP7的に直すのであれば、参照渡しのコードを残すことができないみたいですから、副作用は 「PHP4環境で実行した場合に、shallow copy のつもりで書いた代入が deep copy になる」ことです。変更したはずの値が先祖返りしたり、オーバーヘッド(メモリ、CPU、処理時間)が増加することが予想されます。前者については、とある変数に代入したオブジェクトを、別の変数に代入した上で、どちらの変数も使い続けるようなシチュエーションでもなければその状況にはならないでしょう。後者はどうしようもないですね。 -- henoheno
- なので例えば lib/config.php で umorigu さんが変更された部分は、変数 $obj を、オブジェクトを収める唯一の器として使い回しているだけですから、前者の(=機能上の)影響はないでしょう。 -- henoheno
- 「とある変数に代入したオブジェクトを、別の変数に代入した上で、どちらの変数も使い続けるようなシチュエーションでもなければその状況にはならないでしょう」コメントありがとうございます。まさにご指摘の通りで、newの挙動の違いがあってもPHP4で最終的に出力結果が変わらないことを実データによって確認できたので、この点について対応済みとしたく思います -- umorigu
- ちなみに $obj = new Class() した後に、 $obj2 = & $obj (参照渡し)することはできるのでしょうか?今手元にPHP7はありません。 -- henoheno
- そもそも参照渡ししている理由は何でしょうか。PHPではポインタが使え無いので実質ポインタっぽくなっていますがポインタではありません。リソース節約的意味ならほぼ意味ありませんよ -- [[.]]
- 過去の実装なので推測するしかないのですが、PHP4とPHP5の挙動を合わせたかったのだと思います。『$c = &new C』と書いておけば、PHP4とPHP5のどちらで実行しても、PHP5で『$c = new C』と書いたのと同じ動作(オブジェクトの実体への参照が$cに代入される)になっていました -- umorigu
コメント†
- 正直、今回のPHP7は今までの流れから大きく方向転換してイマドキの設計思想を採用しています。PHP4と完全互換で同一スクリプトというのは難しいのではないでしょうか -- NoName
- なので、PHP4や古い環境向けのバグFIXのみを1.5系に残しつつ1.5系からPHP7に最適化した1.6系を作ったほうが早い気がします。 -- NoName
- 昨日まで私もそう("PHP4と完全互換で同一スクリプトというのは難しい")思ってたのですが、少しの変更で動作してしまったのでこのままPHP4,PHP5.x,PHP7 対応にできそうだな、と思ってます。ただPHP4で動作を見るのは次のバージョンまでにします。もう使ってる人も少ないでしょう。次の次は 5.2 or 5.3 あたりを最低ラインにしようかなと。5.3 がトップシェアになったというニュースもありますね :-) w3techs.com/blog/entry/php_version_5_3_is_now_the_most_used_version_just_ahead_of_5_2 -- umorigu
- PHP7 で PukiWiki official と dev のデータはすべて表示できる程度に対応しました。 branch_r1_5 -- umorigu
- branch_r1_5ブランチのHEADではPHP7で動作するようになりました。これをもってPHP7対応完了とします。この変更は次回リリース1.5.1に含まれます。PHP7上で問題を見つけた方は、ここへのコメントか、新規BugTrackの登録にてお知らせください -- umorigu
- &だけ対応しましたが、#contentsが使えないみたいです。 -- nobou
- #contents の見出しリストが正しく表示されないのは「2. 変更された関数 - preg_replace() 関数が "\e" (PREG_REPLACE_EVAL) をサポートしなくなりました。」が原因です。1.5.0をPHP7で動作させるためには branch_r1_5の "1746320 Merge branch 'php7' into branch_r1_5" でマージされている5つの変更が必要です -- umorigu