PHP JSON解码Amazon SNS

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 post的内容传递给json_decode时,它返回null。对于第一层JSON,我使用的是:

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

针对 E_ERROR 的问题,我需要补充说明的是,我肯定已经使用了 json_decode 函数,因为有些通知已经被正确解析了。但是,由于某种原因,我只得到了其中的一个子集。

更新:由于时间过去了一段时间,我的头脑中已经不再有这段代码,但是为了回答 Hasan 的问题,这里是可行的代码及我的注释。

// 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);

希望这能帮到你!

你遇到了什么问题? - Bafsky
我使用这个类(不仅在Yii项目中)来处理json未启用的情况 https://github.com/yiisoft/yii/blob/1.1.13/framework/web/helpers/CJSON.php - Bogdan Burym
你遇到了什么“问题”?有出现任何错误吗?当你尝试使用json_decode时会发生什么? - gen_Eric
1
我尝试了第二种方法,使用 json_decode,它运行良好。 - gen_Eric
你是如何解决这个问题的? - Hasan Tareque
显示剩余4条评论
1个回答

1
这是一个相当古老的问题,但我遇到了与Amazon SNS接收到的JSON解码相同的问题。json_decode()无法正常工作,而json_last_error()返回JSON_ERROR_SYNTAX。
在尝试(失败)进行字符串替换后,我决定禁用Amazon SES中的“包括原始标头”(它将退信通知发送到Amazon SNS)。突然间一切都正常了。

Setting In 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);
}

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接