WordPress中的奇怪行为MySQL插入JSON编码数据

时间:2017-09-04 16:19:21

标签: php mysql json encoding utf-8

我正在查看我的代码和结果,并且我没有看到任何明显的错误,所以我认为让一些额外的眼睛看一遍是有用的。

我有一个自定义PayPal IPN侦听器,用于更新数据库中的事务表。我在离开工作之前星期五部署了它,今天返回后,它似乎正常正常工作;但我想弄清楚为什么一个插入行为奇怪。

这是对周末发生的插入物的捕获: PayPal IPN log

如您所见,第4个事务的log列的预期JSON值为空。我发现它很奇怪,因为transaction_id列的值正在从同一个数组中解析。

以下是相关的db insert代码:

// Generate valid IPN log
private function generateIpnLog () {
    global $wpdb;

    // prepare log
    $array_log = [];
    $array_log['verified'] = true;
    $array_log['ipn_response'] = (isset($this->PayPal_Response)) ? : 'Error reading from POST array';

    // Parse transaction ID
    $transaction_id = (isset($this->PayPal_Response['txn_id'])) ? $this->PayPal_Response['txn_id'] : null;

    // Generate log
    $log = json_encode($array_log);

    // Update DB
    $wpdb->insert(
        'log_paypal',
        [
            'transaction_id'    => ($transaction_id) ? $transaction_id : 'Error getting transaction ID',
            'log' => ($log) ? $log : 'Error generating transaction log'
        ],
        [
            '%s',
            '%s'
        ]
    );

    // json log response
    $this->json_return = $log;
}

看到事务ID从PayPal响应中解析得很好,并且因为我们知道$array_log['verified']具有明确声明的值,我的猜测是json_encode($array_log)必定存在问题。

我还检查了有问题的PayPal帐户的PayPal IPN历史记录中的数据,并且可以验证在空log列中与其他人相比,数据的形成方式没有任何不同之处

任何人都知道在这种情况下会发生什么?

1 个答案:

答案 0 :(得分:0)

正如@ishegg所建议的,这是一个编码问题,因为PayPal IPN使用windows-1252编码,而DB字段是在UTF-8中编码的。

在这种情况下很容易修复,因为PayPal返回数据不是嵌套/多维的(见下文)。

在证书链加密验证PayPal IPN条目后,在早期函数中调用:

// Process IPN response
$this->PayPal_Response = $this->processIpn();

然后,功能本身:

// Manipulate IPN response and prepare  
// for database update and log
private function processIpn () {
    // Response ref.
    $response = $this->post_array;

    if ( isset($response['charset']) ) {
        if ($response['charset'] == "windows-1252") {
            foreach ($response as $key => $ipn_value) {
                $response[$key] = mb_convert_encoding($ipn_value, 'UTF-8', 'Windows-1252');
            }
        }
    }
    return $response;
}