简体   繁体   中英

For loop inside of foreach loop is causing duplicates

I am looping thru a list of switches and returning their port information. If i run the script on 1 ip it works fine but when doing this on multiple IPS i get duplicate data from the for loop. I want to run the code on each switch in the csv file. Please help..

Any help or detalis would be awesome...

$csv = array_map('str_getcsv', file('port_test.csv'));

foreach ($csv as $key => $value) {
    $ip = $value[0];  
    code goes here...

    for loop causes it to do the code for each line in csv file
}


------------------------------
HERE IS MY FULL CODE


<tr id="fsu-header">
    <th>Host Name</th>
    <th>Ports</th>
    <th>Link</th>
    <th>Speed</th>
    <th>POE</th>
    <th>Desciption</th>
    <th>In Bytes</th>
    <th>Out Bytes</th>
    <th>In Errors</th>
    <th>Out Errors</th>
    <th>In Ucast</th>
    <th>Out Ucast</th>
    <th>In Bcast</th>
    <th>Out Bcast</th>           
</tr>
<?php
    //switch infor
    //$host = $_GET['ip'];
    $csv = array_map('str_getcsv', file('port_test.csv'));

    foreach ($csv as $key => $value) {
        $ip = $value[0];                 
        //$ip = "10.16.26.26";
        $community = "passcode";
        $updown1   =  "interfaces.ifTable.ifEntry.ifOperStatus";
        $desc     =  "interfaces.ifTable.ifEntry.ifDescr";
        $speed    =  "interfaces.ifTable.ifEntry.ifSpeed";
        $inbyte   =  "interfaces.ifTable.ifEntry.ifInOctets";
        $outbyte  =  "interfaces.ifTable.ifEntry.ifOutOctets";
        $inerror  =  "interfaces.ifTable.ifEntry.ifInErrors";
        $outerror =  "interfaces.ifTable.ifEntry.ifOutErrors";
        $inucast = "InUcastPkts";
        $outucast = "OutUcastPkts";   
        $found_vname=  ".1.3.6.1.4.1.1991.1.1.3.2.7.1.21"; #vlan names   
        $found_vport=  ".1.3.6.1.4.1.1991.1.1.3.2.6.1.1"; #vlan to port 

        $found_excurrent= ".1.3.6.1.4.1.1991.1.1.1.1.18"; #exhaust current

        $found_exwarn=  ".1.3.6.1.4.1.1991.1.1.1.1.19"; #exhaust warn
        $found_exshut=  ".1.3.6.1.4.1.1991.1.1.1.1.20"; #exhaust shut

        $found_power=  ".1.3.6.1.4.1.1991.1.1.1.2.1.1.3"; #power supply

        $cserial =  ".1.3.6.1.4.1.9.3.6.3";    #serial number cisco
#       $fserial =  "  .1.3.6.1.4.1.1991.1.1.2.8.1.1.6";     #foundry serial
        $fserial =  ".1.3.6.1.4.1.1991.1.1.1.1.2";     #foundry serial
        $fsnmp_poe =  ".1.3.6.1.4.1.1991.1.1.2.14.2.2.1.3";  #foundry poe status
        $fesnmp_poe =  ".1.3.6.1.4.1.1991.1.1.3.3.1.1.58";         #found fes poe                       
        ///////////////////////////////////////////////////////////////
        //launch snmp walk

        //port numbers
         $sysName = shell_exec('/usr/bin/snmpwalk -c "'.$community.'" -v 1 "'.$ip.'" sysName.0');
         $sys_name = substr($sysName, strpos($sysName, "STRING:") + 8); 

        $port_num = shell_exec('/usr/bin/snmpwalk -c "'.$community.'" -v 1 "'.$ip.'" ifDescr');
        $port_number = explode("IF-MIB", trim($port_num));
        //Port Description
        $output = shell_exec('/usr/bin/snmpwalk -c "'.$community.'" -v 1 "'.$ip.'" ifAlias');
        $port_des1 = explode("IF-MIB", trim($output));

        $speeds = shell_exec('/usr/bin/snmpwalk -c "'.$community.'" -v 1 "'.$ip.'" "'.$speed.'"');
        $speeds_ = explode("IF-MIB", trim($speeds));

        $poe = shell_exec('/usr/bin/snmpwalk -c "'.$community.'" -v 1 "'.$ip.'" "'.$fsnmp_poe.'"');
        $poe_wat = explode("SNMPv2", trim($poe));


        $updown = shell_exec('/usr/bin/snmpwalk -c "'.$community.'" -v 1 "'.$ip.'" interfaces.ifTable.ifEntry.ifOperStatus');
        $updown_stat = explode("IF-MIB", trim($updown));

        $in_bytes = shell_exec('/usr/bin/snmpwalk -c "'.$community.'" -v 1 "'.$ip.'" "'.$inbyte.'"');
        $in_byte = explode("IF-MIB", trim($in_bytes));


        $out_bytes = shell_exec('/usr/bin/snmpwalk -c "'.$community.'" -v 1 "'.$ip.'" "'.$outbyte.'"');
        $out_byte = explode("IF-MIB", trim($out_bytes));

        $in_errors = shell_exec('/usr/bin/snmpwalk -c "'.$community.'" -v 1 "'.$ip.'" "'.$inerror.'"');
        $in_error = explode("IF-MIB", trim($in_errors));

        $out_errors = shell_exec('/usr/bin/snmpwalk -c "'.$community.'" -v 1 "'.$ip.'" "'.$outerror.'"');
        $out_error = explode("IF-MIB", trim($out_errors));

        $in_ucasts = shell_exec('/usr/bin/snmpwalk -c "'.$community.'" -v 1 "'.$ip.'" "'.$inucast.'"');
        $in_cast = explode("IF-MIB", trim($in_ucasts));

        $out_ucasts = shell_exec('/usr/bin/snmpwalk -c "'.$community.'" -v 1 "'.$ip.'" "'.$outucast.'"');
        $out_cast = explode("IF-MIB", trim($out_ucasts));

        $in_nucasts = shell_exec('/usr/bin/snmpwalk -c "'.$community.'" -v 1 "'.$ip.'" ifInNUcast');
        $in_ncast = explode("IF-MIB", trim($in_nucasts));

        $out_nucasts = shell_exec('/usr/bin/snmpwalk -c "'.$community.'" -v 1 "'.$ip.'" ifOutNUcast');
        $out_ncast = explode("IF-MIB", trim($out_nucasts));


        // output data to tables
        for ($i=1; $i < count($port_number) ; $i++) {
            $port_des_ = substr($port_number[$i], strpos($port_number[$i], "STRING:") + 8);
            $port_des_1 = substr($port_des1[$i], strpos($port_des1[$i], "STRING:") + 8);    
            $speeds_1 = substr($speeds_[$i], strpos($speeds_[$i], "Gauge32:") + 8);
            if(strpos( $speeds_1 , '1000000000' ) !== false){$speeds_1 = "1Gb";}
            if(strpos( $speeds_1 , '10000000' ) !== false){$speeds_1 = "10Mb";}
            if(strpos( $speeds_1 , '100000000' ) !== false){$speeds_1 = "100Mb";}  
            if (preg_match('/40Gig/',$port_des_) & strpos( $speeds_1 , '4294967295' ))$speeds_1 = "40Gb";
            if(strpos( $speeds_1 , '4294967295' ) !== false){$speeds_1 = "10Gb";}                                         
            $updown_stat_1 = substr($updown_stat[$i], strpos($updown_stat[$i], "") + 8);    
                if(strpos( $updown_stat_1 , 'up(1)' ) !== false){$updown_stat_1 = "UP";}
                else{$updown_stat_1 = "DOWN";}
            $inbytes = substr($in_byte[$i], strpos($in_byte[$i], "Counter32") + 10);
            $outbytes = substr($out_byte[$i], strpos($out_byte[$i], "Counter32") + 10);
            $inerrors = substr($in_error[$i], strpos($in_error[$i], "Counter32") + 10);
            $outerrors = substr($out_error[$i], strpos($out_error[$i], "Counter32") + 10);
            $inucasts = substr($in_cast[$i], strpos($in_cast[$i], "Counter32") + 10);
            $outucasts = substr($out_cast[$i], strpos($out_cast[$i], "Counter32") + 10);
            $inbcasts = substr($in_ncast[$i], strpos($in_ncast[$i], "Counter32") + 10);
            $outbcasts = substr($out_ncast[$i], strpos($out_ncast[$i], "Counter32") + 10);
            $poe_watts = substr($poe_wat[$i], strpos($poe_wat[$i], "SNMPv2") +53);
            $sys_name_ = substr($sysName, strpos($sysName, "STRING:") + 8);
            // table rows / data
            $table .= '<tr>';
            $table .= '<td>'.$sys_name_.'</td>';                                         
            $table .= '<td>'.$port_des_.'</td>';
            $table .= '<td>'.$updown_stat_1.'</td>';
            $table .= '<td>'.$speeds_1.'</td>';
            $table .= '<td>'.$poe_watts.'</td>';
            $table .= '<td>'.$port_des_1.'</td>';
            $table .= '<td>'.$inbytes.'</td>';
            $table .= '<td>'.$outbytes.'</td>';
            $table .= '<td>'.$inerrors.'</td>';
            $table .= '<td>'.$outerrors.'</td>';
            $table .= '<td>'.$inucasts.'</td>';
            $table .= '<td>'.$outucasts.'</td>';
            $table .= '<td>'.$inbcasts.'</td>';
            $table .= '<td>'.$outbcasts.'</td>';
            $table .= '</tr>';
        }
         echo $table;
        }

