2

I am trying to access array keys of an array:

$attributes = $xml['SAMLP:RESPONSE']['SAML:ASSERTION']['SAML:ATTRIBUTESTATEMENT']['SAML:ATTRIBUTE']['SAML:ATTRIBUTEVALUE'];

The way I did it works great if the response comes out nicely as I expected. If not, I will get something like this:

Undefined index: SAMLP:RESPONSE

I've tried:

try {
  $attributes = $xml['SAMLP:RESPONSE']['SAML:ASSERTION']['SAML:ATTRIBUTESTATEMENT']['SAML:ATTRIBUTE']['SAML:ATTRIBUTEVALUE'];
} catch (Exception $e) {
    Helper::console("Bad SAML RESPONSE.");
    dd('Sorry, we could not find your data. Please contact Business Customer Service at 015332266.');
}

I'm trying to avoid doing a lot of this array_key_exists check:

if (array_key_exists('SAMLP:RESPONSE', $xml)) {
    if (array_key_exists('SAML:ASSERTION', $xml['SAMLP:RESPONSE'])) {
        if (array_key_exists('SAML:ATTRIBUTESTATEMENT', $xml['SAMLP:RESPONSE']['SAML:ASSERTION'])) {

            if (array_key_exists('SAML:ATTRIBUTE', $xml['SAMLP:RESPONSE']['SAML:ASSERTION']['SAML:ATTRIBUTESTATEMENT'])) {

                if (array_key_exists('SAML:ATTRIBUTEVALUE', $xml['SAMLP:RESPONSE']['SAML:ASSERTION']['SAML:ATTRIBUTESTATEMENT']['SAML:ATTRIBUTE'])) {

                    $attributes = $xml['SAMLP:RESPONSE']['SAML:ASSERTION']['SAML:ATTRIBUTESTATEMENT']['SAML:ATTRIBUTE']['SAML:ATTRIBUTEVALUE'];

                }else{
                    Helper::console("['SAML:ATTRIBUTEVALUE'] key not exist");
                    dd('Sorry, we could not find your data. Please contact Business Customer Service at 015332266.');
                }

            }else{
                Helper::console("['SAML:ATTRIBUTE'] key not exist");
                dd('Sorry, we could not find your data. Please contact Business Customer Service at 015332266.');
            }
        }else{
            Helper::console("['SAML:ATTRIBUTESTATEMENT'] key not exist");
            dd('Sorry, we could not find your data. Please contact Business Customer Service at 015332266.');
        }
    }else{

        Helper::console("['SAMLP:RESPONSE'] key not exist");
        dd('Sorry, we could not find your data. Please contact Business Customer Service at 015332266.');
    }

} else {
    Helper::console('SAMLP:RESPONSE key not exist');
    dd('Sorry, we could not find your data. Please contact Business Customer Service at 015332266.');
}

What would be the right way or best practice to check for something like this? How would one go about and do it?

AbraCadaver
  • 78,200
  • 7
  • 66
  • 87
code-8
  • 54,650
  • 106
  • 352
  • 604

1 Answers1

2

Though long, one isset will work:

if(isset($xml['SAMLP:RESPONSE']
             ['SAML:ASSERTION']
             ['SAML:ATTRIBUTESTATEMENT']
             ['SAML:ATTRIBUTE']
             ['SAML:ATTRIBUTEVALUE'])) {

    $attributes = $xml['SAMLP:RESPONSE']
                      ['SAML:ASSERTION']
                      ['SAML:ATTRIBUTESTATEMENT']
                      ['SAML:ATTRIBUTE']
                      ['SAML:ATTRIBUTEVALUE'];
}

Or in PHP 7 the Null coalescing operator will assign if set or assign an alternate value if not:

$attributes = $xml['SAMLP:RESPONSE']
                  ['SAML:ASSERTION']
                  ['SAML:ATTRIBUTESTATEMENT']
                  ['SAML:ATTRIBUTE']
                  ['SAML:ATTRIBUTEVALUE'] ?? null;

You could also check out the Getter function from How to write getter/setter to access multi-level array by key names? and pass it something like this:

$path = "SAMLP:RESPONSE.SAML:ASSERTION.SAML:ATTRIBUTESTATEMENT.SAML:ATTRIBUTE.SAML:ATTRIBUTEVALUE";
$attributes = get($path, $xml); //returns NULL if the path doesn't exist

I used a . separator, however you can use any separator other than : like / or - instead.

AbraCadaver
  • 78,200
  • 7
  • 66
  • 87