ページ: 1
先日PHP7.0.9がリリースされたので、7.0.8からアップデートしたら
アイテム編集画面の「追加プラグインオプション」の部分でいくつかのプラグインの動作がおかしくなりました。
自分が実際に確認したのは、「Custom URL」の部分が表示されなくなり、
アイテムを保存するとカスタムパスが元の「item_xx」に戻ってしまうという症状です。
他のプラグインでもイベントが呼び出されないという症状が出たようです。
アップデートする際は注意が必要かもしれません。
コアの開発にも影響する部分かもしれませんのでご報告まで。
オフライン
先日PHP7.0.9がリリースされたので、7.0.8からアップデートしたら
アイテム編集画面の「追加プラグインオプション」の部分でいくつかのプラグインの動作がおかしくなりました。
問題の起きそうなところは
・sqlのキャッシュ
・コアのオプション関数
・プラグイン側の event_関数
の順ですね
Version 7.0.9 Core: Fixed bug #72508 (strange references after recursive function call and "switch" statement).
とあるので 、reference をいじったようなので MANAGER::notify 関数が破壊された可能性も若干あります
オフライン
「まとめ」
以前フォーラム(2012年8月)でmekyoが指摘していましたnotify関数内のcall_user_func関数の誤使用が原因でした。
フォーラムid=6141 (2012-08-24)で指摘しているように
MANAGER.phpのfunction notify関数の
if (isset($this->plugins[$listener]) && method_exists($this->plugins[$listener], 'event_' . $eventName))
call_user_func(array($this->plugins[$listener], 'event_' . $eventName), $data);
から ↓
$event_funcname = 'event_' . $eventName;
if (isset($this->plugins[$listener]) && method_exists($this->plugins[$listener], $event_funcname))
$this->plugins[$listener]->$event_funcname($data);
に変更すると直ります。
急ぐ場合は、手動で上記の内容を修正することで対応してください。
「概要」
php 7.0.9 + 英語版 or 日本語版 Nucleus + NP_CustomURL
+ ini_set('display_errors','0'); で警告を消しても
同様の現象を確認しました。
追加プラグインオプションの Custom Pathが表示されなくなりました
php 7.0.9にするとプラグインで
expected to be a reference, value given in /nucleus/libs/MANAGER.php
と表示されます。
下記に記載のスレッドの通りに notify関数を修正すると直りました。
(2012年8月) call_user_func_arrayの挙動
で
誤実装を指摘していますが
以前のメイン開発チームにいた人が記述を理解できずに、報告者をバカ扱いし、修正すべきコードを変更をせずに、そのまま放置されていたため
今回 php7.0.9で不具合を起こしたようです。
7.0.9でコアに修正が入り、本来の動作?になっため動作しなくなったと思われます。
phpのcall_user_funcの説明書にも
注意:
call_user_func() のパラメータは 参照渡しではないことに注意しましょう。
と記述されています
参照渡しにしたい場合は、call_user_func_arrayを使わないといけないのです。
このコードで
call_user_func_array(array($this->plugins[$listener], 'event_' . $eventName), array(&$data));
修正すると正常動作にできるのですが、
phpとそのソースであるC言語について上級程度の知識がないと理解が難しいので
Nucleusは、オープンソースであり、素人,プロいろいろなレベルの人がいることもふまえ, notify関数での
call_user_func系の関数を使うのをやめ
以前フォーラムで指摘されているように誰でもわかるコードで
素直に
$event_funcname = 'event_' . $eventName;
if (isset($this->plugins[$listener]) && method_exists($this->plugins[$listener], $event_funcname))
$this->plugins[$listener]->$event_funcname($data);
としたほうが簡潔で、だれでも理解でき、誤動作もなく いいと思います
変数に関数名をいれて$つけると関数として動作する文法が廃止されるまでは、
期待通りの動作をこれからもするはずです。
Nucleus - プラグイン API ヘルプより
パラメータ
event_EventName メソッドはひとつだけ $data パラメータを持ち、
それはイベントごとに内容が異なります。これは連想配列です。
この連想配列に渡されたオブジェクトや配列は参照形式で渡されるため、
これらに加えた変更は記憶されます。
引数は1個しかないので、->$変数($data) の 記述で問題ないと思います。
編集者 ピヨピヨbird (2016-08-10 15:16:29)
オフライン
英語版と日本語版のmasterと開発ブランチ両方にプルリクエストしましたので、しばらくお待ちください。
オフライン
検証と修正ありがとうございました。
以前より問題視されていた部分が今回のアップデートで浮き彫りになった感じですね。
マイナーアップデートで不具合が出たので少しびっくりしました。
この件はこれで安心です。
オフライン
ページ: 1