4

我在使用 PHP json_decode(5.3.10-1ubuntu3.5) 解码某些 Amazon SNS 通知时遇到问题,尽管使用 jsonlint.com 将 json 标记为有效,但我仍然无法弄清楚原因。有人可以指出我正确的方向吗?这里有两个例子:

{
  "Type" : "Notification",
  "MessageId" : "8q787fm3-f7fe-5sf4-863e-331bre627f24",
  "TopicArn" : "arn:aws:sns:us-east-1:1234567890:ses-bounces-topic",
  "Message" : "{\"notificationType\":\"Bounce\",\"bounce\":{\"reportingMTA\":\"dns; a193-136.smtp-out.amazonses.com\",\"bounceType\":\"Transient\",\"bouncedRecipients\":[{\"emailAddress\":\"email@example.com\",\"status\":\"5.0.0\",\"diagnosticCode\":\"smtp; 5.3.0 - Other mail system problem 571-'5.7.1 Message contains spam or virus or sender is blocked : 17624:1603463706|734463C' (delivery attempts: 0)\",\"action\":\"failed\"}],\"bounceSubType\":\"General\",\"timestamp\":\"2013-03-11T22:15:21.000Z\",\"feedbackId\":\"0000013d5b854265-18f16a12-8a99-11e2-aa8d-81a75f1af476-000000\"},\"mail\":{\"timestamp\":\"2013-03-11T22:14:51.000Z\",\"source\":\"otheremail@example.com\",\"messageId\":\"0000013d5b853e2a-820173e1-095e-4h91-9c91-03876f970534-000000\",\"destination\":[\"email@example.com\"]}}",
  "Timestamp" : "2013-03-11T22:14:52.935Z",
  "SignatureVersion" : "1",
  "Signature" : "bY5gjFMgrVnK+4Qw867qHR0cLDXlgZmYb6EdiDAd4hNHMDab4J5MdldldEQwkSFslkdkDsdowlsKAdQvZ9HZwSmEcTRpwgg3Fpp5R/efVnTdUVfJkmBcnhijhWHpxSdEqN9m5vgPhg=",
  "SigningCertURL" : "https://sns.us-east-1.amazonaws.com/SimpleNotificationService-f3ecfb7224c72n3fe7bp5KDMMX6de32f.pem",
  "UnsubscribeURL" : "https://sns.us-east-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-1:1234567890:ses-bounces-topic:73m9983aa-0f4b-4r87-a5d7-d43pb99c91af"
}

{
  "Type" : "Notification",
  "MessageId" : "3c91t096-h331-5dm1-9u22-8822c3cdb7e8",
  "TopicArn" : "arn:aws:sns:us-east-1:1234567890:ses-bounces-topic",
  "Message" : "{\"notificationType\":\"Bounce\",\"bounce\":{\"reportingMTA\":\"dsn; aws-ses-mta-svc-iad-1d-i-ccb81arf.us-east-1.amazon.com\",\"bounceType\":\"Permanent\",\"bouncedRecipients\":[{\"emailAddress\":\"email@example.com\",\"status\":\"5.1.1\",\"diagnosticCode\":\"smtp; 550-5.1.1 The email account that you tried to reach does not exist. Please try\\\\n550-5.1.1 double-checking the recipient's email address for typos or\\\\n550-5.1.1 unnecessary spaces. Learn more at\\\\n550 5.1.1 http://support.google.com/mail/bin/answer.py?answer=6596 ht9si5931660qab.18 - gsmtp\",\"action\":\"failed\"}],\"bounceSubType\":\"General\",\"timestamp\":\"2013-03-08T16:15:40.000Z\",\"feedbackId\":\"0000015m4ac15133-4b74a3sf-890b-11e2-bf3f-53yadf2149d9-000000\"},\"mail\":{\"timestamp\":\"2013-03-08T16:15:39.000Z\",\"source\":\"otheremail@example.com\",\"messageId\":\"0000017d44c94bnf-a333d68b-8bed-4a2b-bdbf-4156zb5cdd9f-000000\",\"destination\":[\"example@sample.com\"]}}",
  "Timestamp" : "2013-03-08T16:15:40.472Z",
  "SignatureVersion" : "1",
  "Signature" : "pYxerRQVHo0kgbLh4a/nri8Rveqdlb/CbPuXEkdCaBt7ulJ5G5gU6TYaUM94iFnCTBC9+5dLZRvydIsemFCiUQUArsh30tcgzBbb2rb7cuZoi09T4bYByN9FY=",
  "SigningCertURL" : "https://sns.us-east-1.amazonaws.com/SimpleNotificationService-f3mcfb7224c7235fe7bb5f79f96dd52p.pem",
  "UnsubscribeURL" : "https://sns.us-east-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-1:1234567890:ses-bounces-topic:7p37c3za-0h4b-4j87-a5i7-d42cb90c9maf"
}

我看到 jsonlint.com 说它是有效的 JSON 我只是不明白为什么当我将 RAW 帖子的内容传递给json_decode它时返回 null。对于我正在使用的第一级 JSON:

$result = json_decode($HTTP_RAW_POST_DATA);
if (!empty($result)) { }

我应该添加我肯定有的每个 E_ERROR 的问题,json_decode因为某些/大部分通知都已正确解析。我只是得到一个由于某种原因没有的子集。

更新:已经有一段时间了,所以我的头不再在这段代码中,而是回答哈桑的问题。这是工作代码和我对此的评论。

// json_decode does not like single quotes in the response so strip them here
$notification = str_replace("'", '', $HTTP_RAW_POST_DATA);
$result = json_decode($notification);

希望这可以帮助!

4

1 回答 1

0

这是一个非常古老的问题,但我在解码从 Amazon SNS 收到的 JSON 时遇到了同样的问题。json_decode () 不工作并且 json_last_error () 返回 JSON_ERROR_SYNTAX。

在尝试使用字符串替换(但失败)后,我决定在 Amazon SES 中禁用“包含原始标头”(它将退回通知发送到 Amazon SNS)。突然间一切正常。

在 AWS SES 中设置

为了完整起见,我解码字符串的 PHP 代码如下:

$decoded = json_decode (trim ($jsonFromAWS), true);
if (is_array ($decoded) && isset ($decoded['Message']) && !is_array ($decoded['Message']) && $decoded['Message'] !== '')
{
    $decoded['Message'] = json_decode (trim ($decoded['Message']), true);
}

希望能帮助其他遇到这个问题的人!

于 2019-10-03T22:28:41.003 回答