#author("2023-08-28T10:58:01+09:00","","")
#author("2023-09-07T21:50:12+09:00","","")
* PHP7対応 [#y99b2374]

- ページ: [[BugTrack2]]
- 投稿者: [[umorigu]]
- 優先順位: 重要
- 状態: 完了
- カテゴリー: 本体新機能
- 投稿日: 2016-01-03 (日) 07:32:46
- バージョン: 1.5.0
- リリース予定バージョン: 1.5.1

#contents

** メッセージ [#z123c55f]
2015/12/03 に PHP7 が リリースされました。 [[php.net:archive/2015.php#id2015-12-03-1]]

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


関連情報:
- Migrating from PHP 5.6.x to PHP 7.0.x -- [[php.net:manual/en/migration70.php]]

分かっている問題:
- 1. 新しいオブジェクトを参照渡しで代入できない - 「new 文の結果を参照渡しで変数に代入することができなくなりました。」
-- [[php.net:manual/ja/migration70.incompatible.php#migration70.incompatible.other.new-by-ref]]
-- 対策: ' $var = & new Class ' のコードは ' $var = new Class ' に書き換えた。PHP4での動作に問題がないことを確認済み
- 2. 変更された関数 - preg_replace() 関数が "\e" (PREG_REPLACE_EVAL) をサポートしなくなりました。
-- [[php.net:manual/ja/migration70.changed-functions.php#migration70.changed-functions.core]]
-- 注釈の抽出に $NotePattern (lib/html.php, lib/init.php) で利用されている
-- 同一個所のバグ: [[BugTrack2/22]] 見出しと目次に含まれる注釈の構文定義の揺れ (正規表現のパッチ)
-- 同一個所のバグ2: [[BugTrack2/358]] XAMPPの特定バージョンで「テキスト整形のルール」 FormattingRules を表示できない
-- 対策: /e を使わなくしました。(もともと PREG_REPLACE_EVAL のロジックは使っていなかったので、単純に実装上から e を削除しただけです)
- 3. navi.inc.php のNextリンクが不正。リンク先がparentと同じになっている
-- foreach の変更 - 「foreach は内部の配列ポインタを変更しない」
-- [[php.net:manual/ja/migration70.incompatible.php#migration70.incompatible.foreach.array-pointer]]
-- arrayの内部ポインタの挙動の違いによるもの (current関数)
--- 参考リンク: wiki.php.net/rfc/php7_foreach qiita.com/hnw/items/c79458dead338a554a13
-- 対策: 配列の内部変数に依存しないロジックに書き換えた。current以外の配列内部ポインタ参照関数を利用していないことを確認した
- 4. ereg系正規表現関数がなくなった
-- 削除された拡張モジュール - ereg
-- [[php.net:manual/ja/migration70.removed-exts-sapis.php#migration70.removed-exts-sapis.removed-exts]]
-- 問題例: calendar_viewer プラグインの表示ができない
-- 対策: ereg は preg_replace に ereg_replace は preg_replace に置き換えた

--------
** コメント: & new Class() [#e1f913c0]

- & new Class() の構文がサポートされなくなったようなので、PHP4との両対応が難しくなっています -- [[umorigu]] &new{2016-01-03 (日) 07:35:26};
-- ふむ・・・ Deprecated になったといういう記載は無さそうですね -- [[henoheno]] &new{2016-01-05 (火) 21:33:02};
-- ここのようです。 [[php.net:manual/ja/migration70.incompatible.php#migration70.incompatible.other.new-by-ref]] PHP 5.6.x から PHP 7.0.x への移行 - 下位互換性のないその他の変更 - 新しいオブジェクトを参照渡しで代入できない - 「new 文の結果を参照渡しで変数に代入することができなくなりました。」 -- [[umorigu]] &new{2016-01-05 (火) 23:36:57};
- '& new Class' を 'new Class' に変えるだけで PHP7 でも動作するようになりました。 [[sfjp:projects/pukiwiki/scm/git/pukiwiki/commits/b1489f40b55e74dec22f0066bfb07bf1e835132c]]  PHP4でも動作しているように見えるのですが、問題があることをどうやって確認しよう・・・ -- [[umorigu]] &new{2016-01-06 (水) 01:06:38};
-- officialとdevのデータをPHP4.1と7で表示してみて差分をとる方法を考えました -- [[umorigu]] &new{2016-01-06 (水) 01:42:52};

- 新しいオブジェクトを参照渡しで代入できない は、[[BugTrack2/146]]みたく結果をバッファに入れてからなら参照渡しできるのかな?と思ったけど、[[php.net:manual/language.operators.assignment.php]]からするとPHP4だけ最初は丸々コピーされる状況がリビジョン:b1489f40b55e74dec22f0066bfb07bf1e835132c と変わらない気がするので意味ないかな~と思い直す…(お役に立てなさそうだ…) --  &new{2016-01-07 (木) 20:03:47};
-- 情報ありがとうございます。[[BugTrack2/146]] ここで & new Class() が一気に増えたんですね。必要があって参照にしているんだと思っていましたが、経緯を見ると E_NOTICE を避けるために導入されたようです。今はもうE_NOTICE上等なので無視するとして、これなら機能的な問題も起きなさそうです。大変参考になりました -- [[umorigu]] &new{2016-01-08 (金) 01:40:59};
-- 参照返しでの"return new Class()"に関する[[BugTrack2/146]]のコミット cvs:lib/convert_html.php (1.17) は物理的に消えている([[teanan]]さんのコメント 2005-12-29 (木) 23:23:33 からのやりとりを参照)らしいですよ。"& new Class()"という使い方は、[[BugTrack/499]]あたりの改修(GITだと[[pukiwiki/commits/8187d3406d0ebfbd2067a8b3ff74411190767b68>sfjp:projects/pukiwiki/scm/git/pukiwiki/commits/8187d3406d0ebfbd2067a8b3ff74411190767b68]])の時点でも存在はしているようです。 --  &new{2016-01-08 (金) 21:48:49};
-- 早とちりしました。今のところ問題ないので結果オーライということで・・・ -- [[umorigu]] &new{2016-01-11 (月) 00:15:12};
- なるほど "&" が目に入っていませんでした。
-- 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]] &new{2016-01-10 (日) 23:30:31};
-- このような状況で、仮にPHP4のコードをPHP7的に直すのであれば、参照渡しのコードを残すことができないみたいですから、副作用は 「PHP4環境で実行した場合に、shallow copy のつもりで書いた代入が deep copy になる」ことです。変更したはずの値が先祖返りしたり、オーバーヘッド(メモリ、CPU、処理時間)が増加することが予想されます。前者については、とある変数に代入したオブジェクトを、別の変数に代入した上で、どちらの変数も使い続けるようなシチュエーションでもなければその状況にはならないでしょう。後者はどうしようもないですね。 -- [[henoheno]] &new{2016-01-07 (木) 23:22:50};
-- なので例えば lib/config.php で umorigu さんが変更された部分は、変数 $obj を、オブジェクトを収める唯一の器として使い回しているだけですから、前者の(=機能上の)影響はないでしょう。 -- [[henoheno]] &new{2016-01-07 (木) 23:33:39};
--- 「とある変数に代入したオブジェクトを、別の変数に代入した上で、どちらの変数も使い続けるようなシチュエーションでもなければその状況にはならないでしょう」コメントありがとうございます。まさにご指摘の通りで、newの挙動の違いがあってもPHP4で最終的に出力結果が変わらないことを実データによって確認できたので、この点について対応済みとしたく思います -- [[umorigu]] &new{2016-01-10 (日) 23:42:56};

- ちなみに $obj = new Class() した後に、 $obj2 = & $obj (参照渡し)することはできるのでしょうか?今手元にPHP7はありません。 -- [[henoheno]] &new{2016-01-07 (木) 23:49:10};
-- オブジェクトの参照の代入はできるようです -- [[umorigu]] &new{2016-01-08 (金) 01:36:00};
 class C { var $v; function __construct($_v) { $this->v = $_v; } }
 $a = new C(1);
 $b = new C(3);
 echo $a->v; // => 1
 echo $b->v; // => 3
 $ref_a = &$a;
 $ref_a = $b;
 echo $a->v; // => 3
 echo $b->v; // => 3
 $ref_a->v = 5;
 echo $a->v; // => 5
 echo $b->v; // => 5
 $b->v = 7;
 echo $a->v; // => 7
 echo $b->v; // => 7
-- 確認をありがとうございました。オブジェクトの参照渡し自体は可能であるならば、一応shallow copyの余地はありそうですね。 -- [[henoheno]] &new{2016-01-11 (月) 03:05:39};
- そもそも参照渡ししている理由は何でしょうか。PHPではポインタが使え無いので実質ポインタっぽくなっていますがポインタではありません。リソース節約的意味ならほぼ意味ありませんよ -- [[.]] &new{2016-01-15 (金) 09:13:10};
-- 過去の実装なので推測するしかないのですが、PHP4とPHP5の挙動を合わせたかったのだと思います。『$c = &new C』と書いておけば、PHP4とPHP5のどちらで実行しても、PHP5で『$c = new C』と書いたのと同じ動作(オブジェクトの実体への参照が$cに代入される)になっていました -- [[umorigu]] &new{2016-01-16 (土) 15:15:06};
- navi.inc.php のNextリンクが不正、修正方法がわかりません。教えてください -- [[Radha]] &new{2023-08-28 (月) 10:58:01};
-- navi.inc.php になにかバグを見つけたということでしょうか?どういうバグでしょうか?詳しく教えてください -- [[umorigu]] &new{2023-09-07 (木) 21:50:12};

#comment

** コメント [#qd5e3302]
- 正直、今回のPHP7は今までの流れから大きく方向転換してイマドキの設計思想を採用しています。PHP4と完全互換で同一スクリプトというのは難しいのではないでしょうか -- [[NoName]] &new{2016-01-07 (木) 11:29:48};
- なので、PHP4や古い環境向けのバグFIXのみを1.5系に残しつつ1.5系からPHP7に最適化した1.6系を作ったほうが早い気がします。 -- [[NoName]] &new{2016-01-07 (木) 11:31:57};
-- 昨日まで私もそう("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]] &new{2016-01-08 (金) 01:08:27};
- PHP7 で [[PukiWiki official>pukiwiki:FrontPage]] と [[dev>dev:FrontPage]] のデータはすべて表示できる程度に対応しました。 [[branch_r1_5>sfjp:projects/pukiwiki/scm/git/pukiwiki/commits?branch=branch_r1_5]] -- [[umorigu]] &new{2016-01-10 (日) 18:33:31};
- branch_r1_5ブランチのHEADではPHP7で動作するようになりました。これをもってPHP7対応完了とします。この変更は次回リリース1.5.1に含まれます。PHP7上で問題を見つけた方は、ここへのコメントか、新規BugTrackの登録にてお知らせください -- [[umorigu]] &new{2016-01-10 (日) 23:58:37};
- &だけ対応しましたが、#contentsが使えないみたいです。 -- [[nobou]] &new{2016-01-15 (金) 17:01:34};
-- #contents の見出しリストが正しく表示されないのは「2. 変更された関数 - preg_replace() 関数が "\e" (PREG_REPLACE_EVAL) をサポートしなくなりました。」が原因です。1.5.0をPHP7で動作させるためには [[branch_r1_5>sfjp:projects/pukiwiki/scm/git/pukiwiki/commits?branch=branch_r1_5]]の "1746320 Merge branch 'php7' into branch_r1_5" でマージされている5つの変更が必要です -- [[umorigu]] &new{2016-01-16 (土) 14:42:56};
--- すいません、コメントの5つの変更が追えないのですが、サマリにある4項目の修正でOKでしょうか。 -- [[elem]] &new{2016-11-19 (土) 16:55:32};
--- 4項目が5つに分割されてコミットされている(=5つの変更)ということだと思います。5つの変更をすべてまとめたのが [[ja.osdn.net:projects/pukiwiki/scm/git/pukiwiki/commits/1746320f9b855bba054dfbdb2bc868824cc4296c]] で、これを参考に修正するといいかと。 -- [[bee]] &new{2016-11-19 (土) 18:58:39};
--- はい。それでOKです。 [[df0569a>osdn.net:projects/pukiwiki/scm/git/pukiwiki/commits/df0569a774f332ed2823fd2c098551627e1582d6]] [[6ac4ecf>osdn.net:projects/pukiwiki/scm/git/pukiwiki/commits/6ac4ecfdde6e5e5b1f0b85022c9c81b2c6a22c30]] [[51ce191>osdn.net:projects/pukiwiki/scm/git/pukiwiki/commits/51ce19164fa53b3d987a10e91889d3c5c15d36e0]] [[59f8641>osdn.net:projects/pukiwiki/scm/git/pukiwiki/commits/59f864164fb49de06e29519a663898f855c4b6c0]] [[b1489f4>osdn.net:projects/pukiwiki/scm/git/pukiwiki/commits/b1489f40b55e74dec22f0066bfb07bf1e835132c]] -- [[umorigu]] &new{2016-11-19 (土) 19:07:51};
 $ git log --oneline --graph --decorate 1746320
 *   1746320 Merge branch 'php7' into branch_r1_5
 |\
 | * df0569a BugTrack2/369 PHP7: Replace ereg regex functions with preg_xxx
 | * 6ac4ecf BugTrack2/369 Follow PHP7 changes of internal array pointer
 | * 51ce191 BugTrack2/369 PHP7 - Remove /e (PREG_REPLACE_EVAL) in preg_replace
 | * 59f8641 Fix invalid reference operator of array for usort
 | * b1489f4 BugTrack2/369 Support PHP7 - Remove '& new Class' notation
 |/
 * 4752aff BugTrack2/358 Improve note regex for better PHP compatibility

#comment

トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Site admin: PukiWiki Development Team

PukiWiki 1.5.4+ © 2001-2022 PukiWiki Development Team. Powered by PHP 8.2.12. HTML convert time: 0.084 sec.

SourceForge