【问题标题】:PHP Parse Json from HTTP response & Foreach Iterate Array来自 HTTP 响应和 Foreach 迭代数组的 PHP 解析 Json
【发布时间】:2015-12-03 17:21:44
【问题描述】:

关于这个主题有几个重点问题,但在尝试了所有之后,我觉得有必要寻求帮助。我正在使用 Sendgrid,他们的 webhook 发送一个 json 响应,由于某种原因,我无法弄清楚如何与我们的 CRM 集成。

更新:2015 年 12 月 3 日 @ 下午 1:01 - 我有一些代码可以工作(可能不是最有效的,但它可以工作)见下文。

发送来自 Sendgrid 的 JSON 示例:

    [
  {
    "sg_message_id":"sendgrid_internal_message_id",
    "email": "john.doe@sendgrid.com",
    "timestamp": 1337197600,
    "smtp-id": "<4FB4041F.6080505@sendgrid.com>",
    "event": "spamreport"
  },
  {
    "sg_message_id":"sendgrid_internal_message_id",
    "email": "john.doe@sendgrid.com",
    "timestamp": 1337966815,
    "category": "newuser",
    "event": "bounce",
    "url": "https://sendgrid.com"
  },
  {
    "sg_message_id":"sendgrid_internal_message_id",
    "email": "john.doe@sendgrid.com",
    "timestamp": 1337969592,
    "smtp-id": "<20120525181309.C1A9B40405B3@Example-Mac.local>",
    "event": "unsubscribe",
    "asm_group_id": 42
  }
]

我遇到的问题是 JSON 中的每个数组都与特定事件有关。例如“垃圾邮件”、“退回”或“退订”。我已将其设置为只发送这三个事件。但是,有可能有人会先弹跳,然后得到它,然后点击垃圾邮件,然后点击退订。

最简单的解决方案(忽略层次结构)是让这些事件中的每一个都传递到我们 CRM 中的特定字段。例如,如果 event = spam,那么它将用“spam”填充 $spam。但是,如果它不存在,它应该什么都不做。

最后一点,我必须传递一个标头,以便 Sendgrid 停止向脚本发送垃圾邮件。另外,我不是编码员,也不是程序员,在过去的几个月里我刚刚学到了一些东西。

我的脚本不起作用:

        <?php

    $data = file_get_contents("php://input");
    $events = json_decode($data, true);

    require_once('Infusionsoft/infusionsoft.php');
    $contact = new Infusionsoft_Contact();

    $custom = array(
    '_SGBounce',
    '_SGSpam',
    '_SGUnsub'
    );
    $contact->addCustomFields($custom);

if (is_array($events) || $events instanceof Traversable) {    
foreach ($events as $event) {
        $email = $event['email'];
        if($event['event'] === 'bounce') {
            $bounce = 'bounce';
        } elseif ($event['event'] === 'spamreport') {
            $spam = 'spam';
        } elseif ($event['event'] === 'unsubscribe') {
            $unsub = 'unsubscribe';
        } else {
            die echo header("HTTP/1.1 200 OK");
    }
        process_event($event);
    }}
    if (empty($email)) {
        die echo header("HTTP/1.1 200 OK");
    } else {
        $contact->Email = $email;
        $contact->_SGBounce = $bounce;
        $contact->_SGSpam = $spam;
        $contact->_SGUnsub = $unsub;
        $contact->save();
    }

    header("HTTP/1.1 200 OK");
    ?>

我还有一个正在使用的脚本写入文件,只是为了测试并查看是否可以写入正确的事件。但是我没有成功让它遍历第一个数组。我尝试将 foreach() 嵌套在另一个 foreach() 中,并在此处的另一个答案中发布了 key => value 解决方案。然而,这也是一个死胡同。

任何提示、帮助和指导......将不胜感激。

更新:下面的工作代码(以防这有助于某人)

<?php

$data = file_get_contents("php://input");
$events = json_decode($data, true);

require_once('Infusionsoft/infusionsoft.php');
$contact = new Infusionsoft_Contact();

$custom = array(
'_SendGrid',
);
$contact->addCustomFields($custom);

$emails = array();
$em = '';

