Search code examples
phpjsonapipostencode

PHP POST'ing JSON encoded array data


I am trying to POST JSON encoded data to a webhook endpoint that resides in one of our companies Microsoft Teams channels. It accepts basic JSON encoded payloads.

I started off in PostMan on my local machine and POST'd the following to my Teams Channel connector webhook URL:

{
 "@context": "https://schema.org/extensions"
 "@type": "MessageCard",
 "themeColor": "0072C6",
 "title": "Test From PostMan",
 "text": "This is the text body of the notification card",
 "potentialAction": [
    {
      "@type": "OpenUri",
      "name": "View in Browser...",
      "targets": [
         { "os": "default", "uri": "https://<REDACTED>" }
      ]
    }
  ]
}

This works fine, it posts the card into the Teams Channel, with the action button below it.

So I moved to PHP, and I made the code below:

<?php
//api endpoint
$url = 'https://<REDACTED>';

//new curl connection
$ch = curl_init($url);

//build json data array
$postdata = array(
  '@context' => 'https://schema.org/extensions',
  '@type' => 'MessageCard',
  'themeColor' => '0072C6',
  'title' => 'Test from curl in PHP',
  'text' => 'test string.. test string.. test string.. test string.. test string.. test string.. test string..',
    'potentialAction' => array (
       '@type' => 'OpenUri',
       'name' => 'View in Browser...',
       'targets' => array (
          'os' => 'default',
          'uri' => 'https://<REDACTED>'
       )
   )
);

//encode json data array
$encodeddata = json_encode($postdata);

//set curl options
curl_setopt($ch, CURLOPT_POSTFIELDS, $encodeddata);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type:application/json'));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);

//debug
echo $result;

//close
curl_close($ch);
?>

When I run the above, the API errors and responds saying it was an invalid payload. So I stripped my code down so that my $postdata array was a lot simpler, as below:

//build json data array
$postdata = array(
  '@context' => 'https://schema.org/extensions',
  '@type' => 'MessageCard',
  'themeColor' => '0072C6',
  'title' => 'Test from curl in PHP',
  'text' => 'test string.. test string.. test string.. test string.. test string.. test string.. test string..'
);

And this works fine, my PHP script is able to post a card into the Teams Channel, just with no action button underneath it. So my issue here lies in how I'm encoding the additional arrays inside of $postdata ?

I'll be honest, my knowledge of arrays in PHP is limited, I think I'm doing this correctly, but clearly I'm having problems, lol. Is there a different/better/more correct way to encode multiple arrays inside of an array into JSON data to POST?


Solution

  • potentialAction in your original JSON is an array of objects, but you made it a single level array only in your PHP data structure.

    You need to wrap this into an additional level:

    $postdata = array(
      '@context' => 'https://schema.org/extensions',
      '@type' => 'MessageCard',
      'themeColor' => '0072C6',
      'title' => 'Test from curl in PHP',
      'text' => 'test string.. test string.. test string.. test string.. test string.. test string.. test string..',
        'potentialAction' => array (
           array (
             '@type' => 'OpenUri',
             'name' => 'View in Browser...',
             'targets' => array (
                array (
                  'os' => 'default',
                  'uri' => 'https://<REDACTED>'
                )
             )
           )
       )
    );
    

    This will give you an array of objects in that place, when you encode it as JSON. (The outer array has a zero-based numeric index, so it stays an array when converted to JSON; the inner array has associative keys, so it automatically becomes an object.)


    Edit: As mentioned in comments, same thing for the targets property inside. Edited the code, to insert an additional level there as well.