enter code here
?>
</table>

First, some cleanup. There is no reason to have this block of assignments within the foreach loop. You are setting them each time the loop happens, they should be outside of the loop:

        $community = "passcode";
        $updown1   =  "interfaces.ifTable.ifEntry.ifOperStatus";
        $desc     =  "interfaces.ifTable.ifEntry.ifDescr";
        ...
        $fesnmp_poe =  ".1.3.6.1.4.1.1991.1.1.3.3.1.1.58";         #found fes poe   

Now, to understand the code flow, let's make a pseudo-code representation:

//Get CSV data
$csv = array_map('str_getcsv', file('port_test.csv'));

// Variable Assignments

// Loop each line from CSV
foreach ($csv as $key => $value) {
 $ip = $value[0];

 // Collect data using snmpwalk
 $port_num = shell_exec('/usr/bin/snmpwalk -c "'.$community.'" -v 1 "'.$ip.'" ifDescr');
 $port_number = explode("IF-MIB", trim($port_num));

 // Loop for each port number, skipping first value from exploded array
 for ($i=1; $i < count($port_number) ; $i++) {

  // Display row of gathered information.
  $table .= $info;

 }

}

This will for each IP address display a row of information for each port number found.

Inside the foreach loop, all arrays are replaced each time, so data from the previous iteration will not be used again.

But the issue is that $table is not being cleared. You need to add a line in at the top of the loop to reset $table :

for ($i=1; $i < count($port_number) ; $i++) {
 $table = '';

There also is a potential issue I see. Most of the shell_exec calls return arrays. I can't see the data that each is outputting, but I'm guessing that the data doesn't magically line up with the same amount of data as the port number array.

Imagine this scenario:

$port_number = explode("IF-MIB", trim($port_num));
print_r($port_number);
// outputs: array(12,34,45,67,78,89)

$poe_wat = explode("SNMPv2", trim($poe));
print_r($poe_wat);
// outputs: array(20,10,30)

$in_byte = explode("IF-MIB", trim($in_bytes));
print_r($in_byte);
// outputs: array(1,2,3,4,5,6,7,8,9,10)

I don't see how the data would line up from each of these calls if they returned different result values that didn't directly correlate to the port number.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM