13

PHP のバージョンを 5.5 から 7.0 に変更した後、Magento 1.8 の奇妙な動作に遭遇しました。この奇妙な振る舞いは、仕事関数の変化によるものuasortです。

ソースコード:

<?php

$arr = [
    "nominal" => [
        "before" => ["subtotal", "grand_total"],
        "after" => [],
        "_code" => "nominal"
    ],
    "subtotal" => [
        "after" => ["nominal"],
        "before" => ["grand_total", "shipping", "freeshipping", "tax_subtotal", "discount", "tax", "weee"],
        "_code" => "subtotal"
    ],
    "shipping" => [
        "after" => ["subtotal", "freeshipping", "tax_subtotal", "nominal", "weee"],
        "before" => ["grand_total", "discount", "tax_shipping", "tax"],
        "_code" => "shipping"
    ],
    "grand_total" => [
        "after" => ["subtotal", "nominal", "shipping", "freeshipping", "tax_subtotal", "discount", "tax"],
        "before" => [],
        "_code" => "grand_total"
    ],
    "msrp" => [
        "before" => [],
        "after" => [],
        "_code" => "msrp"
    ],
    "freeshipping" => [
        "after" => ["subtotal", "nominal"],
        "before" => ["tax_subtotal", "shipping", "grand_total", "tax", "discount"],
        "_code" => "freeshipping"
    ],
    "discount" => [
        "after" => ["subtotal", "shipping", "nominal", "freeshipping", "tax_subtotal", "tax_shipping", "weee"],
        "before" => ["grand_total", "tax"],
        "_code" => "discount"
    ],
    "tax_subtotal" => [
        "after" => ["0" => "freeshipping", "1" => "subtotal", "3" => "nominal"],
        "before" => ["tax", "discount", "shipping", "grand_total", "tax_shipping", "weee"],
        "_code" => "tax_subtotal"
    ],
    "tax_shipping" => [
        "after" => ["shipping", "tax_subtotal", "subtotal", "freeshipping", "nominal"],
        "before" => ["tax", "discount", "grand_total"],
        "_code" => "tax_shipping"
    ],
    "tax" => [
        "after" => ["subtotal", "shipping", "discount", "tax_subtotal", "freeshipping", "tax_shipping", "nominal", "weee"],
        "before" => ["grand_total"],
        "_code" => "tax"
    ],
    "weee" => [
        "after" => ["subtotal", "tax_subtotal", "nominal", "freeshipping"],
        "before" => ["shipping", "tax", "discount", "grand_total", "tax_shipping"],
        "_code" => "weee"
    ]
];


function _compareTotals($a, $b)
{
    $aCode = $a['_code'];
    $bCode = $b['_code'];
    if (in_array($aCode, $b['after']) || in_array($bCode, $a['before'])) {
        $res = -1;
    } elseif (in_array($bCode, $a['after']) || in_array($aCode, $b['before'])) {
        $res = 1;
    } else {
        $res = 0;
    }
    echo sprintf("%s <> %s: %s", $aCode, $bCode, $res) . "\n";
    return $res;
}

uasort($arr, '_compareTotals');
var_dump(array_keys($arr));

PHP 5.5の結果は次のとおりです。

freeshipping <> subtotal: 1
freeshipping <> shipping: -1
weee <> freeshipping: 1
tax <> freeshipping: 1
tax_shipping <> freeshipping: 1
tax_subtotal <> freeshipping: 1
discount <> freeshipping: 1
nominal <> freeshipping: -1
freeshipping <> grand_total: -1
msrp <> freeshipping: 0
subtotal <> msrp: 0
nominal <> subtotal: -1
tax_subtotal <> shipping: -1
weee <> tax_subtotal: 1
tax <> tax_subtotal: 1
tax_shipping <> tax_subtotal: 1
grand_total <> tax_subtotal: 1
discount <> tax_subtotal: 1
shipping <> tax_subtotal: 1
grand_total <> discount: 1
grand_total <> shipping: 1
grand_total <> tax_shipping: 1
grand_total <> tax: 1
weee <> grand_total: -1
shipping <> discount: -1
tax <> shipping: 1
tax_shipping <> shipping: 1
weee <> shipping: -1
tax_shipping <> discount: -1
tax <> tax_shipping: 1
discount <> tax_shipping: 1
tax <> discount: 1