if (is_array($events) || $events instanceof Traversable) {
    foreach ($events as $event) {
    $email = $event['email'];
    $em = $email;
    if($event['event'] === 'unsubscribe') {
        $event = 'unsubscribe';
        $unsubscribe = 'unsubscribe';
    } elseif($event['event'] === 'spamreport') {
        $event = 'spam';
        $spam = 'spam';
    } elseif($event['event'] === 'bounce') {
        $event = 'bounce';
        $bounce = 'bounce';
    } else {
        continue;
    }
    $default = array(
        'bounce' => false,
        'spam' => false,
        'unsubscribe' => false
    );
    if(!is_null($event)) {
        if(array_key_exists($email, $emails)) {
            $entry = $emails[$email];
        } else {
            $entry = $default;
        }

        switch($event) {
            case "bounce":
                $entry['bounce'] = true;
                break;
            case "spam":
                $entry['spam'] = true;
                break;
            case "unsubscribe":
                $entry['unsubscribe'] = true;
                break;
        }
    }
}}
if($unsubscribe === 'unsubscribe'){
    $param = 'unsubscribe';
} elseif($spam === 'spam'){
    $param = 'spam';
} elseif($bounce === 'bounce'){
    $param = 'bounce';
} else {
    echo header("HTTP/1.1 200 OK");
}

$contact->Email = $em;
$contact->_SendGrid = $param;
$contact->save();

header("HTTP/1.1 200 OK");
?>

【问题讨论】:

  • 您在循环中设置变量,然后稍后使用变量。这意味着您只能从存储在 $contact 中的 LAST $event 中获取数据...
  • 嗯是有道理的。由于 JSON 字符串的大小(即:数组的数量)是动态的,我可能不知道将存在多少个数组或值,我是否必须将每个值添加到数组中以保留第一个、第二个等事件以确保它们被存储?顺便感谢您的快速响应。
  • 差不多。如果 sendgrid 为这些事件中的每一个提供一个唯一的 id,您可以使用它作为键,例如$contact[$uniquekey]-&gt;email = $email,然后在 foreach 循环中执行此操作。
  • 他们发送的 JSON 示例在上面,但是看起来每个数组上方没有唯一键或分配给整个字符串。我不确定它是否有用,但我确实看到每个 JSON 数组的时间戳都是唯一的。
  • 看到他们在每个数组中都有一个 id 的位置。电子邮件未嵌套(多维)在该 ID 下方...例如使用 $event['sg_message_id']['email'] = $email 对我不起作用。 foreach ($events as $events['timestamp'] =&gt; $event) { $event['email'] = $email; 也没有

标签: php json sendgrid webhooks infusionsoft


【解决方案1】:

你能做的就是这样处理它;

$emails = array();

foreach ($events as $event) {
    $email = $event['email'];
    if($event['event'] === 'bounce') {
        $event = 'bounce';
    } elseif ($event['event'] === 'spamreport') {
        $event = 'spam';
    } elseif ($event['event'] === 'unsubscribe') {
        $event = 'unsubscribe';
    } else {
        continue;
    }
    // Set defaults
    $default = array(
        'bounce' => false,
        'spam' => false,
        'unsubscribe' => false
    );
    if(!is_null($event)) {
        if(array_key_exists($email, $emails)) {
            $entry = $emails[$email];
        } else {
            $entry = $default;
        }

        switch($event) {
            case "bounce":
                $entry['bounce'] = true;
                break;
            case "spam":
                $entry['spam'] = true;
                break;
            case "unsubscribe":
                $entry['unsubscribe'] = true;
                break;
        }
    }
}

然后你会得到一个电子邮件列表,这些电子邮件是它们自己的数组,其中键为 bouncespamunsubscribe 的布尔值。您可以对该数组进行循环以保存数据。

【讨论】:

  • Leuan 感谢您的回复!我添加了您的 sn-p 并尝试对其进行测试。请原谅我在这里缺乏代码知识,但我会将电子邮件放在$emails 内的数组中,对吗?事件呢?是$event吗?如果我做了var_dump($emails)var_dump($event) 我会有这些值吗?我需要将电子邮件和值传递给我的 CRM,据我所知,SendGrid webhook 的每个响应只有 1 封关联的电子邮件,所以可能不需要一系列电子邮件?感谢反馈
  • 有一些代码可以工作,更新了原始代码。谢谢leuan的建议。
猜你喜欢
  • 2016-04-14
  • 2013-07-23
  • 1970-01-01
  • 2020-11-27
  • 1970-01-01
  • 2011-05-20
  • 2020-01-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多