遍历数组的强大方法

I had the data in XML file i.e.

<domain>  
   <host>xyz</host>  
   <key>keeeeeeeeeey</key>  
</domain>
<domain>
  <host>xyz</host>  
   <key>keeeeeeeeeey</key> 
</domain>

From that xml I created an array for robustness had I knew how to find that using xml I would have done so but lack of my knowledge I converted that xml file into array using:

 $json = json_encode($xml); 
 $array = json_decode($json,TRUE);`

Below is my array:

Array
(
    [domain] => Array
        (
            [0] => Array
                (
                    [host] => bdbdfbdvbdbdfbdfbf.net
                    [key] => 933f416350de1a955544b30b5bb7ca09cfa2311101a22972320cc4c7af2ecedc03f36b8a48961ef938972478592a1e261819052b51c09a45cf805663f83cb2c0233969255a2c3e2e7e212a295a247b785d41
                )

            [1] => Array
                (
                    [host] => bdev1vvvvvvveinf.net
                    [key] => 933f416350de1a955544b30b5bb7ca09cfa2311101a22972320cc4c7af2ecedc03f36b8a48961ef938972478592a1e261819052b51c09a45cf805663f83cb2c0233969255a2c3e2e7e212a295a247b785d41
                )

            [2] => Array
                (
                    [host] => bdev1.aaaaaaaaureinf.net
                    [key] => 933f416350de1a955544b30b5bb7ca09cfa2311101a22972320cc4c7af2ecedc03f36b8a48961ef938972478592a1e261819052b51c09a45cf805663f83cb2c0233969255a2c3e2e7e212a295a247b785d41
                )

            [3] => Array
                (
                    [host] => bdennnnnnnninf.net
                    [key] => 933f416350de1a955544b30b5bb7ca09cfa2311101a22972320cc4c7af2ecedc03f36b8a48961ef938972478592a1e261819052b51c09a45cf805663f83cb2c0233969255a2c3e2e7e212a295a247b785d41
                )

            [4] => Array
                (
                    [host] => bdeveewerwerwerwerreinf.net
                    [key] => 933f416350de1a955544b30b5bb7ca09cfa2311101a22972320cc4c7af2ecedc03f36b8a48961ef938972478592a1e261819052b51c09a45cf805663f83cb2c0233969255a2c3e2e7e212a295a247b785d41
                )

        )

)

I want a robust loop through which if I pass the host name it returns the key. Can anyone please throw some light? The size of the array could grow to 100 000 000 plus entries.

Change your array to look like:

$data = array('domain' => array(
  'bdbdfbdvbdbdfbdfbf.net' => '933...',
  'bdev1vvvvvvveinf.net' => '933...',
));

Then you can do this:

echo $data['domain']['bdbdfbdvbdbdfbdfbf.net'];

There is no "robust" way to do it with your current array. You'd have to search through the entire thing:

function get_key($data, $host)
{
    foreach ($data['domain'] as $domain)
    {
      if ($domain['host'] == $host)
        return $domain['key'];
    }
}

Given this new information:

The size of the array could grow to 100 000 000 plus entries.

I retract the usefulness of this answer, as the entire concept of using any plain text format, including XML or a serialized PHP key-value array, to store this amount of data is just crazy.

You should store the data in a database with the domain indexed. Even an sqlite database would be a major upgrade from a linear probe of a text file.

Of course there are ways to store the data in a custom format that is optimized, but there's really no good reason to reinvent something a database can easily do.

If possible, I think it would be better if host could be in place of the array key instead of a numeric index. That means it could look like

Array
(
    [domain] => Array
        (
            [bdbdfbdvbdbdfbdfbf.net] => Array
                (

                    [key] => 933f416350de1a955544b30b5bb7ca09cfa2311101a22972320cc4c7af2ecedc03f36b8a48961ef938972478592a1e261819052b51c09a45cf805663f83cb2c0233969255a2c3e2e7e212a295a247b785d41
                )

            [bdev1vvvvvvveinf.net] => Array
                (

                    [key] => 933f416350de1a955544b30b5bb7ca09cfa2311101a22972320cc4c7af2ecedc03f36b8a48961ef938972478592a1e261819052b51c09a45cf805663f83cb2c0233969255a2c3e2e7e212a295a247b785d41
                )

            [bdev1.aaaaaaaaureinf.net] => Array
                (

                    [key] => 933f416350de1a955544b30b5bb7ca09cfa2311101a22972320cc4c7af2ecedc03f36b8a48961ef938972478592a1e261819052b51c09a45cf805663f83cb2c0233969255a2c3e2e7e212a295a247b785d41
                )
       )
)

which would be searchable with

$somedomain = "bdev1.aaaaaaaaureinf.net";
if (isset($domains['domain'][$somedomain])) {
   // do stuff
   //$domains['domain'][$somedomain]['key']; is the key you want
}

If you can, do it that way

Since you only need the [domain] array from the outer array, this should work

function getKey($domains)
{
    foreach($domains as $domain)
    {
        if($domain['host'] == $testHost)
           return $domain['key'];
    }
    return false;
}

$myKey = getKey($myArr['domain']);

Here is a method that works with the array that you gave. You don't have to make any changes to the array.

/**
 * Find the Key of the Domain in the Array with a Given Host
 * @param $given The host you want to search for
 * @returns The key of the domain (of the array) that has the matching host
 */
function findHost($given)
{
    // This code assumes that the data array is $array .
    global $array;

    foreach ($array["domain"] as $key => $value)
    {
        if ($value["host"] == $given)
            return $key;
    }

    // If no matches
    return false;
}

// Call findHost() as you desire.
// If there is no match, the function returns false.
// Otherwise, it returns the key of $array["domain"] that the host matches.

With 100 000 000 plus entries you're likely hitting the string length limit in PHP which would mean that you can't use json_encode and json_decode any longer.

This does something similar, but you need to metric yourself what's faster:

$array = (array) $xml;
array_walk_recursive($array, function(&$v) { $v = (array) $v; });

Good luck!

Anyway, I wonder how large that XML string is then. Hmm. I think the numbers you give are just not right, your question looks pretty bogus on a second thought.