array(11) {
  [0] =>
  string(7) "nominal"
  [1] =>
  string(8) "subtotal"
  [2] =>
  string(4) "msrp"
  [3] =>
  string(12) "freeshipping"
  [4] =>
  string(12) "tax_subtotal"
  [5] =>
  string(4) "weee"
  [6] =>
  string(8) "shipping"
  [7] =>
  string(12) "tax_shipping"
  [8] =>
  string(8) "discount"
  [9] =>
  string(3) "tax"
  [10] =>
  string(11) "grand_total"
}

PHP 7.0の結果は次のとおりです。

nominal <> subtotal: -1
subtotal <> shipping: -1
shipping <> grand_total: -1
grand_total <> msrp: 0
msrp <> freeshipping: 0
freeshipping <> discount: -1
discount <> tax_subtotal: 1
msrp <> tax_subtotal: 0
freeshipping <> tax_subtotal: -1
discount <> tax_shipping: 1
freeshipping <> tax_shipping: -1
tax_subtotal <> tax_shipping: -1
discount <> tax: -1
tax <> weee: 1
tax_shipping <> weee: 1
freeshipping <> weee: -1
tax_subtotal <> weee: -1

array(11) {
  [0] =>
  string(7) "nominal"
  [1] =>
  string(8) "subtotal"
  [2] =>
  string(8) "shipping"
  [3] =>
  string(11) "grand_total"
  [4] =>
  string(4) "msrp"
  [5] =>
  string(12) "freeshipping"
  [6] =>
  string(12) "tax_subtotal"
  [7] =>
  string(4) "weee"
  [8] =>
  string(12) "tax_shipping"
  [9] =>
  string(8) "discount"
  [10] =>
  string(3) "tax"
}

PHP5grand_totalでは最後の要素ですが、PHP7 では - いいえ。この問題は、位置msrp要素の不確実性に関連しています。PHP 5 に関連するこのテーマに関する研究を見つけました。

相対位置を示すことでこの問題を解決しましたmsrp。しかし、なぜphp5で動作し、php7では動作しないのだろうか。これらは新しいバージョンの php の機能ですか、それともバグですか?

追加#1

問題は、PHP7 が等しい要素 (たとえばmsrpand ) をソートする方法を認識していないことだけではありませんgrand_totalshippingitemとを見るとfreeshipping、どちらが早いか明確に定義されています。PHP5 はこの問題を解決しますが、PHP7 は解決しません。

4

3 に答える 3

12

usort()ドキュメントから:

注: 2 つのメンバーを比較して等しい場合、並べ替えられた配列内の相対的な順序は未定義です。

これはあなたがここで見ているものです。PHP 7 は、部分的に安定した別のソート アルゴリズムを使用するため、ソート関数に従って等しい要素を比較すると、異なる順序になる可能性があります。

等しい要素の並べ替え順序が気になる場合 (これは単なるテストの問題ではありません)、比較関数で明示的にする必要があります。

于 2015-12-15T11:30:27.840 に答える
4

考えられる解決策

php7の合計計算でmagentoの問題を解決するために、magentoモジュールを作成しました。私が特に経験した問題は、AmazonPayments チェックアウト ページの Amazon モジュールでの支払いの総計に税金が 2 回追加されたことです。

クレジット

解決策はhttps://magento.stackexchange.com/a/97107/35665のarchigrafixによって提供され、私の問題を解決しました。つまり、これは単にモジュールにパックされた修正です。

モジュール:

https://github.com/hartmut-ltd/magento-php7-totals-fix

于 2016-03-21T01:28:25.947 に答える