donglin7979
donglin7979
2015-12-03 17:21

PHP从HTTP响应和Foreach迭代数组中解析Json

已采纳

There are several focused questions on this topic but after trying them all I felt the need to seek out help. I am using Sendgrid, their webhook sends a json response and for some reason I have been unable to figure out how to integrate with our CRM.

Update: 12/3/2015 @ 1:01pm - I got some code to work (probably not the most efficient but it works) see below.

Example JSON from Sendgrid being sent:

    [
  {
    "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
  }
]

The issue I am running into is that each array in the JSON pertains to a particular event. For example "Spam", or "Bounced" or "Unsubscribe". I've set it up so that only those three events are sent. However there is a possibility that someone will bounce first, then get it, then hit spam, then hit unsubscribe.

The simplest solution for this (disregarding a heirarchy system) is to have each of these events pass along to a specific field in our CRM. For example if the event = spam, then it would fill $spam with "spam". However if it is not present it should do nothing.

One last note, I have to pass a header across so that Sendgrid will stop spamming the script. Also I am not a coder, or programmer, I have just picked up a few things over the last few months.

My Script that Isn't Working:

        <?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");
    ?>

I also have a script I am using that writes to a file, just to test and see if I can get the correct events to write. However I have been unsuccessful to get it to iterate past the first array. I've tried nesting the foreach() in another foreach() with a key => value solution posted in another answer here. However that was also a dead end.

Any tips, help, and guidance... would be greatly appreciated.

Update: Working Code Below (in case this helps someone)

<?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");
?>
  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

1条回答

  • donljt2606 donljt2606 6年前

    What you could do, is process it like this;

    $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;
            }
        }
    }
    

    Then you'd end up with a list of emails that are their own array with boolean values for keys bounce, spam and unsubscribe. You could do a loop over that array to save the data.

    点赞 评论 复制链接分享

相关推荐