1

私は現在、解決できない問題のために巨大な壁にぶつかっています。

問題は、Facebook 支払いプラットフォーム (facebook javascript sdk) を介して支払いを発行すると、バックグラウンドで支払いを処理する必要があるコールバック ページにデータが送信されることです。

これはすべて正常に機能しますが、問題が 1 つあります。Facebook が使用する注文 ID は 64 ビット ID であり、私のサーバーは 32 ビット サーバーであるため、コールバック ページの変数に保存されると ID の精度が失われます。これは、ID を保存できないため、最終的に適切な order_ID を取得できないという結果になります。

この問題は、このフォーラムのいくつかのページで説明されています。たとえば、次のとおりです。

Facebook クレジットのコールバック、order_id の変更 新しいサーバーに移動した後の形式の変更

PHP: 64 ビット整数を文字列に変換する

しかし、どちらのページにも問題の解決策はなく、自分で修正することはできないようです。Facebook がコールバック ページに送信する json データを整数の配列ではなく文字列データに変換しようとしました (これは Facebook が提供する基本的なコードで発生します) が、これを機能させることができません。

他の人がこの問題を (すべてを 64 ビット サーバーに移行することなく) 克服したのを見て、どうすればよいのか疑問に思います。

この問題に光を当てることができる人はいますか?

編集:jsonデータをデコードするために呼び出される標準のfacebookコードである文字列に変換しようとしました(facebookが提供するコード):

$request = parse_signed_request($_POST['signed_request'], $app_secret);

これは関数 parse_signed_request を呼び出します。

function parse_signed_request($signed_request, $secret) {
list($encoded_sig, $payload) = explode('.', $signed_request, 2);

$sig = base64_url_decode($encoded_sig);

$data = json_decode(base64_url_decode($payload), true);

  if (strtoupper($data['algorithm']) !== 'HMAC-SHA256') {
    error_log('Unknown algorithm. Expected HMAC-SHA256');
    return null;
  }

  // check sig
  $expected_sig = hash_hmac('sha256', $payload, $secret, $raw = true);
  if ($sig !== $expected_sig) {
    error_log('Bad Signed JSON signature!');
    return null;
  }
  return $data;
}

この関数は、facebook からの暗号化された json データを (アプリ シークレットを使用して) デコードし、json データを PHP 配列にデコードする必要があります。

その関数は次の関数を使用します (正確には:

function base64_url_decode($input) {
  return base64_decode(strtr($input, '-_', '+/'));
}

上記のコードにより、注文 ID が適切に保存されず、精度が失われ、次のような ID になります: 4.8567130814993E+14

次の関数を使用して、json データを文字列にデコードしようとしましたが (そのため、64 ビット整数 ID の精度が失われません)、役に立ちませんでした:

  function largeint($rawjson) {
    $rawjson = substr($rawjson, 1, -1);
    $rawjson = explode(',' , $rawjson);
    array_walk($rawjson, 'strfun');
    $rawjson = implode(',', $rawjson);
    $rawjson = '{' . $rawjson . '}';
    $json = json_decode($rawjson);
    return $json;
  }


function strfun(&$entry, $key) {
    $data = explode(':', $entry);
    if (FALSE === strpos($data[1], '"')) {
    $data[1] = '"' . $data[1] . '"';
    $entry = implode(':', $data);
    }
}

編集(ユージンの回答):

json_decode を使用して php 変数にする前に JSON データを変更しようとすると、preg_replace 関数を使用する必要がありますか? 以下は、支払いプロセスを開始するためにコールバック ページに送信される初期 JSON データの例です。ここで、問題が何であるかを既に確認できます (これは json_decode を使用した後、id およびその他のデータの精度が失われます)。ID は、実際のデータを反映しないように変更されています。上段のバイヤーIDと下段のユーザーIDを見比べると精度が落ちていることが分かります。

Array
(
[algorithm] => HMAC-SHA256
[credits] => Array
    (
        [buyer] => 1.0055555551318E+14
        [receiver] => 1.0055555551318E+14
        [order_id] => 5.2555555501665E+14
        [order_info] => {"item_id":"77"}
        [test_mode] => 1
    )

[expires] => 1358456400
[issued_at] => 1358452270
[oauth_token] => AAAH4s2ZCCEMkBAPiGSNsmj98HNdTandalotmoredata
[user] => Array
    (
        [country] => nl
        [locale] => nl_NL
        [age] => Array
            (
                [min] => 21
            )

    )

[user_id] => 100555555513181
)

編集#3:

JSON データ内のすべての整数を文字列として表示するために次のことを試みましたが、Facebook プラットフォームからエラーが発生します。ただし、整数を文字列に変更するため、精度が失われることはありません (残念なことに、現在は何も機能しません xD)

preg_replace('/([^\\\])":([0-9]{10,})(,|})/', '$1":"$2"$3', $a)
4

1 に答える 1

1

どのバージョンのPHPを実行していますか?

JSONの「JSON_BIGINT_AS_STRING」オプションをサポートするバージョンのPHPを実行している場合は、それが答えかもしれません。そのオプションを追加するためにjson_decodeが使用されている場合は常に、ライブラリを変更する必要があります。http://php.net/manual/en/function.json-decode.phpを参照してください

PHPバージョンがJSON_BIGINT_AS_STRINGをサポートしていない場合、オプションは次のように制限されます。

ハッキーなオプション:FB APIから返されるJSON文字列に対して何らかの正規表現操作を実行し、その大きなintを二重引用符で囲んで、大きなintではなく文字列としてデコードするようにします。

理想的なオプション:弾丸をかみ、64ビット環境に移行します。それは長期的には多くの頭痛からあなたを救うでしょう。

于 2013-01-17T19:12:07.133 に答える