PHP属性/关联数组中的未定义索引警告?

I am having trouble retrieving some data out of an LDAP attribute in PHP.

I connect to LDAP, perform my query, and store the results in a var like so:

$info = ldap_get_entries($connect, $sr);

Now, I can store most of the LDAP attributes I need in sessions vars, like so:

        $_SESSION['accountFirstName'] = $info[0]['givenname'][0];
        $_SESSION['accountLastName'] = $info[0]['sn'][0];
        $_SESSION['accountEmail'] = $info[0]['mail'][0];

These work fine.. No problems. However, there is another var I need to store. I believe It is an associative array. For some reason, no matter what I do, I am getting an NOTICE: Undefined index warning for that specific attribute. I have tried storing it like the above demonstration, but to be honest I'm not entirely sure what the [0] indices on either ends of the attribute name mean.. I'm not familiar with LDAP and frankly the setup is very confusing.

So I guess my questions are:

  • how do you access associative arrays that are returned from an LDAP query?

  • what does 'undefined index' mean? Does it mean that that attribute does not exist, or it does not exist at the index provided?

  • How can I test my LDAP query to see if the variable even exists?

  • There is a possibility that the account performing the query does not have adequate LDAP access privileges (the project is for a university and there is a lot of red tape). Is there any way for me to verify that through code?

Thank you! And my apologies for the vagueness of the information provided, I can't be too open-mouthed right now.

The issue doesn't reside with the ldap_get_entries() method, or LDAP at all - it's the data that's being returned.

The NOTICE: Undefined index error is stating that an index in your array doesn't exist. In this case, it is most likely that the data you're receiving doesn't have a value such as givenname or mail, but it could also be the [0] (or, "first record") in one of those arrays.

The textual/string index value, such as givenname or sn, is what would be defined as the "associative array". You are correctly accessing that data with $info[0]['givenname'];

To check if an index exists in PHP, you can use isset(), such as:

if (isset($info[0]['givenname'])) {
    // process data here
}

As a quick way to do your assignments, you can use something like this:

if (count($info) > 0) {
    $_SESSION['accountFirstName'] = (isset($info[0]['givenname']) && isset($info[0]['givenname'][0])) ? $info[0]['givenname'][0] : '';
}

If you have a long list of values you need, I would suggest writing something similar to the following to auto-process it for you:

$fields = array(
    'accountFirstName' => 'givenname',
    'accountLastName' => 'sn',
    'accountEmail' => 'mail'
);

$info = $info[0];
foreach ($fields as $field => $ldapField) {
    // check if the value exists; otherwise set it to an empty-string
    $_SESSION[$field] = (isset($info[$ldapField]) && isset($info[$ldapField][0])) ? $info[$ldapField][0] : '';
}

do

echo '<pre>';
var_dump($info);
echo '</pre>';

and have a look at the structure of the data, then you will know how to access it

The best way to explain an undefined index is by example:

$myArray = array(
    0 => 'val 1',
    1 => 'val 2',
    'apple' => 'cucumber',
);

// If I try to access $myArray['lemon'] I'm going to get an "undefined index" error because that index IS NOT DEFINED (similar to "array index out of bounds").  

If index 0 is giving you this error it's likely that the array you're trying to access is either undefined or empty.

The 0's are just the index it's trying to access on the $info array. The first element is an array with an index of 'givenname' (string opposed to numerical index), and that array contains another set of arrays, of which you're trying to access the 1st element. So your structure must be something like

$info = array(
  [0] => array(
      'givenname' => array(
          [0] => 'test',
          [1] => 'other data or possibly an array'
      ) 
   )
);

The thing with LDAP is that an attribute can 'point' to another attribute. This is why the entries are represented this way:

//$ldapResults = ldap_get_entries(xxx)
//$ldapResults['count'] = 1
//$ldapResults[0] = array('dn' => array('count' => 1, array('CN=XXXX'))

So when you want to go through ldap results you need to know what kind of data you are pulling from the LDAP. You can either access data directly, or simply by looping through the $ldapResults[0] which contains in my opinion the most important information.

Undefined index can both mean that the attribute does not exists or is not at the index you specified. You can test if it exists with a simple isset. Now if you don't know what kind of results you are getting back, you might want to dump the results.

The attributes can be multi-valued, hence the array. Whether an attribute can be present multiple times in an entry is defined in the schema attribute definition. LDAP clients should access the schema to determine the syntax, matching rules, ordering rules, and whether an attribute is multi-valued. "givenName", for example, is multi-valued if the standard schema is used.